drawio-position-adjuster — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited drawio-position-adjuster (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
This document explains how to adjust element positions in draw.io XML files to ensure reasonable element layout during visualization and avoid interference.
Important Note: This skill only adjusts element positions (mxGeometry); it does not modify element content, styles, or connection relationships.When adjusting element positions, the following principles must be followed:
Choose appropriate layout style based on chart type:
| Chart Type | Layout Style | Recommended Direction |
|---|---|---|
| Flowchart | Hierarchical Layout | Top-down |
| Organization Chart | Tree Layout | Top-down |
| Class Diagram | Grid Layout | Top-down or left-to-right |
| State Diagram | Circular Layout | Circular direction |
| Sequence Diagram | Horizontal Layout | Left-to-right |
| Architecture Diagram | Layered Layout | Top-down |
To eliminate the "Text Overflow" issue in mxCell nodes by dynamically calculating the optimal width and height based on string length, ensuring a professional and balanced visual layout.
The Agent must pre-process the value string to determine the mxGeometry attributes:
$$Width = \max(BaseWidth, \min(MaxWidth, \text{CharCount} \times \text{FontSize} \times \text{Ratio}))$$
$$LineCount = \lceil (\text{CharCount} \times \text{FontSize} \times \text{Ratio}) / \text{Width} \rceil$$ $$Height = \max(BaseHeight, (LineCount \times \text{LineHeight}) + \text{VerticalPadding})$$
FontSize * 1.25.Every generated mxCell style MUST include these four key-value pairs to ensure rendering consistency:
| Attribute | Value | Purpose |
|---|---|---|
html | 1 | Enables HTML rendering for smart text wrapping. |
whiteSpace | wrap | CRITICAL: Forces text to wrap within the defined width. |
overflow | hidden | Prevents minor rendering artifacts from showing outside the box. |
spacing | 5 | Adds internal padding to prevent text from touching borders. |
fontFamily=JetBrains Mono, monospace;. This makes character width prediction nearly 100% accurate.LineCount > 4, the Agent should prioritize increasing the Width rather than the Height to maintain an aesthetic rectangular proportion.& → &< → <> → >verticalAlign=middle;align=center; to keep text perfectly centered as the box expands.Input Content: "Vision-Language-Action (VLA) Model Optimization and Data Governance Strategies"
❌ Unoptimized (Using Default Fixed Size):
width="100" height="40"style="rounded=1;"✅ Optimized (Applying Dynamic Size Calculation from Section 2.2):
width="220" height="80" based on text length, but always calculate dynamically for accurate results.<mxCell value="Vision-Language-Action (VLA) Model Optimization and Data Governance Strategies"
style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;spacingLeft=5;spacingRight=5;verticalAlign=middle;align=center;"
vertex="1" parent="1">
<mxGeometry x="100" y="100" width="[calculated_from_text]" height="[calculated_from_text]" as="geometry" />
</mxCell>Note: Replace [calculated_from_text] with actual values calculated using the formulas in Section 2.2
Use standard grid system for layout to ensure even element spacing:
Horizontal spacing = 180px
Vertical spacing = 120pxNote: Element dimensions (width and height) should be calculated dynamically based on text content as described in Section 2.
x = col_index * 180 + margin_lefty = row_index * 120 + margin_top<!-- Row 1, Column 1 - dimensions calculated based on text content -->
<mxCell id="n1" vertex="1" parent="1">
<mxGeometry x="40" y="40" width="[calculated]" height="[calculated]" as="geometry"/>
</mxCell>
<!-- Row 1, Column 2 - dimensions calculated based on text content -->
<mxCell id="n2" vertex="1" parent="1">
<mxGeometry x="220" y="40" width="[calculated]" height="[calculated]" as="geometry"/>
</mxCell>
<!-- Row 2, Column 1 - dimensions calculated based on text content -->
<mxCell id="n3" vertex="1" parent="1">
<mxGeometry x="40" y="160" width="[calculated]" height="[calculated]" as="geometry"/>
</mxCell>Suitable for flowcharts, decision trees, and other charts with hierarchical structure:
Level 0: Root node (top center)
Level 1: Direct child nodes
Level 2: Grandchild nodes
...Rhombus (decision) nodes need extra width and height based on text content:
Size Multipliers for Rhombus:
Example: If text requires width=120px and height=50px:
Suitable for organization charts, inheritance relationship diagrams, etc.:
Root node: Top center
Child nodes: Uniformly distributed below parent node
Branch angle: Keep within 45° to avoid excessive dispersionSuitable for state diagrams, circular processes, etc.:
Center point: (canvas_width/2, canvas_height/2)
Radius: Adjust based on element count
Angle interval: 360° / element countx = center_x + radius * cos(angle)
y = center_y + radius * sin(angle)Elements within containers use coordinates relative to the container:
<!-- Container -->
<mxCell id="group1" vertex="1" parent="1">
<mxGeometry x="100" y="100" width="400" height="300" as="geometry"/>
</mxCell>
<!-- Elements within container: coordinates relative to group1 -->
<mxCell id="child1" vertex="1" parent="group1">
<mxGeometry x="20" y="40" width="[calculated]" height="[calculated]" as="geometry"/>
</mxCell>Swimlane containers typically include title bars; child elements need to avoid title bars:
startSize = 30px (default title bar height)
Child element y coordinate >= startSize + padding<!-- Swimlane container -->
<mxCell id="swimlane1" value="Swimlane 1" style="swimlane;startSize=30;" vertex="1" parent="1">
<mxGeometry x="100" y="100" width="400" height="300" as="geometry"/>
</mxCell>
<!-- Elements within swimlane -->
<mxCell id="lane1-n1" vertex="1" parent="swimlane1">
<mxGeometry x="20" y="40" width="[calculated]" height="[calculated]" as="geometry"/>
</mxCell>For multi-layer nested containers, coordinates at each level are relative to its parent container:
Absolute position = Parent container position + Relative positionCondition for two rectangles to overlap:
(x1 < x2 + width2) AND (x1 + width1 > x2) AND
(y1 < y2 + height2) AND (y1 + height1 > y2)Reserve safe spacing between elements:
Minimum horizontal spacing = 40px
Minimum vertical spacing = 40pxWhen horizontal overlap is detected, move element away:
new_x = existing_x + existing_width + min_spacingWhen vertical overlap is detected, move element down:
new_y = existing_y + existing_height + min_spacingSet edge style to orthogonal routing:
<mxCell edge="1" source="n1" target="n2"
style="edgeStyle=orthogonalEdgeStyle;rounded=1;">
<mxGeometry relative="1" as="geometry"/>
</mxCell>Place tightly connected nodes in adjacent positions to reduce long lines:
Original layout: A(0,0) → B(400,0) → C(400,400)
Optimized: A(0,0) → B(180,0) → C(180,120)Place related nodes together and use containers for grouping:
<!-- Container -->
<mxCell id="related-group" style="group;" vertex="1" parent="1">
<mxGeometry x="100" y="100" width="400" height="200" as="geometry"/>
</mxCell>
<!-- Related nodes -->
<mxCell id="n1" vertex="1" parent="related-group">...</mxCell>
<mxCell id="n2" vertex="1" parent="related-group">...</mxCell>
<mxCell id="n3" vertex="1" parent="related-group">...</mxCell>Use entryX/entryY and exitX/exitY to control connection positions:
<mxCell edge="1" source="n1" target="n2"
style="exitX=1;exitY=0.5;entryX=0;entryY=0.5;">
<mxGeometry relative="1" as="geometry"/>
</mxCell>Let lines bypass obstacles using additional path points:
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="200" y="100"/>
<mxPoint x="200" y="300"/>
</Array>
</mxGeometry> Start
↓
[Step 1] ←───┐
↓ │
[Step 2] │ Loop
↓ │
[Decision]──┘
↙ ↘
[Yes] [No]
↓ ↓
[Continue] [End]Layout Points:
CEO
┌───────┼───────┐
VP1 VP2 VP3
↓ ↓ ↓
┌────┐ ┌────┐ ┌────┐
T1 T2 T3 T4 T5 T6Layout Points:
┌─────────┐
│ Class A │
└─────────┘
↑
│
┌─────────┐
│ Class B │
└─────────┘
↑
│
┌─────────┐
│ Class C │
└─────────┘Layout Points:
┌──────┐
│ Initial │
└──┬───┘
↓
┌──────┐
│ State A │◄────┐
└──┬───┘ │
│ │
┌──────┐ │
│ State B │─────┘
└──┬───┘
↓
┌──────┐
│ End │
└──────┘Layout Points:
x and y in mxGeometryWhen adjusting positions, the following content cannot be modified:
value (display text)style (style definition)id (unique identifier)source and target (connection relationships)parent relationshipsPositioning of text-only labels (without borders):
x = Related element center x - Label width/2
y = Related element top - Label height - SpacingAnnotation elements should be placed near related elements:
Offset = 20px
Position = Target element corner + OffsetEnsure all elements are within canvas range:
x >= 0 AND x + width <= canvas_width
y >= 0 AND y + height <= canvas_heightIt's recommended to backup original position information before modification:
<!-- Keep original position as comment -->
<!-- original: x=100,y=200 -->
<mxCell id="n1" vertex="1" parent="1">
<mxGeometry x="150" y="180" width="140" height="60" as="geometry"/>
</mxCell>For detailed draw.io XML format explanations, please refer to: - drawio-format-adapter/SKILL.md - reference/xml-reference.md
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.