Draw.io 图表绘制
Use when the user requests diagrams, flowcharts, architecture diagrams, ER diagrams, UML / sequence / class diagrams, network topology, cloud architecture from Terraform or Kubernetes manifests, ML/DL model figures (Transformer/CNN/LSTM), mind maps, or any visualization. Also use proactively when explaining systems with 3+ components, complex data flows, or relationships that benefit from visual representation. Best suited when the diagram needs custom styling, rich shape vocabulary, swimlanes, or unique geometry. Generates `.drawio` XML files ready to open in draw.io desktop.
SKILL.md
Draw.io Diagrams
Overview
Generate .drawio XML files ready to open in draw.io desktop for further editing and export to PNG/SVG/PDF/JPG.
When to use / when NOT to use
Use this skill for: polished, precise diagrams (architecture, network, strict UML, ERD), anything needing solid opaque fills, 10,000+ stock/branded shapes, swimlanes, or custom geometry. Generates .drawio files ready to open in draw.io desktop.
Do NOT use it — route elsewhere — for:
- A casual hand-drawn / whiteboard look → excalidraw or tldraw.
- Diagrams-as-code that live in git / render in Markdown → mermaid (general) or plantuml (UML).
- Freeform infinite-canvas sketching or freehand strokes → tldraw.
Bundled resources
When the workflow references one of these, read it on demand — none of them need to be in context up front.
| File | Read it when |
|---|---|
references/toolbox.md | You're not sure which bundled script fits a request, or want to chain several — a map of all 28 scripts grouped by use-case (author / import code / import IaC / import API spec / live infra / compare / annotate / reverse-export / utilities) with an "I have X, I want Y → use Z" guide |
references/xml-authoring.md | You're about to hand-write .drawio XML (workflow step 3) — file skeleton, shape/edge cells, containers, connection distribution, palette, spacing/grid rules. Not needed when a bundled generator writes the XML |
references/diagram-types.md | The user names a specific diagram type (ERD, UML class, sequence, C4, architecture, ML/DL, flowchart) |
references/shapes.md + scripts/shapesearch.py | The diagram needs a specific shape — a cloud icon (AWS/Azure/GCP), Cisco/Kubernetes/network symbol, UML/BPMN/ER/electrical/P&ID element — or any time you'd otherwise guess a style= string. shapesearch.py "<keywords>" returns the exact official style for 10k+ shapes |
scripts/aiicons.py | The diagram involves an AI/LLM brand (OpenAI, Claude, Gemini, Mistral, Llama, HuggingFace, Ollama, LangChain, …) — aiicons.py "<brand>" returns a draw.io image style for the brand logo (lobe-icons via CDN; --embed to inline). draw.io has no built-in AI logos. See references/shapes.md → "AI / LLM brand logos" |
references/style-presets.md | The user asks to learn / save / list / set-default / delete a style preset, or you've resolved an active preset and need the application rules |
references/style-extraction.md | You're inside the Learn flow and need the extraction procedure (called from style-presets.md) |
references/troubleshooting.md | An export fails or a rendering looks wrong |
scripts/repair_png.py | After every -e PNG export — fixes draw.io's truncated IEND chunk (issue #8) |
scripts/encode_drawio_url.py | The CLI is unavailable and you need a browser-fallback diagrams.net URL (--edit for an editable editor URL) |
references/autolayout.md | The diagram is large or layout-heavy (dependency/call graph, code structure, >~15 nodes) and you want Graphviz to place nodes + route edges instead of hand-placing coordinates |
scripts/pyimports.py · jsimports.py · goimports.py · rustimports.py | The user wants to visualize a Python, JS/TS, Go, or Rust project structure |
scripts/pyclasses.py | The user wants a Python class hierarchy / class diagram |
scripts/tfimports.py · k8simports.py · composeimports.py | Visualize declared infrastructure (Terraform, K8s, docker-compose) |
scripts/tfstate.py · dockerimports.py | Draw what is actually running / deployed |
scripts/drawiodiff.py | Compare / diff two diagrams or two snapshots |
scripts/timelapse.py | Architecture time-lapse over git history |
scripts/explain.py | Describe / document an existing .drawio |
scripts/drawio2pptx.py | Export diagram to PowerPoint deck |
scripts/drawiohtml.py | Generate a shareable interactive HTML viewer from .drawio |
scripts/svgflow.py | Animated / "flowing" diagram (marching-ants edges) |
scripts/sqlerd.py | ER diagram from SQL DDL — parses CREATE TABLE statements |
scripts/openapiimports.py | API diagram from OpenAPI / Swagger spec — operations coloured by HTTP method |
scripts/heatmap.py | The user wants to colour an existing .drawio by data (a cost / latency / traffic / error-rate heat map) — heatmap.py diagram.drawio -m metrics.csv matches each metric (CSV key,value or JSON {key:value}) to a node by id or label and recolours it along a gradient (--palette heat|cool|warm, --reverse), optionally scaling node size (--size) and adding a legend. Post-processes any diagram; export as usual |
scripts/seqlayout.py | The user wants a sequence diagram — describe participants + messages as JSON and the script computes all lifeline/activation/arrow geometry deterministically (no hand-placed coordinates, no Graphviz needed) |
scripts/c4.py | The user wants a C4 model (System Context / Container / Component) — levels JSON in, one multi-page .drawio out with official C4 shapes/colors and click-to-drill-down links between levels |
scripts/validate.py | You generated a .drawio (especially via autolayout or for a large hand-placed diagram) and want a fast deterministic structural lint (dangling edges, dup/reserved ids, broken parents, overlaps) before exporting. --score prints a readability score for comparing layout variants |
Prerequisites
The draw.io desktop app must be installed and the CLI accessible:
macOS sandbox / sandbox isolation note (e.g., codex.app): In some sandboxed macOS environments, invoking the draw.io desktop CLI (even drawio --version) can crash the draw.io process or produce no output. If that happens, treat the CLI as unavailable in this sandbox isolation — do not keep retrying inside the sandbox. Prefer a non-sandboxed host environment (outside sandbox isolation) for any CLI export work, or use the browser fallback / XML-only outputs.
# macOS (Homebrew — recommended; CLI binary is `drawio`, not `draw.io`)
brew install --cask drawio
drawio --version
# macOS (full path if not in PATH)
/Applications/draw.io.app/Contents/MacOS/draw.io --version
# Windows
"C:\Program Files\draw.io\draw.io.exe" --version
# Linux
drawio --version
Install draw.io desktop if missing:
- macOS:
brew install --cask drawioor download from https://github.com/jgraph/drawio-desktop/releases - Windows: download installer from https://github.com/jgraph/drawio-desktop/releases
- Linux: download
.deb/.rpmfrom https://github.com/jgraph/drawio-desktop/releases — do not use snap (AppArmor sandbox denies secrets/keyring on servers, causes crash)
Workflow
Before starting the workflow, assess whether the user's request is specific enough. If key details are missing, ask 1-3 focused questions:
- Diagram type — which preset? (ERD, UML, Sequence, Architecture, ML/DL, Flowchart, or general)
- Output location — default is the user's working dir; honor any explicit path the user gives (e.g. "put it in
./artifacts/"). Don't ask if they didn't mention one. - Scope/fidelity — how many components? Any specific technologies or labels?
Skip clarification if the request already specifies these details or is clearly simple (e.g., "draw a flowchart of X").
Step 0 — Resolve active preset. Determine which (if any) user-defined style preset applies to this generation.
- Scan the user's message for a phrase that clearly names a style preset: "use my
<name>style", "with my<name>style", "in<name>mode", "in the style of<name>". A barewith <name>does not count — "draw a diagram with redis" names a component, not a style. If a clear match is found → active preset =<name>. - Else, check
~/.drawio-skill/styles/for any file with"default": true. If found → active preset = that one. - Else → no preset active; fall through to the built-in color/shape/edge conventions for the rest of the workflow.
Load the preset JSON from ~/.drawio-skill/styles/<name>.json, falling back to <this-skill-dir>/styles/built-in/<name>.json. If the named preset exists in neither location, tell the user the name is unknown, list the available presets (user dir + built-in), and stop — do not silently fall back to defaults.
When a preset loads successfully, mention it in the first line of the reply: "Using preset <name> (confidence: <level>)." See references/style-presets.md → "Applying a preset" for how the preset changes color/shape/edge/font decisions.
- Check deps — resolve which name the binary has on this system and use that name verbatim in every subsequent command in this workflow. Try in order: (a)
drawio --version(the canonical name for Homebrew cask, jgraph.deb/.rpm, Arch AUR), (b)draw.io --version(older builds, some custom symlinks, some distro packages), (c) macOS.appdirect:/Applications/draw.io.app/Contents/MacOS/draw.io --version, (d) Windows:"C:\Program Files\draw.io\draw.io.exe" --version. The first one that prints a version is your binary; remember the exact path/name and substitute it fordrawioin every command below. Do not copy the example commands verbatim if your binary is named differently — the examples usedrawioonly because it's the most common. On macOS-Homebrew,drawiois just a thin wrapper script that execs/Applications/draw.io.app/Contents/MacOS/draw.io— they run the same engine, so candidate (c) is only needed when thedrawiowrapper is absent (e.g. the app was installed by drag-and-drop without the cask). Note the major version for CLI flag compatibility. - Plan — identify shapes, relationships, layout (LR or TB), group by tier/layer
- Generate — produce the
.drawiofile via hand-written XML or a bundled generator: (a) Hand-written XML for custom styling, vendor icons, swimlanes, precise geometry — readreferences/xml-authoring.mdfirst (skeleton, cell forms, palette, spacing rules). (b) A bundled generator for the data-driven cases below. For large or layout-heavy diagrams (dependency/call graphs, code structure, >~15 nodes), don't hand-place — describe the graph as JSON and runpython3 <this-skill-dir>/scripts/autolayout.py graph.json -o <name>.drawioto compute node positions + orthogonal edge routing via Graphviz (seereferences/autolayout.md; add--tuneto auto-pick the more readable direction). For a Python / JS-TS / Go / Rust project, the matching importer (scripts/pyimports.py,jsimports.py,goimports.py, orrustimports.py) extracts the import graph (transitive-reduced; add--groupto box modules by sub-package, nested for deep trees) ready for autolayout; for a Python class hierarchy,scripts/pyclasses.pyextracts classes + inheritance instead; for Terraform / Kubernetes / docker-compose (scripts/tfimports.py,k8simports.py,composeimports.py), the importer extracts the resource/service reference graph — tf/k8s nodes resolve to their official cloud icons automatically; to draw what is actually running rather than the declared config, pipeterraform show -jsonintoscripts/tfstate.pyordocker inspect $(docker ps -q)intoscripts/dockerimports.py(k8simports.pyalready accepts livekubectl get ... -o json) — seereferences/live-infra.md; for an ER diagram from SQL DDL,scripts/sqlerd.pyparsesCREATE TABLEinto table nodes + crow's-foot FK edges; for an API diagram from an OpenAPI / Swagger spec,scripts/openapiimports.pymaps operations (coloured by HTTP method) + component schemas into a graph for autolayout. To turn any generated.drawiointo a metric heat map — recolour nodes by a CSV/JSON of cost/latency/traffic/errors — runpython3 <this-skill-dir>/scripts/heatmap.py <name>.drawio -m metrics.csv(matches on cell id or label;--palette,--size, legend). For a sequence diagram, skip autolayout entirely — describe participants + messages as JSON and runpython3 <this-skill-dir>/scripts/seqlayout.py seq.json -o <name>.drawio(deterministic lifeline/activation/arrow geometry; see the script docstring for the JSON schema). For a C4 model,python3 <this-skill-dir>/scripts/c4.py c4.json -o <name>.drawioemits the full multi-page Context→Container→Component set with drill-down links (schema in the script docstring). For complex architecture diagrams with many visible edge labels, give labelslabelBackgroundColor=#ffffff;fontSize=11and use edge geometryx/yoffsets plus<mxPoint as="offset" />to move long labels into nearby whitespace instead of relying on draw.io's default midpoint placement. After generating any.drawio, runpython3 <this-skill-dir>/scripts/validate.py <name>.drawiofor a fast structural lint (dangling edges, dup ids, overlaps), then generate a viewer URL viapython3 <this-skill-dir>/scripts/encode_drawio_url.py <name>.drawioand open it withopen_previewto show the diagram to the user. Default output dir is the user's working dir; if the user specified an output path or directory (e.g../artifacts/,docs/images/), use that instead —mkdir -pthe target dir first. - Review loop — collect user feedback, apply targeted XML edits, re-run encode_drawio_url.py to update the preview, repeat until approved
If drawio --version crashes or prints nothing (common in restricted macOS sandbox isolation like codex.app):
- Do not keep retrying CLI invocations inside the sandbox.
- Use Browser fallback (
scripts/encode_drawio_url.py) or deliver the.drawioXML only.
Escalation rule:
- If the binary exists on PATH (or known app path exists) but execution fails with abnormal exit, empty output, Electron startup failure, display/session error, or likely sandbox restriction, prefer one escalated retry before falling back.
- If the binary is missing entirely, do not escalate just to search more aggressively; go to install guidance or fallback.
Step 4: Review Loop
After preview opens, collect user feedback and apply targeted XML edits as needed.
Targeted edit rules — for each type of feedback, apply the minimal XML change:
| User request | XML edit action |
|---|---|
| Change color of X | Find mxCell by value matching X, update fillColor/strokeColor in style |
| Add a new node | Append a new mxCell vertex with next available id, position near related nodes |
| Remove a node | Delete the mxCell vertex and any edges with matching source/target |
| Move shape X | Update x/y in the mxGeometry of the matching mxCell |
| Resize shape X | Update width/height in the mxGeometry of the matching mxCell |
| Add arrow from A to B | Append a new mxCell edge with source/target matching A and B ids |
| Change label text | Update the value attribute of the matching mxCell |
| Change layout direction | Full regeneration — rebuild XML with new orientation |
Rules:
- For single-element changes: edit existing XML in place — preserves layout tuning from prior iterations
- For layout-wide changes (e.g., swap LR↔TB, "start over"): regenerate full XML
- After applying edits, re-generate viewer URL and re-open preview with
open_preview - Loop continues until user says approved / done / LGTM
- Safety valve: after 5 iteration rounds, suggest the user open the
.drawiofile in draw.io desktop for fine-grained adjustments
Style Presets
A style preset is a named JSON file capturing a user's visual preferences (palette, shapes, font, edges). When active, it fully replaces the built-in color/shape conventions in this skill.
Lookup order when SKILL.md's Step 0 resolves a preset name:
~/.drawio-skill/styles/<name>.json— user presets (survivegit pull)<this-skill-dir>/styles/built-in/<name>.json— shipped built-ins (default,corporate,handdrawn,colorblind-safe,dark)
Always lowercase the user-provided name before any file operation — the schema enforces lowercase.
For everything else — Learn flow (extracting a preset from a file), management ops (list/default/delete/rename), application rules (color lookup, shape keywords, edges, fonts, extras, interaction with diagram-type presets), and validation — read references/style-presets.md. It's only needed when the user invokes those flows or when an active preset must be applied to the current generation.
Authoring .drawio XML
Before hand-writing any .drawio XML (step 3), read references/xml-authoring.md — file skeleton, shape/edge cell forms, containers, connection-point distribution, color palette, and spacing/grid rules all live there. Skip it only when a bundled generator writes the XML for you (autolayout.py + importers, seqlayout.py).
Two rules worth stating even here: never reuse ids 0/1 (reserved root cells), and every edge mxCell needs a <mxGeometry relative="1" as="geometry" /> child — self-closing edge cells do not render.
Browser fallback (no CLI needed)
python3 <this-skill-dir>/scripts/repair_png.py diagram.drawio.png
The script's `endswith(IEND)` guard makes it a no-op once draw.io fixes the bug upstream — safe to run unconditionally.
**Key flags:**
- `-x` — export mode (required)
- `-f` — format: `png`, `svg`, `pdf`, `jpg`
- `-e` — embed diagram XML in output (PNG, SVG, PDF) — exported file remains editable in draw.io. For final PNG export, keep `-e` and run `scripts/repair_png.py` (see Post-export PNG repair). SVG/PDF unaffected.
- `-s` — scale: `1`, `2`, `3` (2 recommended for final PNG)
- `--width <px>` — target width in pixels (no short form; `-w` does **not** exist and silently breaks the input-file parser). Don't combine `--width` with `-s`.
- `-o` — output file path; accepts any directory (e.g. `./artifacts/diagram.drawio.png`) — `mkdir -p` the target dir first. Use `.drawio.png` double extension when embedding.
- `--layout <preset|json>` — **CLI ≥ v30 only** — ELK auto-layout pass on XML input (`verticalFlow`, `horizontalFlow`, `verticalTree`, `horizontalTree`, `radialTree`, `organic`, or a custom ELK JSON array). Alternative to `autolayout.py` when Graphviz is missing. On ≤ 29 this flag breaks argument parsing — don't emit it.
- `-b` — border width around diagram (default: 0, recommend 10)
- `-t` — transparent background (PNG only)
- `--page-index <n>` — export one page of a multi-page file. **1-based** in current drawio-desktop (verified on 29.7.8: `--page-index 2` exports the second page; older docs claimed 0-based). Default: first page. `--page-range 2..3` also works
### Browser fallback (no CLI needed)
When the draw.io desktop CLI is unavailable, generate a client-side URL:
```bash
python3 <this-skill-dir>/scripts/encode_drawio_url.py input.drawio # read-only viewer
python3 <this-skill-dir>/scripts/encode_drawio_url.py --edit input.drawio # opens in the editor
Default prints a https://viewer.diagrams.net/...#R… viewer URL; --edit prints a https://app.diagrams.net/...#create=… URL that opens straight into the editable editor. Either way the diagram XML is encodeURIComponent-encoded, deflate-compressed, and base64'd into the URL fragment — the fragment (after #) is never sent to the server, so nothing is uploaded. The encodeURIComponent step is mandatory: without it, any diagram containing a literal % or non-ASCII (e.g. CJK) label makes the browser throw "URI malformed" and the diagram never opens.
Open the URL with open "$URL" (macOS) / xdg-open "$URL" (Linux). On WSL2 / Windows, cmd.exe drops the #fragment — write a .url shortcut file and open that instead (see references/troubleshooting.md → "WSL2 / Windows specifics").
Fallback chain
When tools are unavailable, degrade gracefully:
| Scenario | Behavior |
|---|---|
| draw.io CLI missing, Python available | Use browser fallback (diagrams.net URL) |
| draw.io CLI missing, Python missing | Generate .drawio XML only; instruct user to open in draw.io desktop or diagrams.net manually |
| draw.io CLI crashes / no output in macOS sandbox isolation | Treat CLI as unavailable in-sandbox; use browser fallback / XML-only; ask user to run CLI exports in a non-sandboxed host environment |
| Export fails (Chromium/display issues) | On Linux, retry with xvfb-run -a; if still failing, deliver .drawio XML and suggest manual export |
| Export fails on Linux server (headless) | Try in order: (1) xvfb-run -a, (2) append --no-sandbox at the very end if root, (3) add --disable-gpu, (4) export HOME=/tmp, (5) install apt deps (libgtk-3-0 libnotify4 libnss3 libgbm1 libasound2t64 etc.), (6) fall back to tomkludy/drawio-renderer Docker (REST API for headless export) |
Checking if drawio is in PATH
# Prefer the Homebrew / Linux-package binary name (no dot)
if command -v drawio &>/dev/null; then
DRAWIO="drawio"
# Fall back to the dot-named binary (older installs, manual symlinks)
elif command -v draw.io &>/dev/null; then
DRAWIO="draw.io"
# macOS .app bundle (binary inside the bundle keeps the dot)
elif [ -f "/Applications/draw.io.app/Contents/MacOS/draw.io" ]; then
DRAWIO="/Applications/draw.io.app/Contents/MacOS/draw.io"
# WSL2: the CLI is the Windows desktop exe, reached via /mnt/c (note the space)
elif grep -qi microsoft /proc/version 2>/dev/null && [ -f "/mnt/c/Program Files/draw.io/draw.io.exe" ]; then
DRAWIO="/mnt/c/Program Files/draw.io/draw.io.exe"
else
echo "drawio not found — install from https://github.com/jgraph/drawio-desktop/releases (Homebrew: brew install --cask drawio)"
fi
On WSL2 / native Windows, opening exported files and browser-fallback URLs needs path conversion + a .url-file workaround (cmd.exe drops URL #fragments) — see the "WSL2 / Windows specifics" section in references/troubleshooting.md.
Common Mistakes
When something looks wrong (export fails, vision rejects a PNG, layout broken, edges misroute), see references/troubleshooting.md for a row-by-row mistake → fix table.
Diagram Type Presets
When the user requests a specific diagram type, read references/diagram-types.md for the matching preset (shapes, edges, layout direction). Pick by user phrasing:
| User says | Section in references/diagram-types.md |
|---|---|
| "ER diagram", "schema diagram", "data model" | ERD |
| "UML class diagram", "class diagram" | UML Class |
| "sequence diagram", "interaction diagram", "lifeline" | Sequence |
| "architecture", "system diagram", "service diagram" | Architecture |
| "neural network", "model architecture", "ML diagram", "deep learning" | ML / Deep Learning Model |
| "flowchart", "decision tree", "process flow" | Flowchart |
| "C4", "system context diagram", "container diagram", "component diagram" | C4 Model |
The diagram-type preset sets structural style keywords. If a user style preset is also active (see ## Style Presets), keep the structural keywords and layer color/font/edge/extras on top — read references/style-presets.md → "Interaction with diagram-type presets" for the merge rules.
评论与讨论
还没有评论,分享你的体验吧。