| name | drawio-impl-swimlanes |
| description | Use when creating swimlane diagrams, cross-functional flowcharts, or pool/lane layouts in Draw.io. Prevents the #1 swimlane mistake: using absolute coordinates for children instead of container-relative coordinates. Covers horizontal and vertical swimlanes, nested lanes, header sizing, and cross-lane connections. Keywords: swimlane, pool, lane, cross-functional, container, startSize, horizontal, vertical, responsibility diagram, who does what, department process, cross-team workflow.
|
| license | MIT |
| compatibility | Designed for Claude Code. Requires Draw.io / diagrams.net (current). |
| metadata | {"author":"OpenAEC-Foundation","version":"1.0"} |
Draw.io Swimlane Implementation
Purpose
This skill enables correct generation of swimlane diagrams, cross-functional flowcharts, and pool/lane layouts in Draw.io mxGraph XML. It enforces the container-relative coordinate system and prevents the most common AI mistake: placing child shapes at absolute page coordinates instead of container-relative coordinates.
Critical Rules (Memorize These)
- ALWAYS set
container=1 in every swimlane and pool style — Without it, child shapes will NOT move with the lane when repositioned.
- ALWAYS use container-relative coordinates for children — A child at
x="40" y="35" is 40px from the lane's left edge and 35px from the lane's top edge (below the header). NEVER use absolute page coordinates.
- ALWAYS set
parent to the container ID for child shapes — A shape inside "lane1" MUST have parent="lane1". NEVER set parent="1" for shapes that belong inside a container.
- ALWAYS set cross-lane edge
parent to the common ancestor — When an edge connects shapes in different lanes, set the edge's parent to the pool (the shared ancestor). NEVER set it to one of the individual lanes.
- ALWAYS include
collapsible=0 on lanes — Without it, users can accidentally collapse lanes in the editor, hiding all contents.
- NEVER use absolute page coordinates for shapes inside a container — This is the #1 swimlane mistake. Shapes will render at the wrong position and will NOT move with their parent lane.
Container Hierarchy
Swimlane diagrams use a strict parent-child hierarchy:
Root (id="1")
Pool (container=1, parent="1") <-- absolute coordinates
Lane A (container=1, parent="pool") <-- relative to pool
Shape 1 (parent="lane_a") <-- relative to Lane A
Shape 2 (parent="lane_a") <-- relative to Lane A
Lane B (container=1, parent="pool") <-- relative to pool
Shape 3 (parent="lane_b") <-- relative to Lane B
Edge (parent="pool", source/target) <-- cross-lane edges on pool
Pool Style
The pool is the outermost container that holds all lanes. Use shape=table for structured pool layouts:
shape=table;startSize=30;container=1;collapsible=0;childLayout=tableLayout;fixedRows=1;rowLines=0;fontStyle=1;strokeColor=#6c8ebf;fillColor=#dae8fc;
| Property | Value | Purpose |
|---|
shape=table | Required | Renders as a structured table container |
startSize | 30 | Height of the pool header band (px) |
container | 1 | REQUIRED — enables parent-child relationship |
collapsible | 0 | Prevents accidental collapse |
childLayout | tableLayout | Arranges child lanes as table rows |
fixedRows | 1 | Locks lane row structure |
rowLines | 0 | Hides row separator lines |
fontStyle | 1 | Bold header text |
Alternative: use swimlane;startSize=30;container=1;collapsible=0; for a simpler pool without table layout.
Lane Style
Each lane is a child container inside the pool:
swimlane;startSize=30;container=1;collapsible=0;horizontal=1;fillColor=#f5f5f5;strokeColor=#666666;fontStyle=1;
| Property | Value | Purpose |
|---|
swimlane | Required | Renders as a swimlane shape |
startSize | 30 | Height of the lane header band (px) |
container | 1 | REQUIRED — enables parent-child relationship |
collapsible | 0 | Prevents accidental collapse |
horizontal | 1 or 0 | Orientation (see next section) |
fontStyle | 1 | Bold header text |
Horizontal vs. Vertical Orientation
| Orientation | Style | Header Position | Flow Direction |
|---|
| Horizontal lanes | swimlane;horizontal=1;startSize=30; | Left side (rotated text) | Left-to-right |
| Vertical lanes | swimlane;horizontal=0;startSize=30; | Top (horizontal text) | Top-to-bottom |
Important: The horizontal property controls the header orientation, NOT the lane stacking direction. horizontal=0 means the header text is horizontal (rendered at the top), and lanes stack side by side — this is the most common layout for cross-functional flowcharts with top-to-bottom flow.
When to Use Which
horizontal=0 (vertical lanes, top-to-bottom flow): Use for cross-functional flowcharts where the process flows downward and lanes represent departments/roles side by side. This is the DEFAULT for most business process diagrams.
horizontal=1 (horizontal lanes, left-to-right flow): Use when lanes stack vertically and the process flows left-to-right. Common for value stream maps and horizontal process flows.
Header Sizing (startSize)
The startSize property controls the header band height (for horizontal=0) or width (for horizontal=1):
| startSize | Use Case |
|---|
20 | Compact header, short labels |
30 | Default — fits single-line labels |
40 | Two-line labels or larger font |
50+ | Extended headers with descriptions |
Coordinate impact: The usable area for child shapes starts AFTER the header. For startSize=30, the first child shape's y-coordinate starts at y=0 relative to the lane (the header occupies the top 30px visually, but child y=0 is at the top-left of the content area after the header in practice). In Draw.io's XML, child y-coordinates are relative to the lane's top-left corner INCLUDING the header. Place children with y >= startSize to avoid overlap.
Lane Geometry Rules
Pool Positioning
The pool uses absolute page coordinates:
<mxCell id="pool1" value="Order Process" style="shape=table;startSize=30;container=1;..."
vertex="1" parent="1">
<mxGeometry x="40" y="40" width="700" height="400" as="geometry" />
</mxCell>
Lane Positioning
Lanes use coordinates relative to the pool. The first lane starts at y=startSize (below the pool header):
<mxCell id="lane1" value="Sales" style="swimlane;..." vertex="1" parent="pool1">
<mxGeometry y="30" width="700" height="130" as="geometry" />
</mxCell>
<mxCell id="lane2" value="Warehouse" style="swimlane;..." vertex="1" parent="pool1">
<mxGeometry y="160" width="700" height="140" as="geometry" />
</mxCell>
Width rule: ALWAYS set lane width equal to pool width. Lanes span the full width of the pool.
Height rule: The sum of all lane heights plus the pool header startSize MUST equal the pool height:
- Pool height = startSize + lane1.height + lane2.height + ...
Child Shape Positioning
Shapes inside lanes use coordinates relative to the lane's top-left corner:
<mxCell id="task1" value="Receive Order" style="rounded=1;whiteSpace=wrap;html=1;..."
vertex="1" parent="lane1">
<mxGeometry x="40" y="35" width="120" height="60" as="geometry" />
</mxCell>
Place children with y >= startSize of the lane to avoid overlapping the lane header.
Cross-Lane Connections
Edges that connect shapes in different lanes MUST use the pool as their parent:
<mxCell id="e1" style="edgeStyle=orthogonalEdgeStyle;endArrow=classic;html=1;"
edge="1" parent="pool1" source="task2" target="task3">
<mxGeometry relative="1" as="geometry" />
</mxCell>
Edges that connect shapes within the SAME lane MAY use either the lane or the pool as parent. For consistency, ALWAYS use the pool as edge parent.
Nested Lanes
Lanes can contain sub-lanes for finer granularity:
<mxCell id="lane1" value="Engineering" style="swimlane;startSize=30;container=1;..."
vertex="1" parent="pool1">
<mxGeometry y="30" width="700" height="200" as="geometry" />
</mxCell>
<mxCell id="sublane1a" value="Frontend" style="swimlane;startSize=25;container=1;..."
vertex="1" parent="lane1">
<mxGeometry y="30" width="700" height="85" as="geometry" />
</mxCell>
<mxCell id="sublane1b" value="Backend" style="swimlane;startSize=25;container=1;..."
vertex="1" parent="lane1">
<mxGeometry y="115" width="700" height="85" as="geometry" />
</mxCell>
Rule: Sub-lane coordinates are relative to the parent lane. Sub-lane widths MUST equal the parent lane width.
Auto-Expand Behavior
When container=1 is set, Draw.io auto-expands the container if a child shape extends beyond its boundaries. To prevent unwanted expansion:
- ALWAYS size the pool and lanes large enough to contain all children.
- Add
resizable=1 to allow manual resizing in the editor.
- Add
recursiveResize=0 on the pool to prevent child lanes from auto-resizing when the pool resizes.
Complete Example: 3-Lane Order Processing
<mxGraphModel>
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="pool1" value="Order Processing" style="shape=table;startSize=30;container=1;collapsible=0;childLayout=tableLayout;fixedRows=1;rowLines=0;fontStyle=1;strokeColor=#6c8ebf;fillColor=#dae8fc;" vertex="1" parent="1">
<mxGeometry x="40" y="40" width="700" height="430" as="geometry" />
</mxCell>
<mxCell id="lane_sales" value="Sales" style="swimlane;startSize=30;container=1;collapsible=0;horizontal=1;fillColor=#f5f5f5;strokeColor=#666666;fontStyle=1;" vertex="1" parent="pool1">
<mxGeometry y="30" width="700" height="130" as="geometry" />
</mxCell>
<mxCell id="t1" value="Receive<br>Order" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="lane_sales">
<mxGeometry x="40" y="35" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="t2" value="Validate<br>Order" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="lane_sales">
<mxGeometry x="220" y="35" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="d1" value="Valid?" style="rhombus;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="lane_sales">
<mxGeometry x="400" y="25" width="100" height="80" as="geometry" />
</mxCell>
<mxCell id="lane_warehouse" value="Warehouse" style="swimlane;startSize=30;container=1;collapsible=0;horizontal=1;fillColor=#f5f5f5;strokeColor=#666666;fontStyle=1;" vertex="1" parent="pool1">
<mxGeometry y="160" width="700" height="130" as="geometry" />
</mxCell>
<mxCell id="t3" value="Pick<br>Items" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="lane_warehouse">
<mxGeometry x="220" y="35" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="t4" value="Pack<br>Shipment" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="lane_warehouse">
<mxGeometry x="400" y="35" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="lane_finance" value="Finance" style="swimlane;startSize=30;container=1;collapsible=0;horizontal=1;fillColor=#f5f5f5;strokeColor=#666666;fontStyle=1;" vertex="1" parent="pool1">
<mxGeometry y="290" width="700" height="140" as="geometry" />
</mxCell>
<mxCell id="t5" value="Generate<br>Invoice" style="shape=document;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;" vertex="1" parent="lane_finance">
<mxGeometry x="400" y="35" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="t6" value="Process<br>Payment" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="lane_finance">
<mxGeometry x="560" y="35" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="t_reject" value="Reject<br>Order" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;" vertex="1" parent="lane_sales">
<mxGeometry x="560" y="35" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="e1" style="edgeStyle=orthogonalEdgeStyle;endArrow=classic;html=1;" edge="1" parent="pool1" source="t1" target="t2">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e2" style="edgeStyle=orthogonalEdgeStyle;endArrow=classic;html=1;" edge="1" parent="pool1" source="t2" target="d1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e3" value="Yes" style="edgeStyle=orthogonalEdgeStyle;endArrow=classic;html=1;" edge="1" parent="pool1" source="d1" target="t3">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e4" value="No" style="edgeStyle=orthogonalEdgeStyle;endArrow=classic;html=1;" edge="1" parent="pool1" source="d1" target="t_reject">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e5" style="edgeStyle=orthogonalEdgeStyle;endArrow=classic;html=1;" edge="1" parent="pool1" source="t3" target="t4">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e6" style="edgeStyle=orthogonalEdgeStyle;endArrow=classic;html=1;" edge="1" parent="pool1" source="t4" target="t5">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="e7" style="edgeStyle=orthogonalEdgeStyle;endArrow=classic;html=1;" edge="1" parent="pool1" source="t5" target="t6">
<mxGeometry relative="1" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
This example demonstrates:
- 3 lanes (Sales, Warehouse, Finance) inside one pool
- 7 shapes across 3 lanes with container-relative coordinates
- Cross-lane connections with
parent="pool1"
- Decision diamond with labeled Yes/No branches
- Document shape for invoice generation
- Consistent left-to-right flow within horizontal lanes
Checklist: Before Outputting a Swimlane Diagram
- Every pool and lane has
container=1 in its style.
- Every lane has
collapsible=0 in its style.
- Every child shape has
parent set to its containing lane ID.
- Every child shape uses coordinates relative to its lane (NOT absolute page coordinates).
- Every cross-lane edge has
parent set to the pool (common ancestor).
- Lane widths equal the pool width.
- Pool height = startSize + sum of all lane heights.
- Child shapes have
y >= startSize of their lane to avoid header overlap.
- Both structural cells (
id="0" and id="1") are present.
- All cell IDs are unique.
- All edges have valid
source and target attributes.
Cross-References
- XML fundamentals: See
drawio-core-xml-format for file structure and structural cells.
- Style syntax: See
drawio-syntax-styles for the complete style property reference.
- Connection details: See
drawio-syntax-connections for edge routing and waypoints.
- Geometry: See
drawio-core-geometry for coordinate system and positioning.
- Flowchart shapes: See
drawio-impl-flowcharts for ISO 5807 shapes used inside lanes.
Reference Links