Getting a Node's Row on a LayeredDiagraph Diagram

Is it possible to determine which row in a LayeredDiagraph a node falls in? I am looping through all of the links in the diagram and changing their styling based on various properties of the links and the toNode/fromNode, and I want to style a link differently if it connects two nodes that are one row apart vs. more than one rows apart.

For example, I am setting the link.routing property differently for the “One to Eleven” link and the “One to Five” link because “One to Eleven” is two rows apart whereas “One to Five” is one row apart. I’m doing this now by checking their node.position.y coordinate and seeing if they exceed the spacing between the rows, but the row spacing may change from diagram to diagram so that is not a reliable method.

Screen Shot 2020-10-01 at 10.20.35 PM

Is it possible to see if a node is in “Row 1”, “Row 2”, etc. from the node’s properties so that I can compare them?

If it helps, here is what I’m doing now code-wise:

myDiagram =
      $$(go.Diagram, "myDiagramDiv",
        {
          initialContentAlignment: go.Spot.Center,
          initialAutoScale: go.Diagram.UniformToFill,
          layout: $$(go.LayeredDigraphLayout,
            { direction: 90, layerSpacing: 100 }),
            "LayoutCompleted": function(e) {
              // Push all link panels to the very beginning of the link (close to the bottom of the parent) as a starting point to be adjusted below
              e.diagram.links.each(function(l) { l.elt(1).segmentIndex = -Infinity; });
              // loop through every node on the diagram
              e.diagram.nodes.each(function(n) {
                console.log(n.data.name + " - " + n.position.y)
                // get all of the links that leave from the node
                var outLinks = n.findLinksOutOf();
                // count the number of links leaving the node
                var numOuts = outLinks.count

                // if there are any links leaving the node, style the link based on the following cases:
                if (numOuts > 0) {
                  
                  outLinks.each(function(link) {
                    // follow the link to it's destination node and determine how many total links are entering this destination node
                    var subsNumOfIns = link.toNode.findLinksInto().count

                    if(numOuts === 1 && subsNumOfIns === 1) {
                      // if the link is the only one out of the parent and the only one into the sub, put the label halfway along the link
                      link.elt(1).segmentIndex = NaN;
                      link.elt(1).segmentFraction = 0.5;
                    } else if (numOuts === 1 && subsNumOfIns > 1) {
                      // if the link is the only one out of the parent but one of many into the sub, put the label right below the parent
                      link.elt(1).segmentIndex = 1;
                    } else if (numOuts > 1 && subsNumOfIns === 1) {
                      // if the link is one of many out of the parent but the only one into the sub, put the label right above the sub
                      link.elt(1).segmentIndex = -2;
                    } else if (numOuts > 1 && subsNumOfIns > 1) {
                      // if the link is one of many out of the parent and one of many into the sub:
                        if(link.toNode.position.y - link.fromNode.position.y < 175) {
                        // if only one row apart (i.e. less than 175 points on the coordinate plane apart)
                          // make the links straight lines (e.g. "Normal") instead of orthagonal
                          link.routing = go.Link.Normal
                          // remove the end segment lenths (the vertical portions of the links immediately above/below nodes)
                          link.fromEndSegmentLength = 0;
                          link.toEndSegmentLength = 0;
                          // have the link label appear 1/4 of the way along the straight line
                          link.elt(1).segmentIndex = NaN;
                          link.elt(1).segmentFraction = 0.25;
                        } else {
                        // if more than one row apart (i.e. more than 175 points on the coordinate plane apart)
                          // style this differently - for now just leave it as orthagonal
                        }
                    }
                  });
                }
              });
            },
          "undoManager.isEnabled": true
        }
      );

Thank you!

If the graph were actually tree-structured, you could call Node.findTreeLevel. https://gojs.net/latest/api/symbols/Node.html#findTreeLevel

But your graphs don’t appear to be trees, so I don’t know if that method would produce the results you want.

I suppose you could customize the Layout that you are using to assign rows. Are you using LayeredDigraphLayout? If so, you could override the LayeredDigraphLayout.commitLayers method, https://gojs.net/latest/api/symbols/LayeredDigraphLayout.html#assignLayers#commitLayers, to get reliable information for where each layer is.

Thank you for the rapid response! I am using LayeredDiagraphLayout, I’ll take a look and see if this would work.