How to snap AvoidsNodes links routing to grid?

I have a 20x20 grid and Orthogonal routing with nodes having fromSpot/toSpot as AllSides.

To align links with grid I’ve created a custom Link class which overrides computePoints to align points with grid. It works as expected and all links follow grid:

Now I want to switch to AvoidsNodes routing, but it results in links not following grid when they are trying to avoids a node:

I tried experimenting with avoidableMargin (e.g. setting it to 1 or 1/2 cell size), but it doesn’t seem to solve it.

My questions:

  1. First of all, is my approach to snapping Orthogonal routing correct? Or is there a more appropriate way to do that?
  2. How to make AvoidsNodes snap to grid as well?

The problem with “…Side” Spots is that as the number of links connecting on a particular side changes, the standard link connection point computation will spread them out evenly on that side, causing them no longer to be aligned according to any fixed grid. Perhaps you have avoided that problem in your custom computePoints method, but it gets pretty complicated.

Furthermore I notice that your nodes don’t seem to have all sides aligned to your grid, which complicates things even more.

I don’t have an easy answer for AvoidsNodes routing. Which version of GoJS are you using?

I use 3.0.27 at the moment. I see now that 3.1 had some improvements to links routing and AvoidsNodes, I’ll give it a try tomorrow.

For the node sides I was able to account for that in my custom computePoints — if point is on the node size, I only snap 1 coordinate so the port is still on the node edge.

Is it possible to extend AvoidsNodes router somehow?

And to clarify my main problem right now is middle segments that are not aligning to grid when they avoiding nearby node:

So if there is a way to modify link points after “avoidance” is calculated, it will be enough for my case.

One possibility is to change the grid that the AvoidsNodesRouter uses in v3.1. But I haven’t tried it for this specific purpose.

Yes, it might be possible to override methods on the AvoidsNodesRouter class even though it isn’t public. You can get an instance of it as the first element in the Diagram.routers list.

Thanks! Monkey-patching routeLinks worked, I even removed my custom grid-snapping Link class as it was no longer needed.