Links not getting correctly linked to "from" and "to" nodes

Between from and to nodes, after creating 5 links, when creating the 6th link, the diagram is not showing the 6th links as connected between from and to nodes.
Only when the nodes are moved (either from or to), this 6th link is getting positioned.

Upon analysis, points are always computed to 0 (List all having the value as 0) for this 6th link (or any additional links getting added after 5).
These points are getting recomputed only when we move the nodes to some position.

Let us know why this is happening? By setting any linkTemplate attributes can we ensure to link it immediately to the nodes instead of moving the nodes?

That’s odd. What are your node and link templates? Have you customized the LinkingTool?

Here’s a basic example that demonstrates that adding more links doesn’t cause problems with the points.

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">

<meta name="description" content="An almost minimal diagram using a very simple node template and the default link template." />
<!-- Copyright 1998-2023 by Northwoods Software Corporation. -->
<meta charset="UTF-8">
<script src="https://unpkg.com/gojs@latest/release/go-debug.js"></script>

<script id="code">
  const init = () => {
    const diagram = new go.Diagram("myDiagramDiv", {
      model: new go.GraphLinksModel([
        { key: "Alpha", color: "lightblue" },
        { key: "Beta", color: "orange" }
      ])
    });

    diagram.nodeTemplate =
      new go.Node("Auto")
        .add(
          new go.Shape("RoundedRectangle", {
            strokeWidth: 0, portId: "", cursor: "pointer",
            fromLinkable: true, toLinkable: true,
            fromLinkableDuplicates: true, toLinkableDuplicates: true
          }).bind("fill", "color"),
          new go.TextBlock({ margin: 8 }).bind("text", "key")
        );
  };
</script>
</head>
<body onload="init()">
<div id="sample">
  <div id="myDiagramDiv" style="border: solid 1px black; width:600px; height:600px"></div>
</div>
</body>
</html>

Hi,

We haven’t customised the linkingtool. Our node template is kind of a collection.
Providing below how we have defined our node template and link templates.

Node

	var templmap = new go.Map();
	var texttemplate = $(go.Node, "Auto", {
		locationSpot: go.Spot.TopCenter,
		isShadowed: false,
		selectable: true,
		resizable: true,
		desiredSize: new go.Size(120, 30),
		layerName: "Background",
		avoidable: false,
		selectionAdorned: false,
		rotatable: false
	}, new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify), new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), new go.Binding("angle", "angle").makeTwoWay(), $(go.Panel, "Vertical", {
		alignment: go.Spot.Center,
		alignmentFocus: go.Spot.Center,
	}, $(go.TextBlock, {
		margin: 10,
		editable: true,
		font: '10pt sans-serif'
	}, new go.Binding("text").makeTwoWay())));
	var diamondtemplate = $(go.Node, "Auto", {
		locationSpot: go.Spot.TopCenter,
		isShadowed: false,
		selectable: true,
		resizable: true,
		desiredSize: new go.Size(100, 100),
		layerName: "Background",
		avoidable: false,
		selectionAdorned: false
	}, new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify), new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), $(go.Shape, "Diamond", roundedBackgroundRectangleParams, {
		name: "SHAPE",
		fill: strokewhite,
		strokeWidth: 1,
		stroke: '#a6a6a6',
		fromLinkable: false,
		fromLinkableSelfNode: false,
		fromLinkableDuplicates: false,
		toLinkable: false,
		toLinkableSelfNode: false,
		toLinkableDuplicates: false,
	}), $(go.Panel, "Vertical", {
		alignment: go.Spot.Center,
		alignmentFocus: go.Spot.Center,
	}, $(go.TextBlock, {
		margin: 10,
		editable: true,
		font: '10pt sans-serif'
	}, new go.Binding("text").makeTwoWay())));
	var diamonddotteddtemplate = $(go.Node, "Auto", {
		locationSpot: go.Spot.TopCenter,
		isShadowed: false,
		selectable: true,
		resizable: true,
		desiredSize: new go.Size(100, 100),
		layerName: "Background",
		avoidable: false,
		selectionAdorned: false
	}, new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify), new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), $(go.Shape, "Diamond", roundedBackgroundRectangleParams, {
		name: "SHAPE",
		fill: "transparent",
		strokeWidth: 1,
		stroke: '#a6a6a6',
		fromLinkable: false,
		fromLinkableSelfNode: false,
		fromLinkableDuplicates: false,
		toLinkable: false,
		toLinkableSelfNode: false,
		toLinkableDuplicates: false,
	}), $(go.Panel, "Vertical", {
		alignment: go.Spot.Center,
		alignmentFocus: go.Spot.Center,
	}, $(go.TextBlock, {
		margin: 10,
		editable: true,
		font: '10pt sans-serif'
	}, new go.Binding("text").makeTwoWay())));	
