Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Use when positioning shapes, routing edges, or placing labels in Draw.io diagrams. Prevents the #1 layout mistake: using absolute coordinates inside containers instead of relative coordinates. Covers the coordinate system, vertex and edge geometry, waypoints, container-relative positioning, and connection points. Keywords: drawio geometry, mxGeometry, coordinates, position, waypoints, connection points, exitX, entryX, shapes overlap, wrong position, edge routing, move shapes, align elements.
license
MIT
compatibility
Designed for Claude Code. Requires Draw.io / diagrams.net (current).
metadata
{"author":"OpenAEC-Foundation","version":"1.0"}
Draw.io Core Geometry
Purpose
This skill defines how to position shapes, route edges, and place labels in Draw.io mxGraph XML. Every visual element requires an <mxGeometry> child element. Getting geometry wrong causes shapes to overlap, edges to misroute, and labels to disappear.
Coordinate System
Draw.io uses a screen coordinate system:
Origin: Top-left corner of the canvas is (0, 0)
X-axis: Positive values go right
Y-axis: Positive values go down
Units: All values are in pixels
(0,0) ────────────► +X (right)
│
│
│
▼
+Y (down)
Vertex Geometry
Every vertex (shape) MUST have an <mxGeometry> with x, y, width, and height:
When a cell is a child of a container (group or swimlane), its geometry coordinates are relative to the parent's top-left corner, NOT the canvas origin.
<!-- Container at canvas position (100, 100) --><mxCellid="10"value="Server Group"style="group"vertex="1"parent="1"><mxGeometryx="100"y="100"width="300"height="200"as="geometry" /></mxCell><!-- Child at (20, 20) RELATIVE to parent = canvas position (120, 120) --><mxCellid="11"value="Web Server"style="rounded=1;"vertex="1"parent="10"><mxGeometryx="20"y="20"width="120"height="60"as="geometry" /></mxCell>
Rules:
NEVER use absolute canvas coordinates for children inside containers. The child's x and y are ALWAYS relative to the parent's top-left corner.
A child at x="0" y="0" sits at the parent's top-left corner.
Children CAN extend beyond the parent's bounds (they will be visually clipped in some styles but still exist).
Decision Tree: Absolute vs. Relative Coordinates
Is the cell a child of a container (parent != "1")?
├── YES → Use coordinates RELATIVE to parent's top-left
│ x=20, y=30 means 20px right and 30px down from parent origin
└── NO → Use ABSOLUTE canvas coordinates
x=200, y=150 means 200px right and 150px down from canvas origin
Collapsible Containers (alternateBounds)
Containers with collapsed="1" use alternateBounds to define their collapsed size:
Connection points control WHERE edges attach to shapes. They are style properties on the edge, using 0.0-1.0 relative coordinates on the source/target shape.
Label positioning on vertices uses style properties:
Property
Values
Default
Purpose
labelPosition
left, center, right
center
Horizontal label position relative to shape
verticalLabelPosition
top, middle, bottom
middle
Vertical label position relative to shape
align
left, center, right
center
Text alignment within label bounds
verticalAlign
top, middle, bottom
middle
Vertical text alignment within label bounds
Critical rule: When labelPosition is NOT center, align MUST be the opposite direction:
labelPosition=left;align=right; → Label left of shape
labelPosition=right;align=left; → Label right of shape
verticalLabelPosition=top;verticalAlign=bottom; → Label above shape
verticalLabelPosition=bottom;verticalAlign=top; → Label below shape
Decision Tree: Label Position vs. Alignment
Is labelPosition set to something other than "center"?
├── YES → Set align to the OPPOSITE value
│ labelPosition=left → align=right
│ labelPosition=right → align=left
└── NO → align controls text alignment within the shape (default: center)
Is verticalLabelPosition set to something other than "middle"?
├── YES → Set verticalAlign to the OPPOSITE value
│ verticalLabelPosition=top → verticalAlign=bottom
│ verticalLabelPosition=bottom → verticalAlign=top
└── NO → verticalAlign controls text alignment within the shape (default: middle)
Perimeter Matching
Non-rectangular shapes NEED a matching perimeter style value for correct edge connection:
Shape
Required Perimeter
shape=ellipse
perimeter=ellipsePerimeter
shape=rhombus
perimeter=rhombusPerimeter
shape=triangle
perimeter=trianglePerimeter
shape=hexagon
perimeter=hexagonPerimeter2
shape=parallelogram
perimeter=parallelogramPerimeter
shape=trapezoid
perimeter=trapezoidPerimeter
Rectangles and rounded rectangles use the default perimeter and need NO explicit value.
References
methods.md - Complete attribute and property reference
examples.md - Working XML examples for all geometry scenarios