How to avoid link overlapping

I have around 2000 nodes in the swimlane layout. Every swimlane has nodes standing in single line.
When I draw a link between nodes the links are overlapping one on the other. Can you please help on “How to avoid links that will not overlap each other”

I use the below code as link template,

var linkTemplate =
routing: go.Link.Normal, corner: 5, curve: go.Link.JumpOver, selectionAdorned: false,
mouseEnter: function (e, link) { this.HighlightLink(link, true); },
mouseLeave: function (e, link) { this.HighlightLink(link, false); }
new go.Binding(“stroke”, “isHighlighted”,
function(h, shape) { return h ? ‘red’ :; })
new go.Binding(“strokeWidth”, “isHighlighted”,
function(h) { return h ? 2 : 1; })

That’s very odd, because your screenshot appears to show Links that are routed orthogonally, not with routing: go.Link.Normal.
And where do those Links go? It would be nice to see representative results with just a few nodes and links.

Are you using Groups, and what is the value for their Group.layout? I assume all of those beige-colored nodes members of the “Applications” Group, but what about other nodes? What is the value for Diagram.layout?

Okay, Here you go,

var linkTemplate =
routing: go.Link.AvoidsNodes,
curve: go.Link.JumpOver,
reshapable: true,
resegmentable: true,
relinkableFrom: true,
relinkableTo: true,
fromPortId: “”,
toPortId: “”,
corner: 4,
name: ‘LINK’
$(go.Shape, { stroke: ‘mediumseagreen’, strokeWidth: 2 })

Diagram layout is here,

        myDiagram =
          $(go.Diagram, "gojsDiagram",
                // use a custom ResizingTool (along with a custom ResizeAdornment on each Group)
                resizingTool: new GroupResizingTool(),
                initialContentAlignment: go.Spot.TopCenter,
                //autoScale: go.Diagram.Uniform,
                allowHorizontalScroll: true,
                allowVerticalScroll: true,
                //allowLink: false,
                // use a simple layout that ignores links to stack the top-level Groups on top of each other
                        cellSize: new go.Size(1, 1),
                        spacing: new go.Size(0, 0),
                        wrappingColumn: (HORIZONTAL ? 1 : Infinity),
                        wrappingWidth: Infinity,
                        isViewportSized: false
                // don't allow dropping onto the diagram's background
                mouseDrop: function (e) { e.diagram.currentTool.doCancel(); },
                "toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom,
                // a clipboard copied node is pasted into the original node's group (i.e. lane).
                "commandHandler.copiesGroupKey": true

The nodes are center aligned due to the requirement.

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, .

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:

Change the link template to have orthogonal routing:

myDiagram.linkTemplate =
    { 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() {;
//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

In the layer bands sample, the nodes are movable to other bands. However, in my case nodes should not moved from the select band. Very similar to swinlanes How to do that?

Did you see how that is implemented in the SwimLanes sample? You would just need to modify that function to use the bounds of the layer band (which is stored in the “_BANDS” model data item array) instead of the Group’s placeholder Shape.

Even if i change it to bands, i want routing as go.Link.Orthogonal, when I use Orthogonal the link overlaps. How to resolve that?

LayeredDigraphLayout tries to avoid having overlapping link segments if the links are completely unrelated – when neither connected Node is shared.

That does mean that it intentionally tries to have overlapping routes for two Links when either the .fromNode or the .toNode are the same Node. Is that the case for what you are seeing?

Thanks, it worked Smile