Link routing behaviour

I am witnessing some odd behavior for the link routing. Hoping you can help fix this.

I have a simple example using a diagram model with two nodes connected as shown. The picture here is initialized on startup in the node and link arrays.

image

  1. The first behavior which Im trying to understand is fix, is the way that link routing changes when I draw it interactively. For example in the above diagram, if I delete the link (as initialized) and then reconnect the nodes using the mouse I get this picture:

image

This seems strange to me, because surely it should follow the same route. And if I save the model and reload it, I would want the links to be drawn consistently in the manner they were saved.

  1. Secondly, I seem to be having trouble trying to manually redraw the link paths. I have set

    reshapable: true,
    resegmentable: true

in the link template, but when I try to move the link, i get errors. For example, when I start with the first picture shown above (on initialization) and try to redraw the link to look like the second picture I get this:

image

This clearly not what I want. Appreciate it, if you can shed some light on this.
Thanks.

Here is the code:

<!DOCTYPE html>
<html lang="en">

<head>

  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover" />
  <meta name="description"
    content="Node link Test" />
        
  <script src="https://unpkg.com/gojs/release/go-debug.js"></script>
 
  <script>

    function init() {

      var $ = go.GraphObject.make;  // for conciseness in defining templates

      var diagram = $(go.Diagram, "myDiagramDiv"
        , {
          allowDrop: true
          , allowDelete: true
          , allowCopy: true
          , "grid.visible": true
        }
      );


      var nodeTemplate =
        $(go.Node, "Auto",  // the whole node panel
          {
            selectionAdorned: true
            , resizable: true
          }
          , new go.Binding("location", "loc")

          , $(go.Shape, "Rectangle",  // spot positions in the the mopde are aligned with respect to this
            {
              fill: "lightblue"
              , strokeWidth: 2
              , desiredSize: new go.Size(100, 100)
              , portId: ""
              , cursor: "crosshair"
              , fromLinkable: true, fromLinkableDuplicates: true
              , toLinkable: true, toLinkableDuplicates: true
              , fromSpot: go.Spot.AllSides
              , toSpot: go.Spot.AllSides      
            }
          )
          ,
          $(go.TextBlock,
            {
              name: "TitleTextBlock"
              , alignment: go.Spot.Top
              , alignmentFocus: go.Spot.Top
              , font: "bold 16px sans-serif"
              , margin: 10
              , desiredSize: new go.Size(80, 80)
              , editable: true
              , text: "node"
              , background: "lightcyan"
            }
            , new go.Binding("text", "nodeTitle")
          )

        );  // end Node

        var linkTemplate =
        $(go.Link
        , {  selectionAdorned: true
            , routing: go.Link.Orthogonal, corner: 5
            , reshapable: true
            , resegmentable: true          
            , toEndSegmentLength: 20
            //, fromEndSegmentLength: 20
            //, toShortLength: 40
         }
         , new go.Binding("points").makeTwoWay()
          , $(go.Shape,
            { strokeWidth: 2 }
          )
          , $(go.Shape,  // arrowhead
            { toArrow: "Triangle", stroke: null, scale: 1.5 }
            )
        );


      var nodeDataArray = [
        { key: "N1", nodeTitle: "Node 1", loc: new go.Point(0, 0) },
        { key: "N2", nodeTitle: "Node 2", loc: new go.Point(150, 170) },

      ];

      var linkDataArray = [
        { from:"N1", to:"N2" }
      ]

      diagram.nodeTemplate = nodeTemplate;
      diagram.linkTemplate = linkTemplate;

      diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
    
   
    }

    window.addEventListener('DOMContentLoaded', init);

  </script>

</head>

<body>

  <div id="myDiagramDiv" style="border: solid 1px blue; width:1000px; height:1000px"></div>

</body>

</html>

If you want link points to persist across save/load, you should use a two-way binding on Link.points, many samples do this such as flowchart which has

new go.Binding("points").makeTwoWay(),

in its link template.

As for resegmenting, the assumption is that you want to change the points of the link except for the ends, so the resegmenting tool will let you modify segments, but will faithfully keep the ends. I can see how this would not be what you want.

You consider using or adapting the Link Shifting tool, which is an example that allows moving the location of the end port as well: Link Shifting Tool

Or you could use multiple ports (one per side, or something) on your node, and then allow relinkableFrom and relinkableTo so that users can explicitly change the side.