Suitable diagram for sparsely and densely populated nodes in a table

Hi, I’m trying to connect fixed sized and positioned nodes (from inside an already built table layout in html, such that nodes are connected from column to column (always from left to right) where each node in the previous column is connected to all the other nodes in the next column with specified nodes.

As you can see I’m using the default layout & link, node templates with { routing: go.Link.AvoidsNodes, curve: go.Link.Bezier } and { portId: '', fromSpot: go.Spot.AllSides, toSpot: go.Spot.AllSides } respectively, in order for linking nodes but avoid overlapping of links with each other and other nodes, but the problem is that whenever we have some densely packed configuration of nodes, the links don’t always take the most optimal path like e.g. below.

So my question is that is there a pre-built or custom layout that we can use to populate links between such configurations of nodes such that links remain a bit more compact, and each link avoids other nodes and links as much as possible while keeping the diagram readable?


In the case that you have marked in red, the nodes are positioned more vertically compared to each other than horizontally, so it naturally chooses to use the bottom and top sides. But you could override that by setting Link.fromSpot to go.Spot.RightSide and Link.toSpot to go.Spot.TopSide on that Link.

What’s going on with all of those links that seem to be coming from the middle of the nodes?

Hi, thanks for the prompt response, honestly I’m myself not sure about the links starting from node centers, here’s my node template:

As you can see, I’m leaving to and from port spots upto the routing algorithm for best outcome but it doesn’t seem to work always )

also will setting isOngoing false with default or some other layout have any effect on the routing? As I plan to have a static diagram with fixed nodes based on server data without drag n drop or any other updates.

Well, that’s a simple node template. I can’t explain such routing behavior.
What is your link template?

here’s the current version:

That’s pretty simple too.

I just tried this by modifying the extensions/Table.html sample, and I didn’t have any problems like that.

So should I use Table layout? If so, please suggest how can I populate it with pre-positioned nodes and links as above? As I am not using any layout above and the underlying table of cells is just Html (nodes are only stroked rectangles)

No, you don’t need to use any Layout at all. Or use TableLayout if that is convenient for you – binding row and column on each node.

The layout shouldn’t have any specific effect on the routing of links, unless the particular layout is supposed to route in particular manners, as some of them do.

Hi, can we customize the avoids nodes routing algorithm to select routes not based on vertical or horizontal distance but based on whether there are no other nodes/links in the path?

For example, in the below example as you can see, its still making the link from bottom side port even though there’s clearly a node in the said path.

Ah, the problem is that the nodes are too close to each other. Because there isn’t enough room to route an “AvoidsNodes” routed link without, the routing decides to ignore that node there. It does not try for a longer route that happens not to cross any nodes.

What would you want it to do if there were nodes at both “User Execution” and “External Remote Services”?

But there might be an easy work-around, that I haven’t tried yet. Instead of using go.Spot.AllSides as the fromSpot and toSpot, use only those sides that are “open”. (Unless there aren’t any, in which case one might as well use go.Spot.AllSides.) So for the “Phishing” node, one would use go.Spot.NotRightSide, and for the “Explotiation …” node one would use go.Spot.NotBottomSide.

for this scenario, can we have something like this design?

I think you can get something like that for either of those links by using a fromSpot that is new go.Spot(0.7, 0.5). Adjust the spot to meet your needs.

so it seems it works pretty well at least with this particular scenario, I will try to implement a more generic solution and will report back in case of any issues, thank you.image

Hi @walter, so I successfully implemented custom bindings for calculating open values for fromSpot and toSpot, but now I am seeing another issue, as you can see in images below, sometimes the bezier curve overlaps the nodes based on the diagram zoom level (Note:- on zoom change, each node’s desiredSize and position bindings are updated to reflect new position and size of its corresponding HTML Element). Can this somehow be fixed in a generic way? I have already tried different values of avoidableMargin and adjusting for node and link templates respectively but to no avail.

Use go.Link.AvoidsNodes routing?

I’m already doing that (also tried updating to the latest gojs npm version)

Your first screenshot from an hour ago seems to have those two link routes going through the “Web Service” node, so it’s as if AvoidsNodes routing isn’t working.

Are there any large Nodes that cover the area of the nodes and links that are not obvious from looking at the screenshot? For example, a Group? If so, have you set Group.avoidable to false, because you don’t mind link routes crossing over that group?

I have made nodes fill white for now, as you can see there’s no group or background node, it just seems an issue with AvoidsNodes routing.

Ah, so (almost) all of those cells are occupied by Nodes, too? You need to set avoidable to false on those nodes, then. But presumably leave avoidable true on the nodes you care about, those with the dashed outline.

Basically, if the whole area is covered with nodes that the link route is supposed to avoid, it won’t be able to find an acceptable route. So it gives up and just uses the default routing, which ignores whether it crosses over any avoidable nodes.