Hi,
I am using the SwimLaneLayout and adopt its sample code.
I noticed that the node order affects the link routing. For example, the following nodeDataArray causes the links between the 2nd level and the 3rd level intertwined
[
{
key: "A",
isGroup: true,
},
{
key: "Box1",
group: "A",
},
{
key: "Box2",
group: "A",
},
{
key: "Box3",
group: "A",
},
{
key: "Box4",
group: "A",
},
{
key: "Box5",
group: "A",
},
{
key: "Box6",
group: "A",
},
];
But if I move Box6 before Box3, the layout becomes much clear.
[
{
key: "A",
isGroup: true,
},
{
key: "Box1",
group: "A",
},
{
key: "Box2",
group: "A",
},
{
key: "Box6",
group: "A",
},
{
key: "Box3",
group: "A",
},
{
key: "Box4",
group: "A",
},
{
key: "Box5",
group: "A",
},
];
However, such node ordering issue does not exist with standard LayeredDigraphLayout. Is it a bug in SwimLaneLayout or is there some configuration that I can apply so that the link routing is not affected by the node order.
My complete HTML page including the JS code is 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>
<script src="../../release/go-debug.js"></script>
<script src="../../extensions/SwimLaneLayout.js"></script>
<script>
function init() {
const $ = go.GraphObject.make;
myDiagram = $(go.Diagram, "myDiagramDiv", {
layout: $(SwimLaneLayout, {
laneProperty: "group", // needs to know how to assign vertexes/nodes into lanes/groups
setsPortSpots: false,
layerSpacing: 20,
columnSpacing: 5,
commitLayers: function (layerRects, offset) {
if (layerRects.length === 0) return;
var horiz = true;
var forwards = true;
var rect = layerRects[forwards ? layerRects.length - 1 : 0];
var totallength = horiz ? rect.right : rect.bottom;
for (var i = 0; i < this.laneNames.length; i++) {
var lane = this.laneNames[i];
// assume lane names do not conflict with node names
var group = this.diagram.findNodeForKey(lane);
if (group === null) {
this.diagram.model.addNodeData({ key: lane, isGroup: true });
group = this.diagram.findNodeForKey(lane);
}
if (horiz) {
group.location = new go.Point(
-this.layerSpacing / 2,
this.lanePositions.get(lane) * this.columnSpacing +
offset.y,
);
} else {
group.location = new go.Point(
this.lanePositions.get(lane) * this.columnSpacing +
offset.x,
-this.layerSpacing / 2,
);
}
var ph = group.findObject("PLACEHOLDER"); // won't be a go.Placeholder, but just a regular Shape
if (ph === null) ph = group;
if (horiz) {
ph.desiredSize = new go.Size(
totallength,
this.laneBreadths.get(lane) * this.columnSpacing,
);
} else {
ph.desiredSize = new go.Size(
this.laneBreadths.get(lane) * this.columnSpacing,
totallength,
);
}
}
},
}),
});
myDiagram.nodeTemplate = $(
go.Node,
"Spot",
new go.Binding("location", "loc", go.Point.parse),
$(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,
{ routing: go.Link.AvoidsNodes, corner: 10 },
$(go.Shape, { strokeWidth: 1.5 }),
$(go.Shape, { toArrow: "Standard", stroke: null }),
);
myDiagram.groupTemplate = $(
go.Group,
"Horizontal",
{
layerName: "Background",
movable: false,
copyable: false,
locationObjectName: "PLACEHOLDER",
layout: null,
avoidable: false,
},
$(
go.TextBlock,
{
font: "bold 12pt sans-serif",
angle: 270,
},
new go.Binding("text", "key"),
),
$(
go.Panel,
"Auto",
$(go.Shape, { fill: "transparent", stroke: "orange" }),
$(go.Shape, {
name: "PLACEHOLDER",
fill: null,
stroke: null,
strokeWidth: 0,
}),
),
);
const nodeDataArray = [
{
key: "A",
isGroup: true,
},
{
key: "Box1",
group: "A",
},
{
key: "Box2",
group: "A",
},
{
key: "Box6",
group: "A",
},
{
key: "Box3",
group: "A",
},
{
key: "Box4",
group: "A",
},
{
key: "Box5",
group: "A",
},
];
const linkDataArray = [
{
from: "Box1",
to: "Box2",
},
{
from: "Box1",
to: "Box3",
},
{
from: "Box2",
to: "Box6",
},
{
from: "Box3",
to: "Box4",
},
{
from: "Box3",
to: "Box5",
},
];
const model = new go.GraphLinksModel();
model.nodeGroupKey = "group";
model.nodeDataArray = nodeDataArray;
model.linkDataArray = linkDataArray;
myDiagram.layout.laneProperty = model.nodeGroupKey;
myDiagram.layout.laneNames = ["A"];
myDiagram.model = model;
}
window.addEventListener("DOMContentLoaded", init);
</script>
</body>
</html>