I am using SwimLaneLayout in the diagram below. Each big box is a node right now. I am wondering if I could make each big box as a group to include a set of nodes (illustrated in red).
I know that the swimlanes are already groups and am wondering if nested groups are supported by SwimLaneLayout. If yes, how to do it?
My HTML + JS code is below.
<!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: 800px"
></div>
<script src="../../release/go-debug.js"></script>
<script src="../../extensions/SwimLaneLayout.js"></script>
<script>
let myDiagram;
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,
layeringOption: go.LayeredDigraphLayout.LayerLongestPathSource,
layerSpacing: 100,
columnSpacing: 50,
commitLayers: function (layerRects, offset) {
if (layerRects.length === 0) return;
var rect = layerRects[layerRects.length - 1];
var totallength = rect.right;
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);
}
group.location = new go.Point(
-10,
this.lanePositions.get(lane) * this.columnSpacing + offset.y,
);
var ph = group.findObject("PLACEHOLDER"); // won't be a go.Placeholder, but just a regular Shape
if (ph === null) ph = group;
ph.desiredSize = new go.Size(
totallength,
this.laneBreadths.get(lane) * this.columnSpacing,
);
}
},
}),
});
myDiagram.nodeTemplate = $(
go.Node,
"Position",
$(go.Shape, "RoundedRectangle", {
name: "CONTAINER",
fill: "transparent",
width: 200,
height: 150,
stroke: null,
}),
$(go.Shape, "RoundedRectangle", {
fill: "white",
position: new go.Point(0, 0),
width: 200,
height: 120,
cursor: "pointer",
}),
$(
go.TextBlock, // the text label
new go.Binding("text", "key"),
{
position: new go.Point(0, 120),
width: 200,
height: 30,
verticalAlignment: go.Spot.Center,
textAlign: "center",
},
),
);
myDiagram.linkTemplate = $(
go.Link,
{ relinkableFrom: true, relinkableTo: true },
{ 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: "B",
isGroup: true,
},
{
key: "Group1",
group: "A",
},
{
key: "Group2",
group: "A",
},
{
key: "Group6",
group: "A",
},
{
key: "Group3",
group: "B",
},
{
key: "Group4",
group: "B",
},
{
key: "Group5",
group: "B",
},
];
const linkDataArray = [
{
from: "Group1",
to: "Group2",
},
{
from: "Group2",
to: "Group6",
},
{
from: "Group3",
to: "Group4",
},
{
from: "Group3",
to: "Group5",
},
];
const model = new go.GraphLinksModel();
model.nodeGroupKey = "group";
model.nodeDataArray = nodeDataArray;
model.linkDataArray = linkDataArray;
myDiagram.layout.laneProperty = model.nodeGroupKey;
myDiagram.layout.laneNames = ["A", "B"];
myDiagram.model = model;
}
window.addEventListener("DOMContentLoaded", init);
</script>
</body>
</html>