Controlling the gap between the end link and the node

I’m trying yo control the gap between the link and the node, when the link breaks down.
In your example, “dynamic ports”, the link breaks “far” from the node (black arrow).
I tried to set the link template attributes, like in the sample code :

routing: go.Link.AvoidsNodes,
corner: 4,
curve: go.Link.JumpGap,
reshapable: true,
resegmentable: true,
relinkableFrom: true,
relinkableTo: true

But the link breaks “near” the node.
I did my example without ports, only node to node link.
I cannot figure out which attribute control the gap between the link and the node.

Your example of the Dynamic Ports sample looks good to me. But if your Nodes do not have multiple ports at their sides, the routing that is used in the Dynamic Ports sample with its custom Link routing, doesn’t really apply, does it? What is your situation?

The picture is taken from your example…
My solution does not use ports as link end points.

OK, but what situations do you have and how do you want to handle them?

The situation i have is like in the picture.
Links go from left side of the left node to the right side of the right node.

I can understand anyone having a reluctance to post a screenshot, for many different reasons. Perhaps you would prefer to converse via email rather than on this public forum?

  function init() {
    var $ = go.GraphObject.make;

    myDiagram =
      $(go.Diagram, "myDiagramDiv");

    myDiagram.nodeTemplate =
      $(go.Node, "Auto",
        { width: 80, height: 80 },
          {  // the main resizable element
            name: "SHAPE", fill: "lightgray",
            portId: "", cursor: "pointer",
            fromSpot: go.Spot.LeftSide, toSpot: go.Spot.RightSide,
            fromLinkable: true, toLinkable: true,
            fromLinkableDuplicates: true, toLinkableDuplicates: true
          new go.Binding("text"))

    myDiagram.linkTemplate =
        { routing: go.Link.AvoidsNodes, corner: 5 },

    myDiagram.model = new go.GraphLinksModel(
        { key: 1, text: "Alpha" },
        { key: 2, text: "Beta" }
        { from: 1, to: 2 },
        { from: 1, to: 2 }

Note: no custom Link routing – i.e. no subclass of Link.

That results in this routing, when the nodes are placed relative to each other as in your screenshot:

I suppose you could complain about the unnecessary link crossing that is just below the “Alpha” node. Sorry, but that’s just how the default routing behavior works.

I might have miss leaded you.
As described, the links go from left to right, yet, one link goes from “Alpha” to “Beta” from Spot (0,0.5) to Spot (1,0.5) while the second link goes from “Beta” to “Alpha” from Spot(1,0.8) to Spot (0,0.8).
So, i binded the “fromSpot” and “toSpot” on the link Level:

var nodeDataArray = [ 

    { key: 1,  source: "icons/Router.svg", siteId: "Alpha", loc:"0 0" }, 
    { key: 2,  source: "icons/Router.svg", siteId: "Beta", loc:"200, 200"}, 

var linkDataArray = [
    { from: "1", to: "2",  fromSpot: "0 0.4",  toSpot: "1 0.4" },
    { from: "2", to: "1" , fromSpot: "1 0.8", toSpot: "0 0.8"  },

diagram.linkTemplate = $(go.Link,
{ routing: go.Link.AvoidsNodes,

            corner: 5,
       new go.Binding("fromSpot", "fromSpot", go.Spot.parse),
       new go.Binding("toSpot", "toSpot", go.Spot.parse),
                    stroke: "black", strokeWidth: 2
        $(go.Shape,   // the "to" end arrowhead
        { toArrow: "Standard", fill: "black" })

The results are :

By explicitly setting the fromSpot or toSpot, you are not getting the benefits of GoJS automatically routing links to the sides of ports when using “…Side” spots.

As a quick hack:

    myDiagram.linkTemplate =
        { routing: go.Link.AvoidsNodes, corner: 5 },
        new go.Binding("fromSpot", "fromSpot", go.Spot.parse),
        new go.Binding("toSpot", "toSpot", go.Spot.parse),
        new go.Binding("fromEndSegmentLength", "fromSpot", function(s) { s = go.Spot.parse(s); return s.y * 12 + 8; }),
        new go.Binding("toEndSegmentLength", "toSpot", function(s) { s = go.Spot.parse(s); return s.y * 12 + 8; }),
        new go.Binding("curviness", "fromSpot", function(s) { s = go.Spot.parse(s); return s.y*30 - 15; }),
        $(go.Shape, { stroke: "black", strokeWidth: 2 }),
        $(go.Shape, { toArrow: "Standard", fill: "black" })

This still has a lot of problems in other situations. More generally you can override methods of Link in order to achieve what you want. That’s what the Dynamic Ports sample does, for example.

In fact
I added the fromEndSegmentLength=55, toEndSegmentLength=55 to the template and it got better.

I’m surprised that it helped having the same end segment length for each link. There needs to be different values so that the vertical segments are offset from each other.

I guess you are right.
Setting these attributes with constant values, on the template level, affects the appearance of other links, even direct straight link.
I set these values only to links that are “break” down, “one floor”.
Looks good.