@littledragon_wxl/drawio-style-graph 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/LICENSE +21 -0
  3. package/README.md +175 -0
  4. package/README_zh.md +171 -0
  5. package/SKILL.md +419 -0
  6. package/data/SHAPE-INDEX-NOTICE.md +17 -0
  7. package/data/lobe-icons.json +878 -0
  8. package/data/shape-index.json.gz +0 -0
  9. package/package.json +43 -0
  10. package/references/autolayout.md +125 -0
  11. package/references/diagram-types.md +83 -0
  12. package/references/shapes.md +151 -0
  13. package/references/style-application-guide.md +120 -0
  14. package/references/style-diagram-matrix.md +159 -0
  15. package/references/style-extraction.md +255 -0
  16. package/references/style-presets.md +110 -0
  17. package/references/styles/style-1-flat-icon.md +79 -0
  18. package/references/styles/style-2-dark-terminal.md +80 -0
  19. package/references/styles/style-3-blueprint.md +84 -0
  20. package/references/styles/style-4-notion-clean.md +78 -0
  21. package/references/styles/style-5-glassmorphism.md +85 -0
  22. package/references/styles/style-6-claude-official.md +84 -0
  23. package/references/styles/style-7-openai.md +94 -0
  24. package/references/styles/style-8-dark-luxury.md +109 -0
  25. package/references/troubleshooting.md +63 -0
  26. package/scripts/aiicons.py +201 -0
  27. package/scripts/autolayout.py +341 -0
  28. package/scripts/encode_drawio_url.py +58 -0
  29. package/scripts/goimports.py +141 -0
  30. package/scripts/jsimports.py +162 -0
  31. package/scripts/pyclasses.py +156 -0
  32. package/scripts/pyimports.py +153 -0
  33. package/scripts/repair_png.py +37 -0
  34. package/scripts/rustimports.py +203 -0
  35. package/scripts/shapesearch.py +162 -0
  36. package/scripts/validate.py +137 -0
  37. package/styles/built-in/corporate.json +49 -0
  38. package/styles/built-in/default.json +49 -0
  39. package/styles/built-in/handdrawn.json +49 -0
  40. package/styles/schema-drawio.json +112 -0
  41. package/styles/schema.json +213 -0