var circletemplate = $(go.Node, "Auto", {
		locationSpot: go.Spot.TopCenter,
		isShadowed: false,
		selectable: true,
		resizable: true,
		desiredSize: new go.Size(100, 100),
		layerName: "Background",
		avoidable: false,
		selectionAdorned: false
	}, new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify), new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), $(go.Shape, "Circle", roundedBackgroundRectangleParams, {
		name: "SHAPE",
		fill: strokewhite,
		strokeWidth: 1,
		stroke: '#a6a6a6',
		fromLinkable: false,
		fromLinkableSelfNode: false,
		fromLinkableDuplicates: false,
		toLinkable: false,
		toLinkableSelfNode: false,
		toLinkableDuplicates: false,
	}), $(go.Panel, "Vertical", {
		alignment: go.Spot.Center,
		alignmentFocus: go.Spot.Center,
	}, $(go.TextBlock, {
		margin: 10,
		editable: true,
		font: '10pt sans-serif'
	}, new go.Binding("text").makeTwoWay())));
	var circledottedtemplate = $(go.Node, "Auto", {
		locationSpot: go.Spot.TopCenter,
		isShadowed: false,
		selectable: true,
		resizable: true,
		desiredSize: new go.Size(100, 100),
		layerName: "Background",
		avoidable: false,
		selectionAdorned: false
	}, new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify), new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), $(go.Shape, "Circle", roundedBackgroundRectangleParams, {
		name: "SHAPE",
		fill: "transparent",
		strokeWidth: 1,
		stroke: '#a6a6a6',
		fromLinkable: false,
		fromLinkableSelfNode: false,
		fromLinkableDuplicates: false,
		toLinkable: false,
		toLinkableSelfNode: false,
		toLinkableDuplicates: false,
	}), $(go.Panel, "Vertical", {
		alignment: go.Spot.Center,
		alignmentFocus: go.Spot.Center,
	}, $(go.TextBlock, {
		margin: 10,
		editable: true,
		font: '10pt sans-serif'
	}, new go.Binding("text").makeTwoWay())));
	var triangleuptemplate = $(go.Node, "Auto", {
		locationSpot: go.Spot.TopCenter,
		isShadowed: false,
		selectable: true,
		resizable: true,
		desiredSize: new go.Size(100, 100),
		layerName: "Background",
		avoidable: false,
		selectionAdorned: false
	}, new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify), new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), $(go.Shape, "TriangleUp", roundedBackgroundRectangleParams, {
		name: "SHAPE",
		fill: strokewhite,
		strokeWidth: 1,
		stroke: strokegray,
		fromLinkable: false,
		fromLinkableSelfNode: false,
		fromLinkableDuplicates: false,
		toLinkable: false,
		toLinkableSelfNode: false,
		toLinkableDuplicates: false,
	}), $(go.Panel, "Vertical", {
		alignment: go.Spot.Center,
		alignmentFocus: go.Spot.Center,
	}, $(go.TextBlock, {
		margin: 10,
		editable: true,
		font: '10pt sans-serif'
	}, new go.Binding("text").makeTwoWay())));
	var triangledowntemplate = $(go.Node, "Auto", {
		locationSpot: go.Spot.TopCenter,
		isShadowed: false,
		selectable: true,
		resizable: true,
		desiredSize: new go.Size(100, 100),
		layerName: "Background",
		avoidable: false,
		selectionAdorned: false
	}, new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify), new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), $(go.Shape, "TriangleDown", roundedBackgroundRectangleParams, {
		name: "SHAPE",
		fill: "transparent",
		strokeWidth: 1,
		stroke: '#a6a6a6',
		fromLinkable: false,
		fromLinkableSelfNode: false,
		fromLinkableDuplicates: false,
		toLinkable: false,
		toLinkableSelfNode: false,
		toLinkableDuplicates: false,
	}), $(go.Panel, "Vertical", {
		alignment: go.Spot.TopLeft,
		alignmentFocus: go.Spot.TopLeft,
	}, $(go.TextBlock, {
		margin: 10,
		editable: true,
		font: '10pt sans-serif'
	}, new go.Binding("text").makeTwoWay())));
	var linehtemplate = $(go.Node, "Auto", {
		locationSpot: go.Spot.TopCenter,
		isShadowed: false,
		selectable: true,
		resizable: true,
		desiredSize: new go.Size(100, 100),
		layerName: "Background",
		avoidable: false,
		selectionAdorned: false
	}, new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify), new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), $(go.Shape, "LineH", {
		name: "SHAPE",
		fill: "transparent",
		strokeWidth: 1,
		stroke: '#a6a6a6',
		fromLinkable: false,
		fromLinkableSelfNode: false,
		fromLinkableDuplicates: false,
		toLinkable: false,
		toLinkableSelfNode: false,
		toLinkableDuplicates: false,
	}), $(go.Panel, "Horizontal", {
		alignment: go.Spot.Center,
		alignmentFocus: go.Spot.Center,
	}, $(go.TextBlock, {
		margin: 10,
		editable: true,
		font: '10pt sans-serif'
	}, new go.Binding("text").makeTwoWay())));
	var linevtemplate = $(go.Node, "Auto", {
		locationSpot: go.Spot.TopCenter,
		isShadowed: false,
		selectable: true,
		resizable: true,
		desiredSize: new go.Size(100, 100),
		layerName: "Background",
		avoidable: false,
		selectionAdorned: false
	}, new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify), new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), $(go.Shape, "LineV", {
		name: "SHAPE",
		fill: "transparent",
		strokeWidth: 1,
		stroke: '#a6a6a6',
		fromLinkable: false,
		fromLinkableSelfNode: false,
		fromLinkableDuplicates: false,
		toLinkable: false,
		toLinkableSelfNode: false,
		toLinkableDuplicates: false,
	}), $(go.Panel, "Vertical", {
		alignment: go.Spot.Center,
		alignmentFocus: go.Spot.Center,
		angle: 90
	}, $(go.TextBlock, {
		margin: 10,
		editable: true,
		font: '10pt sans-serif'
	}, new go.Binding("text").makeTwoWay())));	
