Tree layout vertical nodes alignment

hi team,

I want to align root nodes and their childs in vertical manner. I’m using tree layout for that but got stuck in a child nodes alignments. As you can see in below diagram

Expected output is as shown in image below…

here is layout code:-
layout:

  $(go.TreeLayout,

          {

            treeStyle: go.TreeLayout.StyleRootOnly,

            arrangement: go.TreeLayout.ArrangementVertical,

            angle: 90,

            layerSpacing: 100,

            alternateAngle: 90,

            alternateLayerSpacing: 100,

            alternateNodeSpacing: 80,

            setsPortSpot: false

          })

So suggest me some properties manipulation in tree layout through which I can achieve my expected output.
Thanks in advance…!

Your graph is not tree-structured, so it should not be surprising that TreeLayout assumes that the graph is tree-structured and thus only considers the first of the links that come into a node.

You could try using LayeredDigraphLayout or (with the addition of Groups and split and merge nodes) ParallelLayout.

Try this custom TreeLayout instead:

// A TreeLayout that is slightly smarter about multiple source (input) links connecting with a node.
// This does not handle cycles or links that cross layers well, nor does it try to minimize link crossings.
class MergingTreeLayout extends go.TreeLayout {
  makeNetwork(coll) {
    const net = super.makeNetwork(coll);
    new go.Set(net.vertexes).each(v => {
      if (!v.network) return;
      let srcs = v.sourceVertexes;
      if (srcs.count > 1) {
        srcs = new go.Set(srcs);
        const ins = new go.Set();
        const outs = new go.Set();
        srcs.each(s => {
          ins.addAll(s.sourceVertexes);
          outs.addAll(s.destinationVertexes);
        });
        if (ins.any(s => srcs.has(s))) return;
        if (outs.any(d => srcs.has(d))) return;
        const w = net.createVertex();
        const nodes = new go.List();
        srcs.each(v => { if (v.node) nodes.add(v.node); else if (v._nodes) nodes.addAll(v._nodes); });
        w._nodes = nodes;  // remember the Nodes for this dummy vertex
        w.x = 0;
        w.y = 0;
        if (this.angle === 90 || this.angle === 270) {
          let x = 0;
          let y = 0;
          nodes.each(n => {
            const b = this.getLayoutBounds(n);
            x += ((x > 0) ? this.nodeSpacing : 0) + b.width;
            y = Math.max(y, b.height);
          });
          w.width = x;
          w.height = y;
        } else {
          let x = 0;
          let y = 0;
          nodes.each(n => {
            const b = this.getLayoutBounds(n);
            x = Math.max(x, b.width);
            y += ((y > 0) ? this.nodeSpacing : 0) + b.height;
          });
          w.width = x;
          w.height = y;
        }
        w.focusX = w.width/2;
        w.focusY = w.height/2;
        srcs.each(s => net.deleteVertex(s));  // also deletes connected edges
        net.addVertex(w);  // no .node for this vertex
        net.linkVertexes(ins.first(), w, null);  // one parent link
        outs.each(d => {  // any number of child links
          net.linkVertexes(w, d, null);
        });
      }
    });
    return net;
  }

  commitNodes() {
    this.network.vertexes.each(v => {
      if (!v._nodes) return;
      if (this.angle === 90 || this.angle === 270) {
        let x = v.bounds.x;
        v._nodes.each(n => {
          n.moveTo(x, v.bounds.y);
          x += this.getLayoutBounds(n).width + this.nodeSpacing;
        });
      } else {
        let y = v.bounds.y;
        v._nodes.each(n => {
          n.moveTo(v.bounds.x, y);
          y += this.getLayoutBounds(n).height + this.nodeSpacing;
        });
      }
    });
    super.commitNodes();
  }
}  // end MergingTreeLayout