Files
sap-architecture/references/drawio-gotchas.md
T
2026-07-24 20:47:16 +00:00

124 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# draw.io / mxGraph authoring gotchas
Encoding and alignment rules that apply whenever this skill **writes or edits
mxCell XML directly** — i.e. during surgical relabels (step 4), when adding
cards/edges next to template cells, and in `render_semantic.py`-derived output.
Violations are silent at write time and only visible when the user opens the
file: blank icons, "duplicate id" rejections, or connectors cutting through
artwork. `validate.py` mechanically checks §§12 and the structural parts of §7.
Scaffolded SAP templates already satisfy all of this — these rules matter for
the cells **you** add or change.
## 1. Embedded-image data URIs must OMIT `;base64`
draw.io style strings are `;`-delimited key=value lists. A standard data URI
(`data:image/svg+xml;base64,PHN2...`) contains a `;` — draw.io truncates the
`image=` value at that semicolon and starts parsing `base64,PHN2...` as a new
style key. Result: every icon renders blank, with no error.
- **Correct (draw.io style):** `image=data:image/svg+xml,PHN2Zy8+;`
(payload IS still base64-encoded; only the `;base64` marker is dropped —
draw.io's own convention, and what the bundled SAP libraries ship.)
- **Incorrect:** `image=data:image/svg+xml;base64,PHN2Zy8+;`
- Plain SVG/HTML is the opposite: an `<image href>` **requires** the standard
`;base64` form. If you generate both a `.drawio` and an SVG preview from the
same data, the two encodings must differ.
`extract_icon.py` / `extract_asset.py` emit the correct form — this rule bites
only when embedding a third-party logo or UI5 icon-font SVG by hand.
## 2. Root-cell skeleton and reserved ids
Every diagram page must begin with a **parentless root cell**, then a **layer
cell parented to it**, before any content:
```xml
<mxCell id="0" />
<mxCell id="1" parent="0" />
```
`0`/`1` are mxGraph's defaults, but the SAP corpus frequently uses namespaced
equivalents (`<prefix>-0`, `<prefix>-1`) — the *structure* is what matters, and
`validate.py` checks it. Two failure modes for hand-authored pages:
- Omitting the two root cells entirely → draw.io rejects the file.
- A content cell reusing the page's root/layer id (easy when deriving ids from
numeric counters, colliding with literal `0`/`1`) → "duplicate id", whole
file rejected. Namespace generated ids (`n-<id>`, `edge-3`, `pill-2`).
Ids must be unique within a page; each `<diagram>` page has its own id space.
## 3. Z-order is document order
Later cells render on top. Emit **edges before vertices** so connectors sit
behind nodes/icons (SAP's files do this; they never rely on opaque icon
backings). draw.io resolves an edge's `source`/`target` by id even when those
cells are declared later — forward references are fine. When inserting new
cards into a template, insert them **after** the edges that touch them.
## 4. Connectors must attach to facing connection points
Without fixed connection points, draw.io anchors edges center-to-center and a
line can cut straight through nodes that sit between endpoints. Give every
added edge directional exit/entry on the border side facing the counterpart:
```
exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;
```
(source's right edge → target's left edge, for a left-to-right flow; use
Y 0/1 with X 0.5 for vertical). Combine with `edgeStyle=orthogonalEdgeStyle;
rounded=0;orthogonalLoop=1;jettySize=auto;` so the router runs segments through
the gaps between columns. Z-order alone is never the fix for edges crossing
icons. This complements the center-alignment rule in `shapes-and-edges.md`:
aligned centers make the edge *straight*; facing anchors make it *dock* on the
correct sides.
## 5. Explicit waypoints
To force a route (e.g. through a routing channel between zones), put bend
points inside the edge geometry — intermediate points only; endpoints come
from the cells:
```xml
<mxGeometry relative="1" as="geometry">
<Array as="points"><mxPoint x="520" y="140"/><mxPoint x="520" y="260"/></Array>
</mxGeometry>
```
Keep waypoint coordinates on the 10-px grid like everything else.
## 6. Image aspect ratio & inscription
`imageAspect=1` preserves proportions (`0` stretches to the cell box — wide
wordmark logos become distorted). The SAP corpus itself uses `imageAspect=0`
on cells whose geometry was hand-sized to the artwork, so this is **not** a
validator check — it's a rule for logos *you* embed, where the cell box rarely
matches the source aspect exactly. In SVG the equivalent is
`preserveAspectRatio="xMidYMid meet"`. Square logos placed on a circular tile
must be inscribed: icon side ≤ tile diameter / √2, or the corners poke past
the circle (e.g. a 52-px tile fits at most a ~36-px square icon).
## 7. Structure & page setup
- Skeleton: `<mxfile><diagram id="..." name="..."><mxGraphModel ...><root>` +
the two reserved cells, then content. Emit uncompressed XML — never the
base64-deflate `<diagram>` payload form.
- Every vertex needs `vertex="1"` + `<mxGeometry x y width height as="geometry"/>`;
every edge `edge="1"` + resolvable `source`/`target` (or explicit
`sourcePoint`/`targetPoint` for floating edges); every cell (except `0`) a
valid `parent`.
- Children of a container (`container=1` or any parented vertex) use
coordinates **relative to the parent**, not the canvas. When re-parenting an
icon into a card (the "tucked inside a card" pattern), convert its x/y to
card-local values.
- Escape XML in labels/attrs: `&` `<` `>``&amp;` `&lt;` `&gt;`; `html=1`
when the label carries HTML.
## 8. Edge routing extras seen in the SAP corpus
- `entityRelationEdgeStyle` — perpendicular jetty stubs; SAP uses it for
*indirect* flows where orthogonal elbows would read as a direct chain.
- `targetPerimeterSpacing=15` — leaves a visual gap before the target border so
arrowheads don't kiss the stroke.
- `jumpStyle=none` — edge crossings drawn flat, no hop arcs. Don't enable
jumps; SAP's published files never use them.