var backgroundtemplate = $(go.Node, "Auto", {
		locationSpot: go.Spot.TopCenter,
		isShadowed: false,
		selectable: true,
		resizable: true,
		desiredSize: new go.Size(100, 100),
		layerName: "Background",
		avoidable: false,
		selectionAdorned: false
	}, new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify), new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), $(go.Shape, "RoundedRectangle", roundedBackgroundRectangleParams, {
		name: "SHAPE",
		fill: strokewhite,
		strokeWidth: 1,
		stroke: strokegray,
		fromLinkable: false,
		fromLinkableSelfNode: false,
		fromLinkableDuplicates: false,
		toLinkable: false,
		toLinkableSelfNode: false,
		toLinkableDuplicates: false,
	}), $(go.Panel, "Vertical", {
		alignment: go.Spot.TopLeft,
		alignmentFocus: go.Spot.TopLeft,
	}, $(go.TextBlock, {
		margin: 10,
		editable: true,
		font: '10pt sans-serif'
	}, new go.Binding("text").makeTwoWay())));
	var backgrounddottedtemplate = $(go.Node, "Auto", {
		locationSpot: go.Spot.TopCenter,
		isShadowed: false,
		selectable: true,
		resizable: true,
		desiredSize: new go.Size(100, 100),
		layerName: "Background",
		avoidable: false,
		selectionAdorned: false
	}, new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify), new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), $(go.Shape, "RoundedRectangle", roundedBackgroundRectangleParams, {
		name: "SHAPE",
		fill: "transparent",
		strokeWidth: 1,
		stroke: '#a6a6a6',
		fromLinkable: false,
		fromLinkableSelfNode: false,
		fromLinkableDuplicates: false,
		toLinkable: false,
		toLinkableSelfNode: false,
		toLinkableDuplicates: false,
	}), $(go.Panel, "Vertical", {
		alignment: go.Spot.TopLeft,
		alignmentFocus: go.Spot.TopLeft,
	}, $(go.TextBlock, {
		margin: 10,
		editable: true,
		font: '10pt sans-serif'
	}, new go.Binding("text").makeTwoWay())));
	var externaltemplate = $(go.Node, "Auto", {
			locationSpot: go.Spot.TopCenter,
			isShadowed: true,
			shadowBlur: 0,
			shadowOffset: new go.Point(0, 0),
			shadowColor: "rgba(0, 0, 0, 0)",
			selectable: true,
			resizable: false,
			layerName: "",
			cursor: "pointer",
			selectionAdorned: false,
			avoidable: false
		},
		new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), $(go.Shape, "RoundedRectangle", roundedRectangleParams, {
			name: "SHAPE",
			fill: strokewhite,
			strokeWidth: strokeWidthLink,
			stroke: strokegray,
			portId: "",
			fromLinkable: true,
			fromLinkableSelfNode: true,
			fromLinkableDuplicates: true,
			toLinkable: true,
			toLinkableSelfNode: false,
			toLinkableDuplicates: true,
			cursor: "pointer",
		}), $(go.Picture, {
			name: "IMAGE",
			visible: true,
			margin: 10,
			width: nodeWitdh,
			height: nodeHeight,
			cursor: "pointer",
			opacity: 1
		}, new go.Binding("source")),
	// four small named ports, one on each side:
	makePort("T", go.Spot.Top, false, true),
	makePort("L", go.Spot.Left, true, true),
	makePort("R", go.Spot.Right, true, true),
	makePort("B", go.Spot.Bottom, true, false),
	{ // handle mouse enter/leave events to show/hide the ports
	  mouseEnter: (e, node) => showSmallPorts(node, true),
	  mouseLeave: (e, node) => showSmallPorts(node, false),
	});
	var adaptertemplate = $(go.Node, "Auto", {
			locationSpot: go.Spot.TopCenter,
			isShadowed: true,
			shadowBlur: 0,
			shadowOffset: new go.Point(0, 1),
			shadowColor: "rgba(0, 0, 0, .14)",
			selectable: true,
			resizable: false,
			layerName: "",
			cursor: "pointer",
			selectionAdorned: false
		},
		new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), 
		$(go.Shape, "RoundedRectangle", roundedRectangleParams, {
			name: "SHAPE",
			fill: strokewhite,
			strokeWidth: strokeWidthLink,
			stroke: strokelightgray,
			portId: "",
			fromLinkable: true,
			fromLinkableSelfNode: true,
			fromLinkableDuplicates: true,
			toLinkable: true,
			toLinkableSelfNode: true,
			toLinkableDuplicates: true,
			cursor: "pointer",
		}),
		
		$(go.TextBlock, { margin: 5 },
			new go.Binding("text", "key")),
		  {
			toolTip:                       
			  $(go.Adornment, "Spot",    
				$(go.TextBlock, "Bottom",
				  { margin: 5,background:"white"},
				  new go.Binding("text", "appName"))
				)  
		  },
		  
		  $(go.Picture, {
			name: "IMAGE",
			visible: true,
			margin: 10,
			width: nodeWitdh,
			height: nodeHeight,
			cursor: "pointer",
			opacity: 1
		}, new go.Binding("source")),
		
		makePort("T", go.Spot.Top, false, true),
		makePort("L", go.Spot.Left, true, true),
		makePort("R", go.Spot.Right, true, true),
		makePort("B", go.Spot.Bottom, true, false),
		{ 
		  mouseEnter: (e, node) => showSmallPorts(node, true),
		  mouseLeave: (e, node) => showSmallPorts(node, false),
		}
		);
	var connectiontemplate = $(go.Node, "Auto", {
			locationSpot: go.Spot.TopCenter,
			isShadowed: true,
			shadowBlur: 0,
			shadowOffset: new go.Point(0, 1),
			shadowColor: "rgba(0, 0, 0, .14)",
			selectable: true,
			resizable: false,
			layerName: "",
			cursor: "pointer",
			selectionAdorned: false,
			click: nodeSelection,
		},

		new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
		$(go.Shape, "RoundedRectangle", roundedRectangleParams, {
			name: "SHAPE",
			fill: strokewhite,
			strokeWidth: strokeWidthLink,
			stroke: strokegreen,
			portId: "",
			fromSpot: go.Spot.AllSides,
			toSpot: go.Spot.AllSides,
			fromLinkable: true,
			fromLinkableSelfNode: true,
			fromLinkableDuplicates: true,
			toLinkable: true,
			toLinkableSelfNode: true,
			toLinkableDuplicates: true,
			cursor: "pointer",
		}),
		  
		  $(go.Picture, {
			name: "IMAGE",
			visible: true,
			margin: 10,
			width: nodeWitdh,
			height: nodeHeight,
			cursor: "pointer",
			opacity: 1
		}, new go.Binding("source")),
		$(go.TextBlock, { margin: 5 },
			new go.Binding("text", "key")),
		  {
			toolTip:                       
			  $(go.Adornment, "Spot",    
				$(go.TextBlock, "Bottom",
				  { margin: 5,background:"white"},
				  new go.Binding("text", "connectionName"))
				)  
		  },
		// four small named ports, one on each side:
		makePort("T", go.Spot.Top, false, true),
		makePort("L", go.Spot.Left, true, true),
		makePort("R", go.Spot.Right, true, true),
		makePort("B", go.Spot.Bottom, true, false),
		{ // handle mouse enter/leave events to show/hide the ports
		  mouseEnter: (e, node) => showSmallPorts(node, true),
		  mouseLeave: (e, node) => showSmallPorts(node, false),
		}
		
		);

