OK, so I’ll assume that you are not using different ports on each node, and that your question only involves the temporaryLink used by the LinkingTool (or RelinkingTool, maybe).
So I have modified your code in my node template so that the port-like panel has a name that is the portId of the actual port object prefixed with “". I have overridden LinkingTool.findLinkablePort so that when the user starts drawing a new link from that transparent Shape it finds that Panel whose name is prefixed with "”, which causes that method to return the actual port object whose portId is the rest of that name. That way the LinkingTool operates thinking it’s drawing a new link from that little circular object.
But because you aren’t actually using multiple ports on nodes (because the GraphLinksModel doesn’t support links with particular port identifiers), the actual Link created between the Nodes will only connect with the default port on each Node (Node.port), which is either the port whose portId is the empty string or else (if no such element) the whole Node.
<!DOCTYPE html>
<html>
<head>
<title>Minimal GoJS Sample</title>
<!-- Copyright 1998-2024 by Northwoods Software Corporation. -->
</head>
<body>
<div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:600px"></div>
<textarea id="mySavedModel" style="width:100%;height:250px"></textarea>
<script src="https://unpkg.com/gojs"></script>
<script id="code">
const myDiagram =
new go.Diagram("myDiagramDiv",
{
"linkingTool.findLinkablePort": function() {
const diagram = this.diagram;
let obj = this.startObject;
if (obj === null) {
obj = diagram.findObjectAt(diagram.firstInput.documentPoint,
obj => {
while (obj && obj.name[0] !== "_") obj = obj.panel;
if (obj && obj.name[0] === "_") return obj;
return null;
});
if (obj === null) return null;
this.startObject = obj.part.findPort(obj.name.substring(1));
}
return go.LinkingTool.prototype.findLinkablePort.call(this);
},
"undoManager.isEnabled": true,
"ModelChanged": e => { // just for demonstration purposes,
if (e.isTransactionFinished) { // show the model data in the page's TextArea
document.getElementById("mySavedModel").textContent = e.model.toJson();
}
}
});
const $ = go.GraphObject.make;
myDiagram.nodeTemplate =
new go.Node("Spot")
.add(
new go.Shape({ fill: "white" })
.bind("fill", "color"),
new go.TextBlock({ margin: 8 })
.bind("text"),
$(go.Panel, go.Panel.Auto,
{
alignment: go.Spot.Right,
alignmentFocusName: "DOT",
name: "_R", // a dummy port name is the real port name prefixed with "_"
cursor: "pointer",
desiredSize: new go.Size(14, 28),
},
// transparent Panel for easy port selection
$(go.Shape, {
fill: "transparent",
stroke: null,
}),
// Blue dot
$(go.Shape, "Circle",
{
name: "DOT",
portId: "R",
fromLinkable: true,
toLinkable: true,
cursor: "pointer",
desiredSize: new go.Size(7, 7),
stroke: null,
alignment: go.Spot.Right,
opacity: 1
}
)
)
);
myDiagram.model = new go.GraphLinksModel(
{
// linkFromPortIdProperty: "fp",
// linkToPortIdProperty: "tp",
nodeDataArray:
[
{ key: 1, text: "Alpha", color: "lightblue" },
{ key: 2, text: "Beta", color: "orange" },
{ key: 3, text: "Gamma", color: "lightgreen" },
{ key: 4, text: "Delta", color: "pink" }
]
});
</script>
</body>
</html>