Link ends when shape size changes

I have a diagram similar to state chart

I do save the diagram in the database

now when I open the diagram again after reading the nodes position and the transitions points everything is OK.

the above diagram is kind of template to a more complicate diagram

now I open the complicated diagram , it has more information in its nodes.
that diagram is read only
the problem I have is that the transition are not connected to the nodes. sometimes there is a gap between them and sometimes the transition is drawn on the node.

is there a way to connect the transition lines with the shape correctly (and try to keep the points)
note that the new nodes size are only slightly bigger

You could try to fix up the link routes once the link points have been loaded, in case the saved routes do not match any new node bounds due to changed content.

The following example depends on Link.adjusting being different than the default None:

<!DOCTYPE html>
  <title>State Chart</title>
  <!-- Copyright 1998-2021 by Northwoods Software Corporation. -->
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="go.js"></script>
  <script id="code">
  function init() {
    var $ = go.GraphObject.make;

    myDiagram =
      $(go.Diagram, "myDiagramDiv",
          "InitialLayoutCompleted": function(e) {
            setTimeout(function() {
              e.diagram.commit(function(diag) {
                diag.links.each(function(l) { l.invalidateRoute(); });
            }, 1);

    myDiagram.nodeTemplate =
      $(go.Node, "Auto",
        { locationSpot: go.Spot.Center },
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        $(go.Shape, "RoundedRectangle",
            parameter1: 20,  // the corner has a large radius
            fill: "goldenrod",
            portId: "", cursor: "pointer",
            fromLinkable: true, fromLinkableDuplicates: true,
            toLinkable: true, toLinkableDuplicates: true
          { margin: 10, editable: true },
          new go.Binding("text").makeTwoWay())

    myDiagram.linkTemplate =
          curve: go.Link.Bezier, adjusting: go.Link.End,
          relinkableFrom: true, relinkableTo: true,
          reshapable: true
        new go.Binding("points").makeTwoWay(),
        $(go.Shape, { strokeWidth: 1.5 }),
        $(go.Shape, { toArrow: "standard", stroke: null })


  function save() {
    document.getElementById("mySavedModel").value = myDiagram.model.toJson();
    myDiagram.isModified = false;
  function load() {
    myDiagram.model = go.Model.fromJson(document.getElementById("mySavedModel").value);
<body onload="init()">
<div id="sample">
  <div id="myDiagramDiv" style="background-color: whitesmoke; border: solid 1px black; width: 100%; height: 400px"></div>
  <button id="SaveButton" onclick="save()">Save</button>
  <button onclick="load()">Load</button>
  Diagram Model saved in JSON format:
  <textarea id="mySavedModel" style="width:100%;height:300px">
{ "class": "GraphLinksModel",
  "nodeKeyProperty": "id",
  "linkLabelKeysProperty": "labelKeys",
  "nodeDataArray": [
{"id":0,"loc":"100 0","text":"Initial"},
{"id":1,"loc":"300 100","text":"First down"}
  "linkDataArray": [

this is working!!
why do we need to set timeout?
can we do without it?
why 10ms do we need more time in some cases?

It could be done within the initial transaction that happens when you replace a Diagram.model, and that might be better for undo/redo usage. But I thought for your purposes this was easier to implement.

Maybe I should have used 1 millisecond instead. It’s quite plausible that 0 milliseconds would work too, but I haven’t tested that and would want to try it on different browsers and different platforms. I just wanted a follow-on transaction to happen after the loading of the model and initialization of all of the Nodes and Links in the Diagram.