Link

	var linktemplate = $(go.Link, {
			name: "link",
			routing: go.Link.AvoidsNodes,
			smoothness: 0.9,
			curve: go.Link.JumpOver,
			corner: 20,
			reshapable: true,
			resegmentable: false,
			relinkableFrom: false,
			relinkableTo: false,
			selectionAdorned: false,
			adjusting: go.Link.Stretch,
			layerName: "",
			click: linkSelection,
			cursor: "pointer",
		},
		new go.Binding("points").makeTwoWay(),
		new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify),
		new go.Binding("fromSpot", "fromSpot", go.Spot.parse).makeTwoWay(go.Spot.stringify),
		new go.Binding("toSpot", "toSpot", go.Spot.parse).makeTwoWay(go.Spot.stringify),
		$(go.Shape, {
				name: "SHAPE",
				strokeWidth: strokeWidthLink
			},
			new go.Binding("stroke", "", function (link) {
				return linkColor(link)
			})),
		$(go.Shape, {
				name: "FROM",
				scale: arrowScale
			},
			new go.Binding("stroke", "", function (link) {
				return linkColor(link)
			}),
			new go.Binding("fill", "", function (link) {
				return linkColor(link)
			}),
			new go.Binding("fromArrow", "", function (link) {
				return linkArrow(link, "Backward")
			})),
		$(go.Panel, "Auto", {
				name: "linkTextPanel",
				_isLinkLabel: true,
				segmentIndex: NaN,
				segmentFraction: .5,
				visible: true,
			},
			new go.Binding("segmentFraction").makeTwoWay(),

			$(go.Shape, "RoundedRectangle", {
				name: "linkTextBackGround",
				fill: strokewhite,
				strokeWidth: 1,
				stroke: strokelightblue,
			}),
			$(go.TextBlock, {
					name: "linkTextBlock",
					textAlign: "center",
					font: "9pt helvetica, arial, sans-serif",
					background: strokewhite,
					margin: 8,
					visible: true,
					maxSize: new go.Size(230, NaN)
				},
				new go.Binding("text", "linkText" ) ),
			$(go.Picture, linkWarningImage, {
				name: "linkError",
				desiredSize: new go.Size(10, 10),
				alignment: go.Spot.TopRight,
				click: linkErrors,
				visible: false,
				cursor: "pointer"
			})
		),
		$(go.Shape, {
				name: "TO",
				scale: arrowScale
			},
			new go.Binding("stroke", "", function (link) {
				return linkColor(link)
			}),
			new go.Binding("fill", "", function (link) {
				return linkColor(link)
			}),
			new go.Binding("toArrow", "", function (link) {
				return linkArrow(link, "Standard")
			}))
	);

