Unable to align nodes at same y coordinate

This is my diagram and nodes.


and sharing the node template for this diagram.

$$(go.Panel, 'Spot',
  $$(go.Shape, 'RoundedRectangle', {
      name: 'rect1',
      width: 120,
      portId: '',
      fromLinkable: true,
      toLinkable: true,
      toLinkableDuplicates: true,
      fromLinkableDuplicates: true,
      pickable: true,
      isActionable: true,
      strokeWidth: 1,
      fill: 'orange',
      height: 200
    },
  ),
  $$(go.Shape, 'RoundedBottomRectangle', { // some geometry
      name: 'rect2',
      fill: 'white',
      pickable: true,
      isActionable: true,
      strokeWidth: 0,
      alignment: go.Spot.BottomCenter,
      height: 150
    },
  ),
  $$(go.Panel, 'Spot', {
      alignmentFocus: go.Spot.Center,
      alignment: new go.Spot(1, 0, 0, 50)
    },
    $$(go.Shape, 'RoundedRectangle', {
        name: 'rounded_square',
        width: 40,
        height: 40,
        strokeWidth: 1,
        stroke: 'grey',
        alignment: go.Spot.Center,
        alignmentFocus: go.Spot.Center,
        shadowVisible: true,
        parameter1: 5
      },),
    $$(go.Picture, {
        alignment: go.Spot.Center,
        alignmentFocus: go.Spot.Center,
        desiredSize: new go.Size(18, 18),
        source: 'image_path'
    }),
    $$(go.TextBlock, {
      text: 'some_text',
      alignment: new go.Spot(0, 0, 12, 19),
      alignmentFocus: go.Spot.LeftCenter
    }),
    $$(go.TextBlock, {
      text: 'some_text',
      alignment: new go.Spot(0, 0, 12, 38),
      alignmentFocus: go.Spot.LeftCenter
    })
    // so on
  )
)

Link template for this diagram

myDiagram.linkTemplate = $$(Link,
  {
    corner: 0,
  },
  new go.Binding('toSpot', '', function (data) {
    return new go.Spot(0, 0, 0, 50)
  }),
  new go.Binding('fromSpot', '', function (data) {
    return new go.Spot(1, 0, 0, 50)
  }),
  $$(go.Shape, {strokeWidth: 1, stroke: 'lightgrey'}),
)

Now, I have been trying to align nodes to top align (same y coordinate )
so I am using following code

myDiagram.layout = $(go.LayeredDigraphLayout, {
  setsPortSpots: false,
  layerSpacing: 200, // spacing between parent and child [Horizontal]
  columnSpacing: 70, // spacing between siblings [Vertical]
  alignOption: go.LayeredDigraphLayout.AlignUpperRight,

  // to fix the placement of setup node which is not connected to the main tree
  layeringOption: go.LayeredDigraphLayout.LayerLongestPathSource
})

But this not getting align to this

LayeredDigraphLayout tries to line up the centers of the nodes. That’s what most people want most of the time. You are getting that behavior because the nodes are different sizes.

What range of heights might there be in your app?

OK, I just tried it with variable height nodes and a fixed header height that is also the node’s port. Everything seems to work the way that you expect.

Complete code:

<!DOCTYPE html>
<html>
<head>
  <title>Aligned Layered Digraph Layout</title>
  <!-- Copyright 1998-2023 by Northwoods Software Corporation. -->
  <script src="https://unpkg.com/gojs"></script>
  <script id="code">
function init() {
  var $ = go.GraphObject.make;  // for conciseness in defining templates

  myDiagram =
    new go.Diagram("myDiagramDiv",  // must be the ID or reference to div
      {
        layout: new go.LayeredDigraphLayout({ alignOption: go.LayeredDigraphLayout.AlignAll })
      });

  // define the Node template
  myDiagram.nodeTemplate =
    $(go.Node, "Vertical",
      { resizable: true, resizeObjectName: "SHAPE" },
      $(go.Panel, "Auto",
        { width: 50, height: 25, portId: "" },
        $(go.Shape, { fill: "lightgray" }),
        $(go.TextBlock,
          new go.Binding("text", "text"))
      ),
      $(go.Shape, "Rectangle",
        {
          name: "SHAPE",
          fill: "lightgray",  // the initial value, but data-binding may provide different value
          stroke: "black",
          desiredSize: new go.Size(30, 30),
        },
        new go.Binding("fill", "fill"),
        new go.Binding("desiredSize", "size"))
    );

  // define the Link template to be minimal
  myDiagram.linkTemplate =
    $(go.Link,
      { selectable: false },
      $(go.Shape));

  myDiagram.startTransaction("generateDigraph");
  // replace the diagram's model's nodeDataArray
  generateNodes(20, 40);
  // replace the diagram's model's linkDataArray
  generateLinks();
  myDiagram.commitTransaction("generateDigraph");
}

// Creates a random number of randomly colored nodes.
function generateNodes(min, max) {
  var nodeArray = [];
  if (isNaN(min)) min = 0;
  if (isNaN(max) || max < min) max = min;
  var numNodes = Math.floor(Math.random() * (max - min + 1)) + min;
  var i;
  for (i = 0; i < numNodes; i++) {
    nodeArray.push({
      key: i,
      text: i.toString(),
      fill: go.Brush.randomColor(),
      size: new go.Size(20 + Math.random() * 50, 20 + Math.random() * 100)
    });
  }

  // randomize the node data
  for (i = 0; i < nodeArray.length; i++) {
    var swap = Math.floor(Math.random() * nodeArray.length);
    var temp = nodeArray[swap];
    nodeArray[swap] = nodeArray[i];
    nodeArray[i] = temp;
  }

  // set the nodeDataArray to this array of objects
  myDiagram.model.nodeDataArray = nodeArray;
}

// Create some link data
function generateLinks() {
  if (myDiagram.nodes.count < 2) return;
  var linkArray = [];
  var nit = myDiagram.nodes;
  var nodes = new go.List();
  nodes.addAll(nit);
  for (var i = 0; i < nodes.count - 1; i++) {
    var from = nodes.elt(i);
    var numto = Math.floor(1 + (Math.random() * 3) / 2);
    for (var j = 0; j < numto; j++) {
      var idx = Math.floor(i + 5 + Math.random() * 10);
      if (idx >= nodes.count) idx = i + (Math.random() * (nodes.count - i)) | 0;
      var to = nodes.elt(idx);
      linkArray.push({ from: from.data.key, to: to.data.key });
    }
  }
  myDiagram.model.linkDataArray = linkArray;
}
  </script>
</head>
<body onload="init()">
<div id="sample">
  <div id="myDiagramDiv" style="border: solid 1px black; background: white; width: 100%; height: 500px" />
</div>
</body>
</html>

will alignAll all nodes
I want to align nodes which are connected by particular linkTemplate category(i.e category: ‘straight_link’)
Note: category = straight_link linkTemplate is not used sequentially

consider following


Here 1 indicate linkTemplate category:‘straight_link’

I don’t think LayeredDigraphLayout can be customized in that manner.

It might be possible to increase the chance of getting those links lined up by changing the order of the links, but even that might not be reliable.