SuperAPI AI Directory

drawio-core-geometry

General & other

View repository

Updated 10-15 22:17

About this skill

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:

<mxCell id="2" value="Process" style="rounded=1;whiteSpace=wrap;html=1;"
        vertex="1" parent="1">
  <mxGeometry x="200" y="150" width="120" height="60" as="geometry" />
</mxCell>
Attribute Meaning Required
x Horizontal position of top-left corner YES
y Vertical position of top-left corner YES
width Shape width in pixels YES
height Shape height in pixels YES
as ALWAYS set to "geometry" YES

Rules:

  • ALWAYS specify width and height. Draw.io has NO implicit sizing — omitting dimensions produces a 0x0 invisible shape.
  • ALWAYS set as="geometry" on the <mxGeometry> element.
  • x and y default to 0 if omitted, placing the shape at the canvas origin.

Edge Geometry

Edges MUST use relative="1" on their geometry. The x and y attributes on edge geometry control label placement, NOT the edge path:

<mxCell id="4" value="Yes" style="edgeStyle=orthogonalEdgeStyle;"
        edge="1" source="2" target="3" parent="1">
  <mxGeometry relative="1" as="geometry" />
</mxCell>

Rules:

  • ALWAYS set relative="1" on edge geometry. Without it, the edge rendering breaks.
  • NEVER set width or height on edge geometry.

Edge Label Positioning

When relative="1", the x and y on <mxGeometry> position the edge label:

Attribute Range Meaning
x -1 to 1 Position along the edge path: -1 = source end, 0 = midpoint, 1 = target end
y Any pixel value Perpendicular offset from the edge path. Positive = below/right. Negative = above/left
<!-- Label at midpoint, offset 15px perpendicular -->
<mxGeometry x="0" y="15" relative="1" as="geometry" />

Fine-Tuning with offset

Add an <mxPoint as="offset"> inside <mxGeometry> for pixel-level label adjustment:

<mxGeometry x="0.5" y="0" relative="1" as="geometry">
  <mxPoint x="10" y="-5" as="offset" />
</mxGeometry>

Unconnected Edge Endpoints

When an edge has no source or target attribute, use sourcePoint and targetPoint:

<mxCell id="5" edge="1" parent="1" style="edgeStyle=orthogonalEdgeStyle;">
  <mxGeometry relative="1" as="geometry">
    <mxPoint x="100" y="200" as="sourcePoint" />
    <mxPoint x="400" y="350" as="targetPoint" />
  </mxGeometry>
</mxCell>

These are absolute canvas coordinates.

Waypoints

Edges route through intermediate points using an <Array as="points"> inside <mxGeometry>:

<mxCell id="4" edge="1" source="2" target="3" parent="1"
        style="edgeStyle=orthogonalEdgeStyle;">
  <mxGeometry relative="1" as="geometry">
    <Array as="points">
      <mxPoint x="300" y="150" />
      <mxPoint x="300" y="250" />
    </Array>
  </mxGeometry>
</mxCell>

Rules:

  • Waypoint coordinates are ALWAYS absolute canvas coordinates.
  • The <Array> MUST have as="points".
  • Each <mxPoint> defines one intermediate routing anchor.
  • Order matters: edge routes source -> point1 -> point2 -> ... -> target.

Waypoint Behavior by Edge Style

Edge Style Waypoint Effect
orthogonalEdgeStyle Right-angle segments through each waypoint
elbowEdgeStyle First waypoint determines elbow bend location
curved=1 Waypoints become Bezier control points
No edgeStyle (straight) Direct line segments through each waypoint

Container-Relative Coordinates

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) -->
<mxCell id="10" value="Server Group" style="group" vertex="1" parent="1">
  <mxGeometry x="100" y="100" width="300" height="200" as="geometry" />
</mxCell>
<!-- Child at (20, 20) RELATIVE to parent = canvas position (120, 120) -->
<mxCell id="11" value="Web Server" style="rounded=1;" vertex="1" parent="10">
  <mxGeometry x="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:

<mxCell id="10" value="Server Group" style="swimlane;" vertex="1"
        collapsed="1" parent="1">
  <mxGeometry x="100" y="100" width="300" height="200" as="geometry">
    <mxRectangle x="100" y="100" width="160" height="30" as="alternateBounds" />
  </mxGeometry>
</mxCell>
  • Expanded: renders at 300x200
  • Collapsed: renders at 160x30

Connection Points (Style Properties)

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.

Reference Grid

(0,0)──────(0.5,0)──────(1,0)
  │                        │
(0,0.5)   (0.5,0.5)   (1,0.5)
  │                        │
(0,1)──────(0.5,1)──────(1,1)

Connection Point Style Properties

Property Range Meaning
exitX 0.0 - 1.0 Relative X where edge leaves the source shape
exitY 0.0 - 1.0 Relative Y where edge leaves the source shape
entryX 0.0 - 1.0 Relative X where edge enters the target shape
entryY 0.0 - 1.0 Relative Y where edge enters the target shape
exitDx pixel value Absolute X offset from exit point
exitDy pixel value Absolute Y offset from exit point
entryDx pixel value Absolute X offset from entry point
entryDy pixel value Absolute Y offset from entry point
exitPerimeter 0 or 1 Project exit point onto shape perimeter (default: 1)
entryPerimeter 0 or 1 Project entry point onto shape perimeter (default: 1)

Common Connection Patterns

exitX=1;exitY=0.5;entryX=0;entryY=0.5;     → Right-to-left (horizontal flow)
exitX=0.5;exitY=1;entryX=0.5;entryY=0;     → Bottom-to-top (vertical flow)
exitX=1;exitY=0;entryX=0;entryY=1;         → Diagonal: top-right to bottom-left
exitX=0.5;exitY=0.5;entryX=0.5;entryY=0.5; → Center-to-center

Vertex Label Positioning

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