Diagram intialization with templates

	templmap.add("external", externaltemplate);
	templmap.add("connection", connectiontemplate);
	templmap.add("adapter", adaptertemplate);
	templmap.add("background", backgroundtemplate);
	templmap.add("backgrounddotted", backgrounddottedtemplate);
	templmap.add("circle", circletemplate);
	templmap.add("circledotted", circledottedtemplate);
	templmap.add("diamond", diamondtemplate);
	templmap.add("diamonddotted", diamonddotteddtemplate);
	templmap.add("triangleup", triangleuptemplate);
	templmap.add("triangledown", triangledowntemplate);
	templmap.add("lineh", linehtemplate);
	templmap.add("linev", linevtemplate);
	templmap.add("text", texttemplate);
	myDiagram.nodeTemplateMap = templmap;
	myDiagram.linkTemplate = linktemplate;

Could you please share before and after screenshots showing 5 and 6 links?

Hi,

PFA the recording of the same.

But this time i got it for a 2nd link itself. I was not even able to create five links with proper nodes connected.

  1. First already there is a link (named LinkOne).
  2. Second, as part of our app feature, we are trying to clone. During clone (as LinkTwo), it has to link the two nodes.
  3. If you see the diagram after creating LinkTwo, somewhere the points are plotted and nodes are not connected.

  1. But when i try to click the “LinkTwo”, you can see that the points will be plotted and the nodes connection is visible.

  1. I did a page refresh, again for “LinkTwo” the nodes will not be connected (eventhough upon selecting the link it will show the connected nodes).

  2. Now I tried moving one node to some other position

  3. And then, I refreshed the page again. Now if you see the points are plotted and nodes are connected for “LinkTwo”.

Any help is much appreciated.

There is only one category/template for all links. What category or categories of nodes are shown in your example?

How are you “cloning” links? Could you please show the GraphLinksModel.linkDataArray both before and after?

Why is there a third link, a reflexive one, connecting the top node with itself, in the last screenshot?

Yes. There is only one template for the links. The declaration is shared above.

Cloning is simply we are cloning some of our app related properties/attributes we will set the same to the another link (not related to diagram) in the linkDataArray.

