Tree layout positioning gets messed up

Hi,

I have an issue with how nodes are being laid out after certain actions take place on this split node that I have designed. The split node is basically a node with multiple outgoing ports, 2 or more, that lead into separate paths. For some reason the issue occurs only under certain situations. Here is one example after a delete,

This is the layout with no issues:

This is the layout after deleting the topmost node leaving the split node. What I do is I automatically create new link data so that the node to it’s right takes it’s place and there are no broken links. I checked the node and link data itself and those are correct. But as you can see in the next screenshot, the positioning of nodes is off and their paths criss cross for some reason.

Oddly enough, the reverse example works fine.

If I delete the bottommost node of the split and it had a node to it’s right, then the node positioning works as expected.

Any idea on what the issue could be. Also worth noting that it gets stuck for some reason in this weird criss cross state and other subsequent actions cannot fix it. It only happens when directly leaving my split node which has multiple outgoing ports. I’ll follow up with more example in another comment that has the same behavior.

Here is the lead up to another example. Now I have made it so we have 3 paths. If I add a node to the first and third path, the links already look a little wonky for some reason.

Then, when I add a node in the middle, it causes the bottom two to criss cross.

However, if I change up the order that I add the new nodes in, the layout works as intended except for the sometimes weird links. Here is me starting with the first and second node.

Lastly, I add the third node and it layouts as intended with the exact same data.

I guess it is also worth noting that the nodes do not have any underlying initial location data attached to them. I don’t think this should be an issue, I’d imagine a tree layout mainly takes layer and node spacing into account and thats it.

Could you please show us the definition of that TreeLayout that you are using, and the link template?

Also, could you please temporarily set the Node.background to a garish color such as “lime” and show us a screenshot that shows the problem? I’m trying to see if the nodes might be bigger than they appear, which could cause AvoidsNodes routing to be frustrated.

Here is the tree layout definition:

layout: $(go.TreeLayout, {
        layerSpacing: 100,
        nodeSpacing: 50,
      }),

Here is my link template:

$(
    go.Link,
    {
      routing: go.Link.AvoidsNodes,
      corner: 10,
      deletable: false,
      movable: false,
      mouseDrop: (_, thisObj) => {
        const link = thisObj as go.Link;
        spliceNodeIntoLink(link);
      },
    },
    $(
      go.Shape, // a thick transparent link shape
      {
        isPanelMain: true,
        strokeWidth: 10,
        stroke: 'transparent',
      }
    ),
    $(go.Shape, {
      isPanelMain: true,
      strokeWidth: 2,
    }),
    $(go.Shape, { toArrow: 'Standard' })
  );

I’ll get you a screenshot in a followup comment.

Here is a screenshot where nodes are criss crossed. I have a lightgreen background on all nodes, you can see it behind the split at the corners.

Here is the other example broken:

Right before it breaks, I guess I can see why the link is wonky, here is a screenshot:

Not sure how a node could get in its own way though. The bottom link goes directly to the next node just fine unlike the top link.

OK, so what we want to do is:

  1. reduce the size of the node to be no more than needed
  2. reduce the size of the avoidable area of the node to exclude the vertical section that includes the circle-plus object

For (1) can you figure out why for those nodes in the right-most layer the lightgreen area goes well beyond the circle-plus object? Is there anything else there that might be transparent now?

For (2), you can set the Node.avoidableMargin to new go.Margin(2, -30, 2, 2) or something like that. You’ll need to figure out the distance to use in case -30 isn’t exactly right.

I do know why for (1). I had introduced extra margin around the add icon to make easy on users for drag and drop. I removed the margin for now. It likely isn’t needed anymore due to the drop zone adornment I now have. And there isn’t anything else transparent at the moment related to the node itself. I guess the link adornments could somehow be at play but they are removed in the problematic screenshots so I don’t think they are the issue.

As for (2), I set the avoidable margin to new go.Margin(2, -41, 2, 2) and that fixed the wonky link drawing issues during intermediate stages. But the general problem still persists.

Here’s with links being correctly more direct:

Here is the problematic layout still:

OK, progress. Now you just have to set TreeLayout.sorting to go.TreeLayout.SortingAscending and TreeLayout.comparer to a comparison function so that it arranges the children of each node in the order in which they are connected to ports on the parent node.

Wow, that fixed it for me! Thank you so much for the help Walter

I guess if there are multiple outgoing ports instead of just one, a comparer is needed for positioning.