In below code, when diagram is loaded nodes are placed on random position. Now when nodes are repositioned far away from each other , their link gets truncated. Reposition nodes to close one can see the link touching both nodes.
This is caused by the memberAdded function ( commenting code in memberAdded function reposition of node works properly.)
Also selecting link , shows it is touched to both end nodes.
<!DOCTYPE html>
<html lang="en">
<body>
<script src="https://unpkg.com/gojs@2.2.2/release/go.js"></script>
<div id="allSampleContent" class="p-4 w-full">
<script id="code">
function init() {
myDiagram = new go.Diagram("myDiagramDiv",
{
mouseDrop: e => finishDrop(e, null),
"commandHandler.archetypeGroupData": { isGroup: true, text: "Group", horiz: false },
"undoManager.isEnabled": true
});
// The one template for Groups can be configured to be either layout out its members
// horizontally or vertically, each with a different default color.
function makeLayout(horiz) { // a Binding conversion function
if (horiz) {
return new go.GridLayout(
{
wrappingWidth: Infinity, alignment: go.GridLayout.Position,
cellSize: new go.Size(1, 1), spacing: new go.Size(1, 1)
});
} else {
return new go.GridLayout(
{
wrappingColumn: 1, alignment: go.GridLayout.Position,
cellSize: new go.Size(1, 1), spacing: new go.Size(5, 5)
});
}
}
function memberAdded(group,node) {
if (group.placeholder != null)
node.width = group.placeholder.actualBounds.width - 10;
}
function defaultColor(horiz) { // a Binding conversion function
return horiz ? "rgba(255, 255, 255, 0.55)" : "rgba(255,255,255, 0.5)";
}
function defaultFont(horiz) { // a Binding conversion function
return horiz ? "bold 20px sans-serif" : "bold 16px sans-serif";
}
// this function is used to highlight a Group that the selection may be dropped into
function highlightGroup(e, grp, show) {
if (!grp) return;
e.handled = true;
if (show) {
// cannot depend on the grp.diagram.selection in the case of external drag-and-drops;
// instead depend on the DraggingTool.draggedParts or .copiedParts
var tool = grp.diagram.toolManager.draggingTool;
var map = tool.draggedParts || tool.copiedParts; // this is a Map
// now we can check to see if the Group will accept membership of the dragged Parts
if (grp.canAddMembers(map.toKeySet())) {
grp.isHighlighted = true;
return;
}
}
grp.isHighlighted = false;
}
// Upon a drop onto a Group, we try to add the selection as members of the Group.
// Upon a drop onto the background, or onto a top-level Node, make selection top-level.
// If this is OK, we're done; otherwise we cancel the operation to rollback everything.
function finishDrop(e, grp) {
var ok = (grp !== null
? grp.addMembers(grp.diagram.selection, true)
: e.diagram.commandHandler.addTopLevelParts(e.diagram.selection, true));
if (!ok) e.diagram.currentTool.doCancel();
}
myDiagram.groupTemplate = new go.Group("Auto",
{
background: "blue", stretch: go.GraphObject.Horizontal, width:300,
ungroupable: true, resizable:true,
// highlight when dragging into the Group
computesBoundsAfterDrag: false,
// when the selection is dropped into a Group, add the selected Parts into that Group;
// if it fails, cancel the tool, rolling back any changes
mouseDrop: this.finishDrop,
handlesDragDropForMembers: true, // don't need to define handlers on member Nodes and Links
// Groups containing Groups lay out their members horizontally
layout: makeLayout(false),
memberAdded : memberAdded
})
.bind("layout", "horiz", makeLayout)
.bind(new go.Binding("background", "isHighlighted", h => h ? "rgba(255,0,0,0.2)" : "transparent").ofObject())
.add(new go.Shape("Rectangle",
{ stroke: "black", fill: "green", strokeWidth: 2 })
.bind("stroke", "horiz", defaultColor)
.bind("fill", "horiz", defaultColor))
.add(
new go.Panel("Vertical", { alignment:go.Spot.Top, alignmentFocus:go.Spot.Top, stretch: go.GraphObject.Horizontal, background:"blue" }) // title above Placeholder
.add(new go.Panel("Horizontal", // button next to TextBlock
{ alignment: go.Spot.Left, stretch: go.GraphObject.Horizontal, background: "orange" })
.bind("background", "horiz", this.defaultColor)
.add(go.GraphObject.make("SubGraphExpanderButton", { alignment: go.Spot.Right, margin: 5 }))
.add(new go.TextBlock(
{
alignment: go.Spot.Left,
editable: true,
margin: 10,
font: defaultFont(false),
opacity: 0.95, // allow some color to show through
stroke: "#404040"
})
.bind("font", "horiz", this.defaultFont)
.bind("text", "text", null, null)) // `null` as the fourth argument makes this a two-way binding
) // end Horizontal Panel
.add(new go.Placeholder({ padding: new go.Margin(5,5,5,5), background:"red", alignment: go.Spot.BottomLeft, stretch: go.GraphObject.Fill }))
);
myDiagram.nodeTemplate =
new go.Node("Auto", { stretch: go.GraphObject.Fill, resizable:true, fromSpot: go.Spot.LeftRightSides,
toSpot: go.Spot.LeftRightSides })
.add(new go.Shape("Rectangle", { fill: "white", stroke: "black", strokeWidth: 1}))
.add(new go.TextBlock(
{
margin:new go.Margin(10,12,10,12), alignment:go.Spot.Left,
editable: true,
font: "bold 13px Segoe UI",
})
.bind("text", "text", null, null)
); // `null` as the fourth argument makes this a two-way binding
// define the Link template, representing a relationship
myDiagram.linkTemplate =
new go.Link( // the whole link panel
{
selectionAdorned: true,
layerName: "Foreground",
reshapable: true,
routing: go.Link.AvoidsNodes,
corner: 5,
curve: go.Link.JumpOver
})
.add(new go.Shape( // the link shape
{ stroke: "#303B45", strokeWidth: 2.5 }))
.add(new go.TextBlock(
{
textAlign: "center",
font: "12px Segoe UI",
stroke: "#1967B3",
segmentIndex: 0,
segmentOffset: new go.Point(NaN, NaN),
segmentOrientation: go.Link.OrientUpright
})
.bind(new go.Binding("text", "text")))
.add(new go.TextBlock(
{
textAlign: "center",
font: "12px Segoe UI",
stroke: "#1967B3",
segmentIndex: -1,
segmentOffset: new go.Point(NaN, NaN),
segmentOrientation: go.Link.OrientUpright
})
.bind(new go.Binding("text", "toText")));
load();
}
function load() {
myDiagram.model = new go.Model.fromJson(document.getElementById("mySavedModel").value);
}
window.addEventListener('DOMContentLoaded', init);
</script>
<div id="sample">
<div style="width: 100%; display: flex; justify-content: space-between">
<div id="myDiagramDiv" style="flex-grow: 1; height: 500px; background-color: rgb(39, 29, 29); border: 1px solid black; position: relative; -webkit-tap-highlight-color: rgba(255, 255, 255, 0); font: bold 13px sans-serif; cursor: auto;"><canvas tabindex="0" width="1247" height="684" style="position: absolute; top: 0px; left: 0px; z-index: 2; user-select: none; touch-action: none; width: 907px; height: 498px; cursor: auto;">This text is displayed if your browser does not support the Canvas HTML element.</canvas><div style="position: absolute; overflow: auto; width: 922px; height: 498px; z-index: 1;"><div style="position: absolute; width: 1px; height: 523.427px;"></div></div></div>
</div>
<textarea id="mySavedModel" style="width:100%;height:300px">{ "class": "go.GraphLinksModel",
"nodeDataArray": [
{ "key": "Group1", "text":"Group1", "isGroup": "true", "pos": "0 0", "size": "200 200" },
{ "key": "Group2", "text":"Group2", "isGroup": "true", "pos": "200 0", "size": "200 200" },
{ "key": "Item1", "text": "Item1", "group":"Group1" },
{ "key": "Item2", "text": "Item2", "group":"Group1"},
{ "key": "Item3", "text": "Item3", "group":"Group2"},
{ "key": "Item4", "text": "Item4", "group":"Group2"}
],
"linkDataArray": [
{ "from": "Item1", "to": "Group2", "text": "fromText", "toText": "toText" }
]}
</textarea>
</pre></div>
</body>
</html>