The third link is a mistake. When I tried to drag the node to a different position, mistakenly I created a self link. Please ignore that.

Find below the diagram properties (points, from, to - which we store as json and it also includes our app related properties) for LinkOne.

{
   "class":"GraphLinksModel",
   "nodeKeyProperty":"id",
   "linkKeyProperty":"id",
   "nodeDataArray":[
      {
         "loc":"-322.82421875 -232.2265625",
         "visible":"true",
         "appName":"Atlassian JIRA",
         "groups":"",
         "appCategory":"",
         "source":"logo.jpg",
         "type":"jira",
         "Url":"xxxxxxxx",
         "id":"4827327270713",
         "text":"Atlassian JIRA",
         "connectionName":"testconnection",
         "category":"connection",
         "isGroup":false,
         "group":0
      },
      {
         "loc":"120 60",
         "visible":"true",
         "appName":"Atlassian JIRA",
         "groups":"",
         "appCategory":"",
         "source":"logo.jpg",
         "type":"jira",
         "Url":"xxxxxxxx",
         "id":"5297854419146",
         "text":"Atlassian JIRA",
         "connectionName":"newconnection",
         "category":"connection",
         "isGroup":false,
         "group":0
      }
   ],
   "linkDataArray":[
      {
         "toSyncOption":"Toboth",
         "visible":"true",
         "fromSyncOption":"Fromboth",
         "groups":"unassigned",
         "linkText":"LinkOne",
         "points":[
            -298.32421875,
            -207.7265625,
            -288.32421875,
            -207.7265625,
            -288.32421875,
            -67.921875,
            85.5,
            -67.921875,
            85.5,
            76.33333333333334,
            95.5,
            76.33333333333334
         ],
         "linkStatus":"disabled",
         "linkSchedule":"every minute every day",
         "from":"4827327270713",
         "linkType":"Synchronization",
         "id":"LinkOne",
         "to":"5297854419146",
         "text":"Bug / Bug",
         "category":"applink"
      },
      {
         "linkStatus":"available",
         "toSyncOption":"",
         "visible":"true",
         "fromSyncOption":"",
         "groups":"unassigned",
         "from":"4827327270713",
         "linkText":"",
         "linkType":"Synchronization",
         "id":"-3",
         "to":"4827327270713",
         "category":"dislink",
         "points":[
            -298.32421875,
            -207.7265625,
            -272.32421875,
            -207.7265625,
            -272.32421875,
            -157.2265625,
            -297.57421875,
            -157.2265625,
            -322.82421875,
            -157.2265625,
            -322.82421875,
            -183.2265625
         ]
      }
   ]
}

Find below the diagram properties computed immediately after creating LinkTwo.

{
  "class":"GraphLinksModel",
  "nodeKeyProperty":"id",
  "linkKeyProperty":"id",
  "nodeDataArray":[
     {
        "loc":"-322.82421875 -232.2265625",
        "visible":"true",
        "appName":"Atlassian JIRA",
        "groups":"",
        "appCategory":"",
        "source":"logo.jpg",
        "type":"jira",
        "Url":"xxxxxxxx",
        "id":"4827327270713",
        "text":"Atlassian JIRA",
        "connectionName":"testconnection",
        "category":"connection",
        "isGroup":false,
        "group":0
     },
     {
        "loc":"120 60",
        "visible":"true",
        "appName":"Atlassian JIRA",
        "groups":"",
        "appCategory":"",
        "source":"logo.jpg",
        "type":"jira",
        "Url":"xxxxxxxx",
        "id":"5297854419146",
        "text":"Atlassian JIRA",
        "connectionName":"newconnection",
        "category":"connection",
        "isGroup":false,
        "group":0
     }
  ],
  "linkDataArray":[
     {
        "toSyncOption":"Toboth",
        "visible":"true",
        "fromSyncOption":"Fromboth",
        "groups":"unassigned",
        "linkText":"LinkTwo",
        "linkStatus":"disabled",
        "linkSchedule":"every minute every day",
        "from":"4827327270713",
        "linkType":"Synchronization",
        "id":"LinkTwo",
        "to":"5297854419146",
        "text":"Bug / Bug",
        "category":"applink",
        "points":[
           0,
           0,
           0,
           0,
           39.25,
           0,
           39.25,
           91.33333333333333,
           78.5,
           91.33333333333333,
           96.5,
           91.33333333333333
        ]
     },
     {
        "toSyncOption":"Toboth",
        "visible":"true",
        "fromSyncOption":"Fromboth",
        "groups":"unassigned",
        "linkText":"LinkOne",
        "points":[
           -298.32421875,
           -207.7265625,
           -288.32421875,
           -207.7265625,
           -288.32421875,
           -67.921875,
           85.5,
           -67.921875,
           85.5,
           76.33333333333334,
           95.5,
           76.33333333333334
        ],
        "linkStatus":"disabled",
        "linkSchedule":"every minute every day",
        "from":"4827327270713",
        "linkType":"Synchronization",
        "id":"LinkOne",
        "to":"5297854419146",
        "text":"Bug / Bug",
        "category":"applink"
     },
     {
        "linkStatus":"available",
        "toSyncOption":"",
        "visible":"true",
        "fromSyncOption":"",
        "groups":"unassigned",
        "from":"4827327270713",
        "linkText":"",
        "linkType":"Synchronization",
        "id":"-3",
        "to":"4827327270713",
        "category":"dislink",
        "points":[
           -298.32421875,
           -207.7265625,
           -272.32421875,
           -207.7265625,
           -272.32421875,
           -157.2265625,
           -297.57421875,
           -157.2265625,
           -322.82421875,
           -157.2265625,
           -322.82421875,
           -183.2265625
        ]
     }
  ]
}