Binary file
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@littledragon_wxl/drawio-style-graph",
3
+ "version": "1.0.0",
4
+ "description": "Generate .drawio diagrams with 8 professional visual styles. Self-contained — no external skill dependencies.",
5
+ "main": "SKILL.md",
6
+ "keywords": [
7
+ "drawio",
8
+ "diagram",
9
+ "flowchart",
10
+ "architecture",
11
+ "visualization",
12
+ "uml",
13
+ "svg",
14
+ "style-preset",
15
+ "skill",
16
+ "claude-code"
17
+ ],
18
+ "author": "littledragon_wxl",
19
+ "license": "MIT",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/Littledragon-wxl/drawio-style-graph.git"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/Littledragon-wxl/drawio-style-graph/issues"
26
+ },
27
+ "homepage": "https://github.com/Littledragon-wxl/drawio-style-graph#readme",
28
+ "files": [
29
+ "SKILL.md",
30
+ "README.md",
31
+ "README_zh.md",
32
+ "LICENSE",
33
+ "CHANGELOG.md",
34
+ "scripts/",
35
+ "data/",
36
+ "references/",
37
+ "styles/"
38
+ ],
39
+ "engines": {
40
+ "node": ">=14.0.0"
41
+ }
42
+ }
43
+
@@ -0,0 +1,125 @@
1
+ # Auto-layout (Graphviz)
2
+
3
+ Read this when a diagram is **large or layout-heavy** — dependency/call graphs, code/module structure, or roughly **more than ~15 nodes** — where hand-placing `x`/`y` coordinates is slow, error-prone, and overlap-prone.
4
+
5
+ Instead of computing coordinates by hand in the Generate step, describe the graph as JSON and let `scripts/autolayout.py` place the nodes and route the edges with Graphviz, then continue the normal workflow (Export draft → Self-check → …) on the produced `.drawio`.
6
+
7
+ For small or carefully-styled diagrams, keep hand-placing — auto-layout trades fine control for scale.
8
+
9
+ ## Dependency
10
+
11
+ Requires Graphviz `dot` on PATH:
12
+
13
+ ```bash
14
+ # macOS
15
+ brew install graphviz
16
+ # Debian/Ubuntu
17
+ sudo apt install graphviz
18
+ ```
19
+
20
+ The script exits with a clear message if `dot` is missing — fall back to hand-placed coordinates in that case.
21
+
22
+ ## Usage
23
+
24
+ ```bash
25
+ python3 <this-skill-dir>/scripts/autolayout.py graph.json -o diagram.drawio
26
+ ```
27
+
28
+ It prints `wrote diagram.drawio (N nodes, M edges)` to stderr and writes a normal `.drawio` file. From there, continue at the **Export draft** step of the main workflow (preview PNG with `--width 2000`, self-check, review loop, final export with `-e` + `repair_png.py`).
29
+
30
+ ## Input format
31
+
32
+ ```json
33
+ {
34
+ "direction": "TB",
35
+ "nodes": [
36
+ {"id": "client", "label": "Web Client", "style": "rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;"},
37
+ {"id": "gw", "label": "API Gateway", "group": "edge", "groupLabel": "Edge tier"},
38
+ {"id": "db", "label": "User DB", "style": "shape=cylinder3;whiteSpace=wrap;html=1;", "width": 120, "height": 80, "group": "data"}
39
+ ],
40
+ "edges": [
41
+ {"source": "client", "target": "gw", "label": "HTTPS"},
42
+ {"source": "gw", "target": "db"}
43
+ ]
44
+ }
45
+ ```
46
+
47
+ **Fields**
48
+
49
+ | Field | Required | Default | Notes |
50
+ |---|---|---|---|
51
+ | `direction` | no | `TB` | `TB` (top→bottom) or `LR` (left→right) — the layout rank direction |
52
+ | `nodes[].id` | **yes** | — | Unique; must not be `0` or `1` (reserved for draw.io root cells) |
53
+ | `nodes[].label` | no | the `id` | Display text; auto XML-escaped |
54
+ | `nodes[].style` | no | group colour, else blue | Any draw.io style string — reuse the role/shape styles from `diagram-types.md` and the active preset. A styleless node is tinted by its group (see **Containers / grouping**); an explicit style always wins |
55
+ | `nodes[].width` / `height` | no | `120` / `60` | Pixels; dot lays out at this real size |
56
+ | `nodes[].group` | no | none | Group key, or a `/`-delimited path (`"core/db"`) for **nested** containers — nodes sharing a path are boxed together (see **Containers / grouping**) |
57
+ | `nodes[].groupLabel` | no | last path segment | Title shown on the node's deepest container (first node with the path wins) |
58
+ | `edges[].source` / `target` | **yes** | — | Must match node ids |
59
+ | `edges[].label` | no | empty | Edge text |
60
+
61
+ ## How it places things
62
+
63
+ - Node positions come from `dot` (hierarchical layered layout), converted to draw.io pixels and snapped to the grid (multiples of 10).
64
+ - Edges use `splines=ortho`: dot's orthogonal route is replayed as draw.io waypoints, so edges go **around** nodes instead of through them.
65
+ - Apply the active style preset by setting each node's `style` to the preset's role/shape values before calling the script — the script does not know about presets.
66
+
67
+ ## Containers / grouping
68
+
69
+ Give nodes a `group` key and the script wraps each group in a labeled container (a dashed box with the group title at top) and tells dot to keep that group's nodes together via a Graphviz cluster. Grouped nodes become children of their container (`parent="<container>"`, relative coordinates); ungrouped nodes stay at the top level. This turns a flat hairball into a "boxes of related modules" architecture view.
70
+
71
+ **Nesting.** A `group` value with `/` separators builds nested containers: `"core/db"` puts the node inside a `db` box that itself sits inside a `core` box. Every path prefix becomes a container, so an arbitrarily deep package tree maps to nested boxes. A node can also sit *directly* in a parent box (`group: "core"`) alongside a sibling sub-box (`group: "core/db"`).
72
+
73
+ - **Colour by group.** Each top-level group is assigned a colour from the skill's own palette (`styles/built-in/default.json`, cycled in role order: blue → green → orange → purple → yellow → red → grey). A node with no `style` of its own is tinted with its group's colour, and the container's border + title match — so related modules read as a coloured cluster instead of monochrome boxes. A node that carries its own `style` (e.g. from an applied preset) is left untouched. Pass `--mono` to turn colouring off (dashed grey boxes, default-blue nodes — the previous look). Ungrouped graphs are unaffected.
74
+ - Each container box is the bounding box of its members and child boxes plus a uniform padding. The dot cluster margin is set to that same padding, so each box equals dot's cluster box — which dot keeps non-overlapping at **any nesting depth**.
75
+ - The title sits in the top padding (`verticalAlign=top`); the box title is the path's last segment, or a member's `groupLabel`.
76
+ - Containers are visual only (no edges of their own). Edges still connect node→node and route across containers normally.
77
+ - If a container's top padding would cross the page origin, the whole diagram is shifted so nothing lands at a negative coordinate.
78
+
79
+ ## Validate before previewing
80
+
81
+ `scripts/validate.py` is a deterministic structural linter — run it on the produced `.drawio` before the (slower, vision-based) self-check:
82
+
83
+ ```bash
84
+ python3 <this-skill-dir>/scripts/validate.py diagram.drawio
85
+ ```
86
+
87
+ It catches dangling edge endpoints, duplicate/reserved ids, broken parent references (errors), plus off-grid/negative geometry and overlapping sibling nodes (warnings) — without launching draw.io. Exit status is non-zero on any error (or any warning with `--strict`), so it can gate the workflow. Auto-layout output should always pass clean; a failure means a malformed input graph (e.g. an edge referencing a missing node id).
88
+
89
+ ## Importers — visualize code structure
90
+
91
+ Bundled importers turn a codebase into a graph JSON ready for autolayout, so "visualize this project" is a two-step pipeline:
92
+
93
+ | Language | Script | Node = | Edge = |
94
+ |---|---|---|---|
95
+ | Python | `scripts/pyimports.py <dir>` | module / package (`ast`) | intra-project `import` / `from` |
96
+ | JS / TS | `scripts/jsimports.py <dir>` | source file (`.ts/.tsx/.js/.jsx/.mjs/.cjs`) | resolved relative `import`/`export from`/`require()`/`import()` |
97
+ | Go | `scripts/goimports.py <dir>` | package (directory, via `go.mod`) | intra-module package import |
98
+ | Rust | `scripts/rustimports.py <dir>` | module (`.rs` file / `mod`) | intra-crate `use crate::` / `super::` / `self::` |
99
+ | Python (classes) | `scripts/pyclasses.py <dir>` | class (`ast`) | subclass → base (inheritance) |
100
+
101
+ ```bash
102
+ python3 <this-skill-dir>/scripts/pyimports.py myproject -o graph.json
103
+ python3 <this-skill-dir>/scripts/autolayout.py graph.json -o diagram.drawio
104
+ ```
105
+
106
+ Each keeps only **intra-project** edges (third-party/stdlib imports are ignored), shortens node labels (drops the shared package/module/directory prefix; ids stay fully qualified), and shares the same flags: `--direction TB|LR` (default `TB`), `--group`, `--no-reduce`.
107
+
108
+ - **Python** (`pyimports.py`): if the directory is itself a package (`__init__.py` present), module names are package-qualified so the project's own absolute imports resolve; nested subpackages (`pkg.sub.mod`) are handled.
109
+ - **JS/TS** (`jsimports.py`): resolution is path-based (tries the source extensions and directory `index` files); `node_modules` and bare specifiers are skipped. Scanning is regex-based, not a full parser.
110
+ - **Go** (`goimports.py`): reads the `module` path from `go.mod`; each directory of `.go` files is one package; `*_test.go` and `vendor/` are skipped.
111
+ - **Rust** (`rustimports.py`): each `.rs` file is a module (`mod.rs`/`main.rs`/`lib.rs` name the enclosing module); edges come from `use` paths rooted at `crate::`/`super::`/`self::` (brace groups expanded). `std`/external crates and `target/` are skipped. Regex-based — inline `mod { … }` blocks aren't split out, and 2015-edition bare intra-crate paths aren't resolved.
112
+ - **Python classes** (`pyclasses.py`): a finer granularity — one node per class, edges from each subclass to the project base classes it extends, so the result is an auto-generated class hierarchy. Bases are matched by name (preferring the same module); external bases (`object`, third-party) are ignored. With `--group`, classes are boxed by their module, so a deep package tree nests naturally. Inheritance only — function-level call graphs are out of scope (static call resolution in Python is unreliable).
113
+
114
+ **Density reduction is on by default** — this is the key to a readable result. Real import graphs are dense (asyncio: 33 modules / ~149 edges); without reduction they render as a hairball. Every importer applies **transitive reduction** (Graphviz `tred` — drops edges already implied by a longer path), which on asyncio cuts ~149 edges to ~46 and turns the hairball into a clean, traceable diagram. Pass `--no-reduce` to keep every edge.
115
+
116
+ **`--group`** assigns each node a container by its sub-package / directory path, so autolayout boxes related modules together — nested when the path has depth (see **Containers / grouping**). The fastest way to turn a large code graph into a tiered architecture view.
117
+
118
+ For any other language, produce the same graph JSON from any analyzer (e.g. `dependency-cruiser` for richer JS/TS resolution, `go-callvis` for Go call graphs) and feed it to autolayout the same way.
119
+
120
+ ## Limitations
121
+
122
+ - **Placement is topological, not semantic** — dot minimises edge crossings, which may put a node in a different column than you'd choose by hand. Re-export with the other `direction`, or hand-tune the produced XML afterwards (it's a normal `.drawio`).
123
+ - **Import edges are static** — `pyimports`/`jsimports`/`goimports` read static import statements (not dynamic `importlib`, runtime `require`, or reflection); `pyclasses` resolves inheritance only, not method-level calls.
124
+ - **Parallel edges** between the same `(source, target)` pair share one route.
125
+ - **Containers don't add edges** — `group`/nesting only boxes nodes for layout; edges remain node→node. For hand-built swimlane/architecture containers with their own connections, see SKILL.md "Containers and groups".
@@ -0,0 +1,83 @@
1
+ # Diagram Type Presets
2
+
3
+ When the user requests a specific diagram type, apply the matching preset below for shapes, styles, and layout conventions. These presets set **structural** style keywords (e.g. ERD's `shape=table;childLayout=tableLayout`); a user style preset (see `references/style-presets.md`) layers color/font/edge/extras on top.
4
+
5
+ Read this file when:
6
+ - The user names one of these diagram types (ERD, UML class, sequence, architecture, ML/DL model, flowchart)
7
+ - You're choosing shape vocabulary or layout direction for a new diagram
8
+
9
+ ## ERD (Entity-Relationship Diagram)
10
+
11
+ | Element | Style | Notes |
12
+ |---------|-------|-------|
13
+ | Table | `shape=table;startSize=30;container=1;collapsible=1;childLayout=tableLayout;fixedRows=1;rowLines=0;fontStyle=1;strokeColor=#6c8ebf;fillColor=#dae8fc;` | Each table is a container |
14
+ | Row (column) | `shape=tableRow;horizontal=0;startSize=0;swimlaneHead=0;swimlaneBody=0;fillColor=none;collapsible=0;dropTarget=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;fontSize=12;` | Child of table, `parent=tableId` |
15
+ | PK column | Bold text: `fontStyle=1` on the row | Mark with `PK` prefix or key icon |
16
+ | FK relationship | Dashed edge: `dashed=1;endArrow=ERmandOne;startArrow=ERmandOne;` | Use ER notation arrows |
17
+ | Layout | TB, tables spaced 300px apart | Group related tables vertically |
18
+
19
+ ## UML Class Diagram
20
+
21
+ | Element | Style | Notes |
22
+ |---------|-------|-------|
23
+ | Class box | `swimlane;fontStyle=1;align=center;startSize=26;html=1;` | 3-section: title / attributes / methods |
24
+ | Separator | `line;strokeWidth=1;fillColor=none;align=left;verticalAlign=middle;spacingTop=-1;spacingLeft=3;spacingRight=10;rotatable=0;labelPosition=left;points=[];portConstraint=eastwest;` | Between sections |
25
+ | Inheritance | `endArrow=block;endFill=0;` | Hollow triangle arrow |
26
+ | Implementation | `endArrow=block;endFill=0;dashed=1;` | Dashed + hollow triangle |
27
+ | Composition | `endArrow=diamondThin;endFill=1;` | Filled diamond |
28
+ | Aggregation | `endArrow=diamondThin;endFill=0;` | Hollow diamond |
29
+ | Layout | TB, classes 250px apart | Interfaces above implementations |
30
+
31
+ ## Sequence Diagram
32
+
33
+ | Element | Style | Notes |
34
+ |---------|-------|-------|
35
+ | Actor/Object | `shape=umlLifeline;perimeter=lifelinePerimeter;whiteSpace=wrap;html=1;container=1;collapsible=0;recursiveResize=0;outlineConnect=0;portConstraint=eastwest;` | Lifeline with dashed vertical line |
36
+ | Sync message | `html=1;verticalAlign=bottom;endArrow=block;` | Solid line, filled arrowhead |
37
+ | Async message | `html=1;verticalAlign=bottom;endArrow=open;dashed=1;` | Dashed line, open arrowhead |
38
+ | Return message | `html=1;verticalAlign=bottom;endArrow=open;dashed=1;strokeColor=#999999;` | Grey dashed |
39
+ | Activation box | `shape=umlFrame;whiteSpace=wrap;` on the lifeline | Narrow rectangle on lifeline |
40
+ | Layout | LR, lifelines spaced 200px apart | Time flows top to bottom |
41
+
42
+ ## Architecture Diagram
43
+
44
+ | Element | Style | Notes |
45
+ |---------|-------|-------|
46
+ | Layer/tier | `swimlane;startSize=30;` | Containers for grouping: Client / API / Service / Data |
47
+ | Service | `rounded=1;whiteSpace=wrap;html=1;` + tier color | Use color palette by tier |
48
+ | Database | `shape=cylinder3;whiteSpace=wrap;html=1;` | Green palette |
49
+ | Queue/Bus | `rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;` | Yellow — place centrally for hub pattern |
50
+ | Gateway/LB | `shape=mxgraph.aws4.resourceIcon;` or `rounded=1;` with orange | Orange palette |
51
+ | External | `rounded=1;dashed=1;fillColor=#f5f5f5;strokeColor=#666666;` | Dashed border for external systems |
52
+ | Layout | TB or LR by tier count; ≥4 tiers → TB | Hub nodes centered |
53
+
54
+ ## ML / Deep Learning Model Diagram
55
+
56
+ For neural network architecture diagrams — ideal for papers targeting NeurIPS, ICML, ICLR.
57
+
58
+ | Element | Style | Notes |
59
+ |---------|-------|-------|
60
+ | Layer block | `rounded=1;whiteSpace=wrap;html=1;` + type color | Main building block |
61
+ | Input/Output | `fillColor=#d5e8d4;strokeColor=#82b366;` | Green |
62
+ | Conv / Pooling | `fillColor=#dae8fc;strokeColor=#6c8ebf;` | Blue |
63
+ | Attention / Transformer | `fillColor=#e1d5e7;strokeColor=#9673a6;` | Purple |
64
+ | RNN / LSTM / GRU | `fillColor=#fff2cc;strokeColor=#d6b656;` | Yellow |
65
+ | FC / Linear | `fillColor=#ffe6cc;strokeColor=#d79b00;` | Orange |
66
+ | Loss / Activation | `fillColor=#f8cecc;strokeColor=#b85450;` | Red/Pink |
67
+ | Skip connection | `dashed=1;endArrow=block;curved=1;` | Dashed curved arrow |
68
+ | Tensor shape label | Add shape annotation as secondary label: `value="Conv2D&#xa;(B, 64, 32, 32)"` | Use `&#xa;` for multi-line |
69
+ | Layout | TB (data flows top→bottom), layers 150px apart | Group encoder/decoder as swimlanes |
70
+
71
+ **Tensor shape convention:** annotate each layer with input/output tensor dimensions in `(B, C, H, W)` or `(B, T, D)` format. Place dimensions as the second line of the label using `&#xa;`.
72
+
73
+ ## Flowchart (enhanced)
74
+
75
+ | Element | Style | Notes |
76
+ |---------|-------|-------|
77
+ | Start/End | `ellipse;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;` | Green oval |
78
+ | Process | `rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;` | Blue rectangle |
79
+ | Decision | `rhombus;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;` | Yellow diamond |
80
+ | I/O | `shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;` | Orange parallelogram |
81
+ | Subprocess | `rounded=0;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;` + double border | Purple |
82
+ | Yes/No labels | `value="Yes"` / `value="No"` on decision edges | Always label decision branches |
83
+ | Layout | TB, 200px vertical gap | Decisions branch LR, merge back to center |
@@ -0,0 +1,151 @@
1
+ # Shape vocabulary & search
2
+
3
+ Read this when a diagram needs a **specific shape** — a cloud-provider icon
4
+ (AWS/Azure/GCP), a network/Cisco/Kubernetes symbol, a UML/BPMN/ER element, an
5
+ electrical or P&ID part — or any time you'd otherwise *guess* a `style=` string.
6
+
7
+ There are two ways to get a style:
8
+
9
+ 1. **Search the official shape index** (`scripts/shapesearch.py`) — 10,446 real
10
+ draw.io palette shapes with their exact `style`, `w`, `h`. Use this for
11
+ branded/vendor icons and anything non-trivial. **Always prefer a searched
12
+ style over a hand-written `shape=mxgraph.*` guess** — guessed stencil names
13
+ silently render as a blank box if the name is wrong.
14
+ 2. **The cheatsheet below** — the common built-in shapes whose style strings are
15
+ short and stable enough to write by hand (rectangles, flowchart symbols,
16
+ UML primitives, containers, edges).
17
+
18
+ ## Searching shapes
19
+
20
+ ```bash
21
+ python3 <this-skill-dir>/scripts/shapesearch.py "aws lambda" --limit 5
22
+ python3 <this-skill-dir>/scripts/shapesearch.py "uml actor" --json
23
+ ```
24
+
25
+ - Query is space-separated keywords; matching is tag-based with Soundex
26
+ fuzziness and `camelCase`/`digit` splitting (`"pid2valve"` → `pid valve`).
27
+ - Prints each match as `Title (WxH)` followed by its full `style=` string. With
28
+ `--json`, emits `[{style,w,h,title}]` for programmatic use.
29
+ - Copy the `style` verbatim into an `mxCell`, and use the reported `w`/`h` as the
30
+ `mxGeometry` width/height (vendor icons are drawn at a fixed aspect ratio).
31
+ - Results are ranked by tag relevance, with shapes whose **title** contains the
32
+ query terms bubbled to the top of each score tier. Ranking is still a
33
+ heuristic, though, and many shapes share a title (three `Lambda` variants:
34
+ `aws3`/`aws4`/`aws3d`) — so run with `--limit 5` and pick the row whose title
35
+ and size match what you actually want rather than blindly taking #1.
36
+
37
+ ```xml
38
+ <mxCell id="2" value="Lambda" style="<paste the searched style here>" vertex="1" parent="1">
39
+ <mxGeometry x="40" y="40" width="78" height="78" as="geometry"/>
40
+ </mxCell>
41
+ ```
42
+
43
+ Covered libraries: AWS (`aws3`/`aws4`), Azure, GCP, Cisco, Kubernetes, UML,
44
+ BPMN, ER, electrical, P&ID, mockup/wireframe, flowchart, network, and the
45
+ general/basic sets. The bundled index (`data/shape-index.json.gz`) is the
46
+ upstream draw.io shape data — see `data/SHAPE-INDEX-NOTICE.md` for attribution.
47
+
48
+ ## AI / LLM brand logos
49
+
50
+ draw.io's bundled libraries have **no** modern AI/LLM brand logos, so an "LLM app
51
+ architecture" otherwise renders as generic boxes. `scripts/aiicons.py` resolves a
52
+ brand name (OpenAI, Claude, Gemini, Mistral, Llama, HuggingFace, Ollama,
53
+ LangChain, …321 brands) to a draw.io `image` style backed by the
54
+ [lobe-icons](https://github.com/lobehub/lobe-icons) set (MIT).
55
+
56
+ ```bash
57
+ python3 <this-skill-dir>/scripts/aiicons.py "claude" --json # CDN reference
58
+ python3 <this-skill-dir>/scripts/aiicons.py "openai" --embed # self-contained
59
+ python3 <this-skill-dir>/scripts/aiicons.py --list # all brands
60
+ ```
61
+
62
+ - Picks the `-color` variant when it exists, else the mono logo (e.g. OpenAI is
63
+ mono-only). Returns a square `image` style; use the reported `--size` (default
64
+ 48) for both width and height.
65
+ - **Default references the icon by CDN URL** — the SVG lives on unpkg, not in
66
+ this repo, so **draw.io needs network access when the diagram is rendered or
67
+ opened**; an offline export draws a blank box. Pass `--embed` to fetch the SVG
68
+ once and inline it as a data URI (portable, renders offline, larger XML).
69
+ - Logos are trademarks of their respective owners, referenced for identification
70
+ only — the same basis on which draw.io ships AWS/Azure icons.
71
+ - **Data stores** common in RAG/LLM apps that lobe lacks (Qdrant, Redis,
72
+ Postgres, Mongo, Elasticsearch, Milvus, Supabase, Neo4j, ClickHouse, Kafka,
73
+ Snowflake, Databricks, …) resolve via the [simple-icons](https://simpleicons.org)
74
+ CDN (CC0) as an automatic fallback — same command, same output shape. A brand
75
+ in neither set has no logo; use a cylinder (`shape=cylinder3;`, see below) or
76
+ `scripts/shapesearch.py "<name> database"`.
77
+
78
+ ## Cheatsheet — hand-writable styles
79
+
80
+ These are stable enough to write without searching. Combine with `whiteSpace=wrap;html=1;`.
81
+
82
+ ### Common shapes (`shape=` keyword)
83
+
84
+ | Need | style |
85
+ |---|---|
86
+ | Rectangle / rounded box | `rounded=0;` / `rounded=1;` |
87
+ | Circle / ellipse | `ellipse;` (`aspect=fixed;` for a true circle) |
88
+ | Diamond (decision) | `rhombus;` |
89
+ | Cylinder (database) | `shape=cylinder3;` |
90
+ | Cloud | `cloud;` |
91
+ | Cube (3D) | `shape=cube;` |
92
+ | Sticky note | `shape=note;` |
93
+ | Document (curled bottom) | `shape=document;` |
94
+ | Folder | `shape=folder;` |
95
+ | Card (cut corner) | `shape=card;` |
96
+ | Process (double border) | `shape=process;` |
97
+ | Step / chevron | `shape=step;` |
98
+ | Parallelogram (I/O) | `shape=parallelogram;perimeter=parallelogramPerimeter;` |
99
+ | Trapezoid | `shape=trapezoid;perimeter=trapezoidPerimeter;` |
100
+ | Hexagon | `shape=hexagon;perimeter=hexagonPerimeter2;` |
101
+ | Manual input | `shape=manualInput;` |
102
+ | Data storage | `shape=dataStorage;` |
103
+ | Off-page connector | `shape=offPageConnector;` |
104
+ | Delay | `shape=delay;` |
105
+ | OR / XOR gate | `shape=or;` / `shape=xor;` |
106
+ | Block arrow | `shape=singleArrow;` / `shape=doubleArrow;` |
107
+ | Callout (speech bubble) | `shape=callout;` |
108
+
109
+ ### UML primitives
110
+
111
+ | Element | style |
112
+ |---|---|
113
+ | Actor (stick figure) | `shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;` |
114
+ | Boundary | `shape=umlBoundary;` |
115
+ | Control | `shape=umlControl;` |
116
+ | Entity | `shape=umlEntity;` |
117
+ | Lifeline | `shape=umlLifeline;perimeter=lifelinePerimeter;container=1;` |
118
+ | Frame | `shape=umlFrame;` |
119
+ | Provided interface (lollipop) | `shape=lollipop;direction=south;` |
120
+ | Required interface | `shape=requires;direction=north;` |
121
+ | Component | `shape=component;` |
122
+
123
+ ### Containers (parent-child; children use relative coords)
124
+
125
+ | Type | style | When |
126
+ |---|---|---|
127
+ | Invisible group | `group;pointerEvents=0;` | No border, no own connections |
128
+ | Titled swimlane | `swimlane;startSize=30;` | Visible title bar / has connections |
129
+ | Any shape as container | append `container=1;pointerEvents=0;` | Box without own connections |
130
+
131
+ ### Edges
132
+
133
+ | Need | add to style |
134
+ |---|---|
135
+ | Orthogonal routing | `edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;` |
136
+ | Curved | `curved=1;` |
137
+ | No arrowhead | `endArrow=none;` |
138
+ | Open/thin arrow | `endArrow=open;` / `endArrow=classicThin;` |
139
+ | Dashed | `dashed=1;` (pattern via `dashPattern=8 8;`) |
140
+ | Flow animation | `flowAnimation=1;` |
141
+ | Label background | `labelBackgroundColor=#ffffff;` |
142
+
143
+ ### Useful property knobs
144
+
145
+ - `fontStyle` is a bitmask: `1`=bold, `2`=italic, `4`=underline (add to combine: `3`=bold+italic).
146
+ - `direction=north|south|east|west` rotates a shape in 90° steps; `rotation=<deg>` for free rotation.
147
+ - `gradientColor=#RRGGBB;` + `gradientDirection=north;` for a gradient fill.
148
+ - `sketch=1;` gives a hand-drawn look (set globally via a style preset instead when possible).
149
+
150
+ For richer per-shape detail, the upstream source is jgraph/drawio-mcp's
151
+ `shared/style-reference.md` (Apache-2.0).
@@ -0,0 +1,120 @@
1
+ # Style Application Guide
2
+
3
+ How to apply a visual style to a draw.io diagram generation.
4
+
5
+ ## Quick Reference: Style → Draw.io Tokens
6
+
7
+ When a style is selected, use these mappings to construct `mxCell` style strings:
8
+
9
+ ### Step 1: Determine Role → Color
10
+
11
+ For each node, determine its semantic role, then look up the `(fillColor, strokeColor)` pair
12
+ from the selected style reference file:
13
+
14
+ | Role | Style Reference Key | Example Use |
15
+ |------|---------------------|-------------|
16
+ | Service / component | `primary` | API service, microservice, worker |
17
+ | Database / storage | `success` | PostgreSQL, Redis, S3, vector store |
18
+ | Queue / message bus | `warning` | Kafka, RabbitMQ, SQS |
19
+ | Gateway / API / LB | `accent` | API Gateway, Load Balancer, Proxy |
20
+ | Error / alert | `danger` | Error handler, monitoring alert |
21
+ | Security / auth | `secondary` | OAuth service, IAM, Vault |
22
+ | External system | `neutral` | Third-party API, external service |
23
+
24
+ ### Step 2: Build Vertex Style String
25
+
26
+ Template:
27
+ ```
28
+ {shape_keyword};whiteSpace=wrap;html=1;fillColor={fillColor};strokeColor={strokeColor};strokeWidth={strokeWidth};fontFamily={fontFamily};fontSize={fontSize};fontColor={fontColor};{extras}
29
+ ```
30
+
31
+ Where each variable comes from the style reference:
32
+
33
+ | Variable | Style Reference Field |
34
+ |----------|----------------------|
35
+ | `shape_keyword` | "Shape Preferences" section (e.g., `rounded=1`) |
36
+ | `fillColor` | Role's fillColor from palette table |
37
+ | `strokeColor` | Role's strokeColor from palette table |
38
+ | `strokeWidth` | Extras section (default: 1.5) |
39
+ | `fontFamily` | Typography section |
40
+ | `fontSize` | Typography section (labels size) |
41
+ | `fontColor` | Typography section (primary text) |
42
+ | `extras` | Extras section (e.g., `glass=1;shadow=1;`) |
43
+
44
+ ### Step 3: Build Edge Style String
45
+
46
+ Template:
47
+ ```
48
+ edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;strokeColor={flowColor};strokeWidth={edgeWidth};{dashPattern};exitX={exitX};exitY={exitY};entryX={entryX};entryY={entryY};
49
+ ```
50
+
51
+ | Variable | Source |
52
+ |----------|--------|
53
+ | `flowColor` | Edge Style section, pick by flow type |
54
+ | `edgeWidth` | Edge Style section or infer from strokeWidth |
55
+ | `dashPattern` | `dashed=1` if flow type says dashed |
56
+ | `exitX/Y`, `entryX/Y` | Routing rules (see SKILL.md) |
57
+
58
+ ### Step 4: Set Page Background
59
+
60
+ For dark styles (2, 3, 5, 8), set the background on the mxGraphModel:
61
+
62
+ ```xml
63
+ <mxGraphModel background="#0f0f1a">
64
+ ```
65
+
66
+ For light styles (1, 4, 6, 7), use default or white:
67
+ ```xml
68
+ <mxGraphModel background="#ffffff">
69
+ ```
70
+
71
+ ## Style-Specific Notes
72
+
73
+ ### Style 1 (Flat Icon)
74
+ - Use `rounded=1` for all boxes
75
+ - Colorful palette — different fill for each role
76
+ - Default edge color: `#2563eb` (blue)
77
+ - Arrow semantics use different colors per flow type
78
+
79
+ ### Style 2 (Dark Terminal)
80
+ - Always set `background="#0f0f1a"`
81
+ - Use monospace font for all text
82
+ - Add `shadow=1` on primary (AI/ML) nodes
83
+ - Edge colors match source node's theme
84
+
85
+ ### Style 3 (Blueprint)
86
+ - Always set `background="#0a1628"`
87
+ - Use `rounded=0` (sharp corners)
88
+ - Monospace font, cyan-based text colors
89
+ - External nodes use `fillColor=none;dashed=1`
90
+
91
+ ### Style 4 (Notion Clean)
92
+ - All standard nodes share `fillColor=#f9fafb;strokeColor=#e5e7eb`
93
+ - Only error nodes get pink tint
94
+ - Single arrow color: `#3b82f6`
95
+ - Uppercase type labels at 11px
96
+
97
+ ### Style 5 (Glassmorphism)
98
+ - Always set `background="#0d1117"`
99
+ - Add `glass=1;shadow=1` to all vertex styles
100
+ - Edge colors match the source node's glow color bucket
101
+ - Semi-transparent look in draw.io
102
+
103
+ ### Style 6 (Claude Official)
104
+ - All nodes share `strokeColor=#4a4a4a;strokeWidth=2.5`
105
+ - Warm teal/beige/blue/gray fill colors per role
106
+ - Consistent `#5a5a5a` for all arrows
107
+ - Bold 16px labels with `fontStyle=1`
108
+
109
+ ### Style 7 (OpenAI Official)
110
+ - Almost all nodes: `fillColor=#ffffff;strokeColor=#e5e5e5`
111
+ - Thin borders: `strokeWidth=1.5`
112
+ - Color only in edges: `#10a37f` (green), `#71717a` (gray)
113
+ - No shadows, no decorations
114
+
115
+ ### Style 8 (Dark Luxury)
116
+ - Always set `background="#0a0a0a"`
117
+ - All nodes: `fillColor=#111111` with colored stroke per bucket
118
+ - Dual font: serif for titles, sans-serif for nodes
119
+ - Gold edges (`#d4a574`) for primary flows
120
+ - 6 semantic buckets with distinct stroke colors