有没有一种方法可以绘制gojs图,使得有子节点的节点遵循水平结构,没有子节点的节点遵循垂直排列?

问题描述 投票:0回答:1

我想绘制一个遵循 AlignmentStart 模式的 GoJs 图。对于树中具有子节点的每个节点,应采用水平排列,而对于没有子节点的每个节点,即叶节点,应遵循垂直排列/模式。所有层的节点都应遵循此模式。

我尝试使用不同的布局选项来实现上述行为。我什至尝试了自定义布局,但无法处理所有情况,因为我的树可以是动态的,即可以有多个层。附件是我想要实现的示例图像。

layout gojs
1个回答
0
投票

这是一个自定义的 TreeLayout,我相信它可以满足您的需求:

class ChildlessFirstTreeLayout extends go.TreeLayout {
  makeNetwork(coll) {
    const net = super.makeNetwork(coll);
    new go.Set(net.vertexes).each(parent => {
      const childless = new go.Set();
      const childparents = new go.Set();
      parent.destinationVertexes.each(child => {
        if (child.destinationEdges.count === 0) {
          childless.add(child);
        } else {
          childparents.add(child);
        }
      });
      // if there are both childless and child-ful children,
      // create dummy vertexes
      if (childless.count > 0 && childparents.count > 0) {
        // the first dummy is for the childless children
        const dummy1 = net.createVertex();
        dummy1.copyInheritedPropertiesFrom(this.alternateDefaults);
        dummy1.width = dummy1.height = 0;
        net.addVertex(dummy1);
        net.linkVertexes(parent, dummy1, null);
        childless.each(child => {
          const parentedge = child.sourceEdges.first();
          if (!parentedge) throw new Error("no edge from parent to child???");
          parent.deleteDestinationEdge(parentedge);
          parentedge.fromVertex = dummy1;
          dummy1.addDestinationEdge(parentedge);
        });
        // the second dummy is for the children that have children
        const dummy2 = net.createVertex();
        dummy2.copyInheritedPropertiesFrom(this.rootDefaults);
        dummy2.width = dummy2.height = 0;
        net.addVertex(dummy2);
        net.linkVertexes(parent, dummy2, null);
        childparents.each(child => {
          const parentedge = child.sourceEdges.first();
          if (!parentedge) throw new Error("no edge from parent to child???");
          parent.deleteDestinationEdge(parentedge);
          parentedge.fromVertex = dummy2;
          dummy2.addDestinationEdge(parentedge);
        });
      }
    });
    return net;
  }

  assignTreeVertexValues(v) {
    // change layout for those vertexes with two dummy children
    if (v.childrenCount != 2) return;
    if (v.destinationVertexes.any(c => c.node !== null)) return;
    v.layerSpacing = 0;
    v.nodeIndentPastParent = 0.5;
  }
}

您可以通过以下方式使用它:

      layout:
        $(ChildlessFirstTreeLayout,
          {
            arrangement: go.TreeLayout.ArrangementHorizontal,
            // properties for most of the tree:
            angle: 90,
            alignment: go.TreeLayout.AlignmentStart,
            layerSpacing: 30,
            nodeSpacing: 30,
            // properties for the "last parents":
            treeStyle: go.TreeLayout.StyleLastParents,
            alternateAngle: 90,
            alternateAlignment: go.TreeLayout.AlignmentBottomRightBus,
            alternateLayerSpacing: 30,
            alternateNodeSpacing: 30,
            alternateRowSpacing: 10,
           }),
       . . .

结果:

完整的独立示例位于:https://gojs.net/extras/DualTreeLayout3.html 与往常一样,完整的源代码位于页面本身中。

© www.soinside.com 2019 - 2024. All rights reserved.