Using your node template, I still cannot reproduce any problem.

<!DOCTYPE html>
<html>
<head>
  <!-- Copyright 1998-2022 by Northwoods Software Corporation. -->
</head>
<body>
  <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:400px"></div>
  
  <script src="go.js"></script>
  <script id="code">
const $ = go.GraphObject.make;

const myDiagram =
  $(go.Diagram, "myDiagramDiv",
    {
      "undoManager.isEnabled": true
    });

      // Define a function for creating a "port" that is normally transparent.
      // The "name" is used as the GraphObject.portId, the "spot" is used to control how links connect
      // and where the port is positioned on the node, and the boolean "output" and "input" arguments
      // control whether the user can draw links from or to the port.
      function makePort(name, spot, output, input) {
        // the port is basically just a small transparent circle
        return $(go.Shape,
          {
            fill: null,  // not seen, by default; set to a translucent gray by showSmallPorts, defined below
            stroke: null,
            desiredSize: new go.Size(7, 7),
            alignment: spot,  // align the port on the main Shape
            alignmentFocus: spot,  // just inside the Shape
            portId: name,  // declare this object to be a "port"
            fromSpot: spot, toSpot: spot,  // declare where links may connect at this port
            fromLinkable: output, toLinkable: input,  // declare whether the user may draw links to/from here
            cursor: "pointer"  // show a different cursor to indicate potential link point
          });
      }

      function showSmallPorts(node, show) {
        node.ports.each(port => {
          if (port.portId !== "") {  // don't change the default port, which is the big shape
            port.fill = show ? "rgba(0,0,0,.3)" : null;
          }
        });
      }

myDiagram.nodeTemplate =
  $(go.Node, "Auto", {
			locationSpot: go.Spot.TopCenter,
			isShadowed: true,
			shadowBlur: 0,
			shadowOffset: new go.Point(0, 1),
			shadowColor: "rgba(0, 0, 0, .14)",
			selectable: true,
			resizable: false,
			layerName: "",
			cursor: "pointer",
			selectionAdorned: false,
			//click: nodeSelection,
		},

		new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
		$(go.Shape, "RoundedRectangle", /*roundedRectangleParams,*/ {
			name: "SHAPE",
			fill: "white",  //strokewhite,
			strokeWidth: 2, //strokeWidthLink,
			stroke: "green", //strokegreen,
			portId: "",
			fromSpot: go.Spot.AllSides,
			toSpot: go.Spot.AllSides,
			fromLinkable: true,
			fromLinkableSelfNode: true,
			fromLinkableDuplicates: true,
			toLinkable: true,
			toLinkableSelfNode: true,
			toLinkableDuplicates: true,
			cursor: "pointer",
		}),
		  
		  $(go.Picture, {
			name: "IMAGE",
			visible: true,
			margin: 10,
			width: 32, //nodeWitdh,
			height: 32, //nodeHeight,
			cursor: "pointer",
			opacity: 1
		}, new go.Binding("source")),
		$(go.TextBlock, { margin: 5 },
			new go.Binding("text", "key")),
		  {
			toolTip:                       
			  $(go.Adornment, "Spot",    
				$(go.TextBlock, "Bottom",
				  { margin: 5,background:"white"},
				  new go.Binding("text", "connectionName"))
				)  
		  },
		// four small named ports, one on each side:
		makePort("T", go.Spot.Top, false, true),
		makePort("L", go.Spot.Left, true, true),
		makePort("R", go.Spot.Right, true, true),
		makePort("B", go.Spot.Bottom, true, false),
		{ // handle mouse enter/leave events to show/hide the ports
		  mouseEnter: (e, node) => showSmallPorts(node, true),
		  mouseLeave: (e, node) => showSmallPorts(node, false),
		}
		
  );

