Aligning links to different size nodes in same level

Hello, I have this gojs diagram in which nodes can be of different sizes. The problem is these nodes can be siblings (I have a tree chart). So, when links are generated, due to different in sizing, multiple links are generated.

Can we align this nodes to start with same level, so multiple links are not generated for same child level nodes.

Thanks.

How is the layout defined?

Thanks for the response @walter . The above layout is basically a LayeredDiagraphLayout.

OK, how is that layout defined?

this.diagram = $(go.Diagram, DIAGRAM_ID,
      {
        initialDocumentSpot: go.Spot.TopLeft,
        contentAlignment: go.Spot.TopLeft,
        allowResize: true,
        padding: new go.Margin(0, 100, 0, 150),
        layout: $(BandedLDLayout,
          {
            direction: 90,
            layerSpacing: 30,
            setsPortSpots: false,
            alignOption: go.LayeredDigraphLayout.AlignAll
          }),
        scrollMargin: new go.Margin(0, 0, 0, 100),
      });

This is the configuration of my diagram. Here Layout is BandedLDLayout which just extends my go.LayeredDiagraphLayout.

Here, BandedLDLayout, is a customization of LayeredDiagraphLayout to have that bands logic in the diagram. We have three Bands/Levels in our diagram

Thanks. Did you want to leave the nodes in their current arrangement and have the link routes turn horizontally at the same vertical point, or did you want to align the tops of all of the nodes in each layer?

To accomplish the former, use this Link subclass in your link template(s):

class OffsetLink extends go.Link {
  constructor(init) {
    super();
    if (init) Object.assign(this, init);
  }

  computeMidOrthoPosition(fromX, fromY, toX, toY, vertical) {
    if (vertical) return toY - 20;
    return super.computeMidOrthoPosition(fromX, fromY, toX, toY, vertical);
  }
}

Of course you’ll want to determine your preferred turning point, so you can modify the 20 in the override of Link.computeMidOrthoPosition.

To accomplish the latter, use the AlignedLayeredDigraphLayout in Aligned Layered Digraph Layout Since you have your own subclass of LayeredDigraphLayout already, you’ll need to merge the code. Note the …Network and …Vertex subclasses that you would need to include.

Thanks @walter for above sample code. Can you explain me what does this method do in general and what are the params to it.
I tried this approach but I am not able to get desired results.

I wanted to keep the arrangement of my nodes as it is, so I used computeMidOrthoPosition() method.

Maybe if you can explain this function little bit, then I can debug some scenarios from my end.

  /**
   * @hidden
   * (undocumented)
   * This method is called by {@link addOrthoPoints} to determine the distance
   * of the middle segment between the two ports.
   * @virtual
   * @param fromX - The first point's X coordinate.
   * @param fromY - The first point's Y coordinate.
   * @param toX - The last point's X coordinate.
   * @param toY - The last point's Y coordinate.
   * @param vertical - Whether the mid-position is along the vertical axis or horizontal axis.
   * @returns must be a real number, not NaN or infinity
   */

Here’s the internal documentation describing the method. You can read it in the go.d.ts file. Basically, in your case, it determines how far vertically the link will travel before “turning”. Walter’s override makes it so the link turn 20px above the y value of the to port. Maybe you could experiment with returning fromY + (some number).

Thanks @jhardy . I tried with some values but I observed one pattern.

In above image you can see, all nodes have one link but the nodes (here A and B) which are just below my parent node, for only these two nodes I can see multiple links.

And this is the only misalignment across my whole chart. Only nodes which are just below my parent node, I see multiple links for that.

Any suggestions for this.

Do those nodes happen to be using the super call? Try setting a breakpoint on the return super.compute....

Hi @jhardy . I tried debugging this, nodes are not calling my super.compute() method. All nodes are triggering if condition.

Also after debugging I observed one scenario, In below image you can see we have a small oval shape containing my count of child nodes it has, so since the links will not overlap this shape, thus it is creating multiple links for some nodes.

When I remove that shape, it works fine.

Any suggestions for this.

Is your method defined like:

  computeMidOrthoPosition(fromX, fromY, toX, toY, vertical) {
    if (vertical) return fromY + 20;
    return super.computeMidOrthoPosition(fromX, fromY, toX, toY, vertical);
  }

Do you have more than one link template in use in your screenshot, and if so do both or all of those link templates use your custom Link class instead of go.Link?

I have only one linkTemplate defined for my whole diagram and it uses customLink class.

And the method which I am using is same but if vertical condition satisfies, I am returning toY + (some number)

Is it should be fromY + (some number)

If your links are going downwards (i.e. towards greater Y coordinates), then yes, it should be as I wrote it above. Perhaps with a number other than 20, of course.

In version 3.1 we have added a LayeredDigraphLayout.centered property that when set to false will align the nodes to the top of the layer. So this will address the other aspect of your issue – the positioning of the nodes. You won’t need to use that AlignedLayeredDigraphLayout as an alternative to overriding Link.computeMidOrthoPosition.