Ah, that link template makes a lot more sense than the one you posted first.
It appears that you have links that are crossing lanes. That’s OK, but since swimmers are normally expected to stay in their lane and are not expected to only cross lanes, I think you should be using “bands” instead of “lanes”. See the “Layer Bands” sample, http://gojs.net/latest/samples/swimbands.html .
Note that there are no Groups in this sample.
Then you could use LayeredDigraphLayout, which automatically does try to separate the orthogonal link segments that overlap if they do not go to or come from the same nodes. The problem is that I don’t think that LayeredDigraphLayout can handle 2000 nodes. But you could try this for yourself to see if it happens to work OK for your data.
Start with a copy of the Layer Bands sample: http://gojs.net/latest/samples/swimbands.html.
Change the link template to have orthogonal routing:
myDiagram.linkTemplate =
$(go.Link,
{ routing: go.Link.Orthogonal },
$(go.Shape)); // simple black line, no arrowhead needed
Rename LayeredTreeLayout to be LayeredLayout and have it inherit from LayeredDigraphLayout instead of TreeLayout:
function LayeredLayout() {
go.LayeredDigraphLayout.call(this);
//this.layerStyle = go.TreeLayout.LayerUniform; // needed for straight layers
}
go.Diagram.inherit(LayeredLayout, go.LayeredDigraphLayout);
LayeredLayout.prototype.commitLayers = function(layerRects, offset) {
. . .
Change the Diagram to use this new LayeredLayout:
// this controls whether the layout is horizontal and the layer bands are vertical, or vice-versa:
var HORIZONTAL = false; // this constant parameter can only be set here, not dynamically
myDiagram = $(go.Diagram, "myDiagram",
{
initialContentAlignment: go.Spot.Center,
layout: $(LayeredLayout, // custom layout is defined above
{
direction: HORIZONTAL ? 0 : 90,
packOption: go.LayeredDigraphLayout.PackMedian
})
});