myDiagram.linkTemplate =
  $(go.Link, {
			name: "link",
			routing: go.Link.AvoidsNodes,
			smoothness: 0.9,
			curve: go.Link.JumpOver,
			corner: 20,
			reshapable: true,
			resegmentable: false,
			relinkableFrom: false,
			relinkableTo: false,
			selectionAdorned: false,
			adjusting: go.Link.Stretch,
			layerName: "",
			//click: linkSelection,
			cursor: "pointer",
		},
		new go.Binding("points").makeTwoWay(),
		new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify),
		new go.Binding("fromSpot", "fromSpot", go.Spot.parse).makeTwoWay(go.Spot.stringify),
		new go.Binding("toSpot", "toSpot", go.Spot.parse).makeTwoWay(go.Spot.stringify),
		$(go.Shape, {
				name: "SHAPE",
				strokeWidth: 2 //strokeWidthLink
			},
			// new go.Binding("stroke", "", function (link) {
			// 	return linkColor(link)
			// })
    ),
		// $(go.Shape, {
		// 		name: "FROM",
		// 		scale: 1 //arrowScale
		// 	},
		// 	// new go.Binding("stroke", "", function (link) {
		// 	// 	return linkColor(link)
		// 	// }),
		// 	// new go.Binding("fill", "", function (link) {
		// 	// 	return linkColor(link)
		// 	// }),
		// 	// new go.Binding("fromArrow", "", function (link) {
		// 	// 	return linkArrow(link, "Backward")
		// 	// })
    // ),
		// $(go.Panel, "Auto", {
		// 		name: "linkTextPanel",
		// 		_isLinkLabel: true,
		// 		segmentIndex: NaN,
		// 		segmentFraction: .5,
		// 		visible: true,
		// 	},
		// 	new go.Binding("segmentFraction").makeTwoWay(),

		// 	$(go.Shape, "RoundedRectangle", {
		// 		name: "linkTextBackGround",
		// 		fill: "white", //strokewhite,
		// 		strokeWidth: 1,
		// 		stroke: "lightblue" //strokelightblue,
		// 	}),
		// 	$(go.TextBlock, {
		// 			name: "linkTextBlock",
		// 			textAlign: "center",
		// 			font: "9pt helvetica, arial, sans-serif",
		// 			background: "white", //strokewhite,
		// 			margin: 8,
		// 			visible: true,
		// 			maxSize: new go.Size(230, NaN)
		// 		},
		// 		new go.Binding("text", "linkText" ) ),
		// 	$(go.Picture, /*linkWarningImage,*/ {
		// 		name: "linkError",
		// 		desiredSize: new go.Size(10, 10),
		// 		alignment: go.Spot.TopRight,
		// 		//click: linkErrors,
		// 		visible: false,
		// 		cursor: "pointer"
		// 	})
		// ),
		// $(go.Shape, {
		// 		name: "TO",
		// 		scale: 1 //arrowScale
		// 	},
		// 	// new go.Binding("stroke", "", function (link) {
		// 	// 	return linkColor(link)
		// 	// }),
		// 	// new go.Binding("fill", "", function (link) {
		// 	// 	return linkColor(link)
		// 	// }),
		// 	// new go.Binding("toArrow", "", function (link) {
		// 	// 	return linkArrow(link, "Standard")
		// 	// })
    // )
	);

myDiagram.model = new go.GraphLinksModel(
  {
    linkFromPortIdProperty: "fpid",
    linkToPortIdProperty: "tpid",
    nodeDataArray: [
      { key: 1, text: "Alpha", color: "lightblue", loc: "0 0" },
      { key: 2, text: "Beta", color: "orange", loc: "120 0" },
      { key: 3, text: "Gamma", color: "lightgreen", loc: "200 210" },
      { key: 4, text: "Delta", color: "pink", loc: "180 70" }
    ],
    linkDataArray: [
      { from: 1, fpid: "B", to: 3, tpid: "T" }
    ]
  });
  </script>
</body>
</html>

By the way, you could write some of your bindings much more concisely. Instead of:

			new go.Binding("stroke", "", function (link) {
				return linkColor(link)
			})

You could just write:

			new go.Binding("stroke", "", l => linkColor(l))

Or because linkColor takes the unmodified parameter as its first and only required argument:

			new go.Binding("stroke", "", linkColor)

I didn’t know about your linkColor function nor a bunch of other stuff, so I commented that out from your templates. These kinds of things shouldn’t matter for this topic, though.