The following code shows two nodes Alpha and Beta. Since the node itself is fromLinkable and toLinkable, when I dragged from the non-text area in Alpha and dropped to Beta, a link was created from Alpha to Beta (since they were not linked by default). Once the link has been created, when I dragged from the non-text area in Alpha again, I was no longer able to drop to Beta, which means that I could only create a single link from Alpha to Beta, which is good.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<!-- <div
id="myDiagramDiv"
style="border: solid 1px black; width: 100%; height: 700px"
></div> -->
<div style="width: 100%; display: flex; justify-content: space-between">
<div
id="myPaletteDiv"
style="
width: 105px;
margin-right: 2px;
background-color: whitesmoke;
border: solid 1px black;
"
></div>
<div
id="myDiagramDiv"
style="flex-grow: 1; height: 620px; border: solid 1px black"
></div>
</div>
<script src="../../release/go-debug.js"></script>
<script>
const $ = go.GraphObject.make;
const init = () => {
const myDiagram = $(go.Diagram, "myDiagramDiv", {
"draggingTool.dragsLink": true,
layout: $(go.LayeredDigraphLayout, {
layeringOption: go.LayeredDigraphLayout.LayerLongestPathSource,
}),
});
myDiagram.nodeTemplate = $(
go.Node,
"Spot",
{
locationSpot: go.Spot.Center,
},
$(go.Shape, "RoundedRectangle", {
fill: "white",
width: 100,
height: 50,
portId: "",
fromLinkable: true,
toLinkable: true,
cursor: "pointer",
}),
$(
go.TextBlock, // the text label
new go.Binding("text", "key"),
{
verticalAlignment: go.Spot.Center,
textAlign: "center",
},
),
);
myDiagram.linkTemplate = $(
go.Link, // the whole link panel
{ routing: go.Link.AvoidsNodes, corner: 10 },
$(
go.Shape, // the link shape
{ strokeWidth: 1.5 },
),
$(
go.Shape, // the arrowhead
{ toArrow: "Standard", stroke: null },
),
);
const nodeDataArray = [
{
key: "Alpha",
},
{
key: "Beta",
},
];
const linkDataArray = [];
const model = new go.GraphLinksModel();
model.nodeDataArray = nodeDataArray;
model.linkDataArray = linkDataArray;
myDiagram.model = model;
};
window.addEventListener("DOMContentLoaded", init);
</script>
</body>
</html>
However, once I added ports to the node (I was using the standard makePort method from many of the GoJS sample examples) and made the node’s fromLinkable and toLinkable to be false, I can add many links by keeping dragging from the right port in Alpha and dropping to the left port in Beta. When I dragged Alpha away, the following screenshot illustrates that there are many links between the two nodes, which is NOT what I want.
My question is why adding ports causes multiple links can be added between them? I believe that LinkableDuplicates is false by default. The code with the makePort method is posted below. Thanks so much for your time!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<!-- <div
id="myDiagramDiv"
style="border: solid 1px black; width: 100%; height: 700px"
></div> -->
<div style="width: 100%; display: flex; justify-content: space-between">
<div
id="myPaletteDiv"
style="
width: 105px;
margin-right: 2px;
background-color: whitesmoke;
border: solid 1px black;
"
></div>
<div
id="myDiagramDiv"
style="flex-grow: 1; height: 620px; border: solid 1px black"
></div>
</div>
<script src="../../release/go-debug.js"></script>
<script>
const $ = go.GraphObject.make;
const init = () => {
const myDiagram = $(go.Diagram, "myDiagramDiv", {
"draggingTool.dragsLink": true,
layout: $(go.LayeredDigraphLayout, {
layeringOption: go.LayeredDigraphLayout.LayerLongestPathSource,
}),
});
const makePort = (name, spot, output, input) => {
return $(go.Shape, "Rectangle", {
fill: "rgba(0, 0, 0, 0.3)",
stroke: null,
desiredSize: new go.Size(8, 8),
alignment: spot,
alignmentFocus: spot,
portId: name,
fromSpot: spot,
toSpot: spot,
fromLinkable: output,
toLinkable: input,
cursor: "pointer",
});
};
myDiagram.nodeTemplate = $(
go.Node,
"Spot",
{
locationSpot: go.Spot.Center,
},
$(go.Shape, "RoundedRectangle", {
fill: "white",
width: 100,
height: 50,
// portId: "",
// fromLinkable: true,
// toLinkable: true,
cursor: "pointer",
}),
$(
go.TextBlock, // the text label
new go.Binding("text", "key"),
{
verticalAlignment: go.Spot.Center,
textAlign: "center",
},
),
makePort("Left", go.Spot.Left, false, true),
makePort("Right", go.Spot.Right, true, false),
);
myDiagram.linkTemplate = $(
go.Link, // the whole link panel
{ routing: go.Link.AvoidsNodes, corner: 10 },
$(
go.Shape, // the link shape
{ strokeWidth: 1.5 },
),
$(
go.Shape, // the arrowhead
{ toArrow: "Standard", stroke: null },
),
);
const nodeDataArray = [
{
key: "Alpha",
},
{
key: "Beta",
},
];
const linkDataArray = [];
const model = new go.GraphLinksModel();
model.nodeDataArray = nodeDataArray;
model.linkDataArray = linkDataArray;
myDiagram.model = model;
};
window.addEventListener("DOMContentLoaded", init);
</script>
</body>
</html>