GoJs图表的布局类型

882 阅读4分钟

前言

前面几篇文章介绍了画布内的go.Diagram(图表)、go.Node(节点)、go.Link(连线)等等必备的一些元素。就好像我们做了很多的饭菜,并且支起了桌面,现在的问题就是我们怎样把饭菜摆到桌面上,摆成什么样子。这也就是今天介绍的布局类型--layout。

准备工作

首先我们先准备一些节点和连线,然后对节点做一些处理--显示不同的颜色、图形、文字。

//data
nodes:[
    { key: "1", color: "#99FFFF",text:"三国人物",figure:"Rectangle" },
    { key: "1-1", color: "#FF0000",text:"魏",figure:"Circle" },
    { key: "1-1-1", color: "#FF0000",text:"曹操",figure:"Circle" },
    { key: "1-1-2", color: "#FF0000",text:"荀彧",figure:"Circle" },
    { key: "1-2", color: "#FFFF66",text:"蜀",figure:"Circle"},
    { key: "1-2-1", color: "#FFFF66",text:"刘备",figure:"Circle"},
    { key: "1-2-2", color: "#FFFF66",text:"诸葛亮",figure:"Circle"},
    { key: "1-3", color: "#0000FF",text:"吴",figure:"Circle"  },
    { key: "1-3-1", color: "#0000FF",text:"孙权",figure:"Circle"  },
    { key: "1-3-2", color: "#0000FF",text:"周瑜",figure:"Circle"  },
  ],
  links:[
    {
      from:"1",
      to:"1-1"
    },
    {
      from:"1-1",
      to:"1-1-1"
    },
    {
      from:"1-1",
      to:"1-1-2"
    },
    {
      from:"1",
      to:"1-2"
    },
    {
      from:"1-2",
      to:"1-2-1"
    },
    {
      from:"1-2",
      to:"1-2-2"
    },
    {
      from:"1",
      to:"1-3"
    },
    {
      from:"1-3",
      to:"1-3-1"
    },
    {
      from:"1-3",
      to:"1-3-2"
    }
    ]
     
  //methods
  this.myDiagram = $$(go.Diagram, "myDiagramDiv");
  this.myDiagram.nodeTemplate =
    $$(go.Node, "Vertical",
    $$(go.Shape, "Circle",
        { width: 30, height: 30 },
        new go.Binding("fill", "color"),
        new go.Binding("figure", "figure"),
      ),
    $$(go.TextBlock, { margin: 5 },
        new go.Binding("text", "text"))
   );
   this.myDiagram.model = new go.GraphLinksModel(this.nodes, this.links);

简单的处理之后,页面的默认显示内容如下

image.png

layout布局类型

GridLayout,//网格化布局
CircularLayout,//环形布局
ForceDirectedLayout,//力导向布局
LayeredDigraphLayout,//分层布局
TreeLayout,//树形布局

GridLayout网格化布局

this.myDiagram = $$(go.Diagram, "myDiagramDiv", {
     layout: $$(go.GridLayout)
});

当画布大小充足的时候是同一行显示

image.png 当画布宽度不够的时候会自动换行

image.png

可以看出。GridLayout网格化布局就是按顺序将节点间隔一定的空间排列出来,并且在宽度排列不够的时候会自动进行换行。其配列的顺序则是根据nodes的数据从上到下进行排列。当然也可以利用comparer属性进行判断。其中spaceing有两个属性分别为width和height,width是横向两个节点的间隙,height是竖向两个节点的间隙。 cellSize则是设置单元格的尺寸,其width和height分别是单元格的宽和高。

在单元格内部包括节点和节点的间隙共同组成,每一行至少会有一个单元格,就算是节点的宽度和节点之间的横向间隙大于单元格宽度。仍然会显示在该行。

CircularLayout环形布局

this.myDiagram = $$(go.Diagram, "myDiagramDiv", {
    layout: $$(go.CircularLayout),
});

image.png

CircularLayout环形布局是将节点放到一个圆之上。可以用属性arrangement来设置节点之间的距离,而aspectRatio属性是这是其宽高比,默认是1,也就是原型。因此可以利用此属性把布局修改为椭圆。direction属性设置按顺时针排列还是逆时针排列。

ForceDirectedLayout力导向布局

this.myDiagram = $$(go.Diagram, "myDiagramDiv", {
    layout: $$(go.ForceDirectedLayout),
});

image.png ForceDirectedLayout力导向布局是根据引入库伦斥力和胡克弹力,以保证减少布局中边的交叉等要素的算法之后生成的一种布局方式,这种布局广泛应用于可视化图形中的关系图。在节点数量比较少的时候,力导向布局会保证节点尽量不重合,但是如果节点过多的话,也是会出现节点的折叠。

LayeredDigraphLayout分层布局

this.myDiagram = $$(go.Diagram, "myDiagramDiv", {
    layout: $$(go.LayeredDigraphLayout),
});

image.png

分层布局是将画布中的节点按照节点之间的关系进行一个行和列的分布排列,可以利用layerSpacing属性来设置节点之间的属性。如果数据结构和树形结构比较相似的话,还是要使用树形布局。因为树形布局有自己特殊的属性和并且比分层布局有更好的性能。

TreeLayout树形布局

this.myDiagram = $$(go.Diagram, "myDiagramDiv", {
    layout: $$(go.TreeLayout),
});

image.png

TreeLayout树形布局能够很清晰的看出数据层级并且还能显示上下级节点的关系,其一些配置属性在上文已经分析过,这里就不再赘述了。

总结

gojs还拓展了类似双树、辐射等其他的布局,但是后面可能随时会删除。如果用于生产环境还是可以用静态文件进行引入替换。利用这些布局可以让可视化图形更加符合需求,也更加利于很多信息的显示。