agentic-mermaid 0.1.0 → 0.1.2

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 (333) hide show
  1. package/CHANGELOG.md +149 -4
  2. package/LICENSES/Apache-2.0.txt +202 -0
  3. package/README.md +25 -32
  4. package/THIRD_PARTY_NOTICES.md +29 -0
  5. package/assets/fonts/FONT-LICENSES.md +9 -5
  6. package/assets/fonts/Inter-Bold.ttf +0 -0
  7. package/assets/fonts/Inter-Medium.ttf +0 -0
  8. package/assets/fonts/Inter-Regular.ttf +0 -0
  9. package/assets/fonts/Inter-SemiBold.ttf +0 -0
  10. package/dist/agent-core.d.ts +463 -0
  11. package/dist/agent-core.js +397 -0
  12. package/dist/agent.d.ts +81 -1822
  13. package/dist/agent.js +336 -36839
  14. package/dist/agentic-mermaid-mcp.js +7 -37908
  15. package/dist/am.js +33638 -36261
  16. package/dist/chunk-4QECACIA.js +4702 -0
  17. package/dist/chunk-CDPKJ2BQ.js +37 -0
  18. package/dist/chunk-QKDLMOJJ.js +3487 -0
  19. package/dist/chunk-WI35L7IR.js +615 -0
  20. package/dist/chunk-WN3YDOBG.js +149 -0
  21. package/dist/chunk-ZYMMKQ3I.js +62637 -0
  22. package/dist/index-D54dqSdC.d.ts +6777 -0
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +310 -32836
  25. package/dist/mcp-cli-SBQSTJFC.js +17 -0
  26. package/docs/README.md +14 -6
  27. package/docs/schemas/style-spec.schema.json +1221 -30
  28. package/examples/styles/catalog.json +54 -0
  29. package/examples/styles/cloudflare-workers-inspired-prototype.mmd +9 -0
  30. package/examples/styles/cloudflare-workers-inspired-prototype.style.json +110 -0
  31. package/examples/styles/cupertino-prototype.mmd +10 -0
  32. package/examples/styles/cupertino-prototype.style.json +63 -0
  33. package/examples/styles/mid-century-report.style.json +2 -2
  34. package/examples/styles/star-chart-atlas.style.json +2 -1
  35. package/examples/styles/transit-route-map.style.json +2 -2
  36. package/examples/styles/vercel-inspired-prototype.mmd +6 -0
  37. package/examples/styles/vercel-inspired-prototype.style.json +87 -0
  38. package/package.json +70 -43
  39. package/server.json +41 -0
  40. package/skills/agentic-mermaid-diagram-workflow/SKILL.md +17 -36
  41. package/skills/agentic-mermaid-diagram-workflow/references/cli.md +4 -5
  42. package/skills/agentic-mermaid-diagram-workflow/references/code-mode.md +15 -31
  43. package/skills/agentic-mermaid-diagram-workflow/references/sequence.md +10 -14
  44. package/skills/agentic-mermaid-live-editor/SKILL.md +100 -206
  45. package/AGENT_NATIVE.md +0 -602
  46. package/Instructions_for_agents.md +0 -83
  47. package/TODO.md +0 -662
  48. package/assets/hero.png +0 -0
  49. package/dist/index-x2Cj1dVv.d.ts +0 -1089
  50. package/docs/agent-api-cookbook.md +0 -308
  51. package/docs/agent-mutation-policy.md +0 -104
  52. package/docs/agent-workflow-examples.md +0 -46
  53. package/docs/api.md +0 -203
  54. package/docs/ascii.md +0 -103
  55. package/docs/assets/improvements/box-start-connector.png +0 -0
  56. package/docs/assets/improvements/comment-dropped-lint.png +0 -0
  57. package/docs/assets/improvements/er-content-loss.png +0 -0
  58. package/docs/assets/improvements/fan-in-trunks.png +0 -0
  59. package/docs/assets/improvements/gantt-family.png +0 -0
  60. package/docs/assets/improvements/gantt-milestone-clamp.png +0 -0
  61. package/docs/assets/improvements/gantt-verify-seam.png +0 -0
  62. package/docs/assets/improvements/subgraph-container-edges.png +0 -0
  63. package/docs/assets/improvements/wrapper-frontmatter.png +0 -0
  64. package/docs/assets/improvements/wrapper-init-directive.png +0 -0
  65. package/docs/assets/improvements/wrapper-leading-comment.png +0 -0
  66. package/docs/assets/style-cookbook/mid-century-report.png +0 -0
  67. package/docs/assets/style-cookbook/star-chart-atlas.png +0 -0
  68. package/docs/assets/style-cookbook/transit-route-map.png +0 -0
  69. package/docs/comparison.md +0 -94
  70. package/docs/config.md +0 -105
  71. package/docs/contributing/adding-diagram-types.md +0 -144
  72. package/docs/contributing/diagram-family-citizenship.matrix.json +0 -2127
  73. package/docs/contributing/diagram-family-citizenship.md +0 -82
  74. package/docs/contributing/harvesting-upstream-tests.md +0 -126
  75. package/docs/contributing/lessons-learned.md +0 -276
  76. package/docs/contributing/releasing.md +0 -71
  77. package/docs/contributing/visual-review-evidence.md +0 -53
  78. package/docs/custom-style-cookbook.md +0 -154
  79. package/docs/design/families/README.md +0 -26
  80. package/docs/design/families/architecture-beta.md +0 -48
  81. package/docs/design/families/flowchart-parser-conformance.md +0 -22
  82. package/docs/design/families/gantt-research.md +0 -137
  83. package/docs/design/families/gantt.md +0 -329
  84. package/docs/design/families/journey-agentic-cards-before.png +0 -0
  85. package/docs/design/families/journey-mermaid-classic-implementation.png +0 -0
  86. package/docs/design/families/journey-mermaid-classic-prototype.png +0 -0
  87. package/docs/design/families/journey-mermaid-classic-prototype.svg +0 -163
  88. package/docs/design/families/journey-mermaid-classic-prototype.svg.png +0 -0
  89. package/docs/design/families/journey-migration-parity.md +0 -433
  90. package/docs/design/families/journey-usage-research.md +0 -423
  91. package/docs/design/families/journey.md +0 -125
  92. package/docs/design/families/xychart.md +0 -85
  93. package/docs/design/system/README.md +0 -45
  94. package/docs/design/system/abstraction-audit.md +0 -224
  95. package/docs/design/system/abstraction-recommendations.md +0 -655
  96. package/docs/design/system/architecture.mmd +0 -29
  97. package/docs/design/system/architecture.svg +0 -137
  98. package/docs/design/system/layout-guarantees-and-robustness.md +0 -351
  99. package/docs/design/system/layout-rubric.md +0 -138
  100. package/docs/design/system/route-contracts.md +0 -848
  101. package/docs/design/system/source-preservation-ladder.md +0 -52
  102. package/docs/design/system/styles-rollout.md +0 -216
  103. package/docs/design/system/ugly-layouts.md +0 -119
  104. package/docs/diagram-families.md +0 -193
  105. package/docs/features.md +0 -147
  106. package/docs/fork-differences.md +0 -130
  107. package/docs/getting-started.md +0 -175
  108. package/docs/issue-derived-test-cases.md +0 -156
  109. package/docs/layout-characterization/README.md +0 -245
  110. package/docs/layout-characterization/contact-sheet-families.md +0 -496
  111. package/docs/layout-characterization/contact-sheet.md +0 -638
  112. package/docs/layout-characterization/properties.md +0 -281
  113. package/docs/layout-characterization/visual-quality.md +0 -160
  114. package/docs/layout-characterization/visual-snapshots/architecture.svg +0 -79
  115. package/docs/layout-characterization/visual-snapshots/class.svg +0 -60
  116. package/docs/layout-characterization/visual-snapshots/er.svg +0 -61
  117. package/docs/layout-characterization/visual-snapshots/flowchart.svg +0 -58
  118. package/docs/layout-characterization/visual-snapshots/gantt.svg +0 -52
  119. package/docs/layout-characterization/visual-snapshots/journey.svg +0 -118
  120. package/docs/layout-characterization/visual-snapshots/pie.svg +0 -36
  121. package/docs/layout-characterization/visual-snapshots/quadrant.svg +0 -47
  122. package/docs/layout-characterization/visual-snapshots/sequence.svg +0 -59
  123. package/docs/layout-characterization/visual-snapshots/state.svg +0 -52
  124. package/docs/layout-characterization/visual-snapshots/timeline.svg +0 -64
  125. package/docs/layout-characterization/visual-snapshots/xychart.svg +0 -97
  126. package/docs/mcp-code-mode-rationale.md +0 -101
  127. package/docs/mcp-http-transport.md +0 -223
  128. package/docs/mermaid-layout-complaints.md +0 -837
  129. package/docs/mutation-testing.md +0 -206
  130. package/docs/project/divergences.md +0 -98
  131. package/docs/project/dogfooding-docs-strategy.md +0 -66
  132. package/docs/project/hosted-mcp-cloudflare-plan.md +0 -338
  133. package/docs/project/lessons-learned.md +0 -1019
  134. package/docs/project/remove-role-styling-plan.md +0 -176
  135. package/docs/quality.md +0 -212
  136. package/docs/react.md +0 -97
  137. package/docs/style-authoring.md +0 -133
  138. package/docs/testing-strategy.md +0 -335
  139. package/docs/theming.md +0 -162
  140. package/examples/agent-improve-auth-flow.ts +0 -206
  141. package/examples/agent-loop.ts +0 -53
  142. package/examples/mcp-vs-cli-complex-diagrams.ts +0 -133
  143. package/llms.txt +0 -104
  144. package/skill-evals/README.md +0 -77
  145. package/skill-evals/fixtures/architecture-cache/input.mmd +0 -5
  146. package/skill-evals/fixtures/class-payment/input.mmd +0 -4
  147. package/skill-evals/fixtures/er-orders/input.mmd +0 -10
  148. package/skill-evals/fixtures/flowchart-cache/input.mmd +0 -3
  149. package/skill-evals/fixtures/gantt-release/input.mmd +0 -7
  150. package/skill-evals/fixtures/journey-checkout/input.mmd +0 -6
  151. package/skill-evals/fixtures/pie-exports/input.mmd +0 -5
  152. package/skill-evals/fixtures/quadrant-priorities/input.mmd +0 -11
  153. package/skill-evals/fixtures/sequence-retry/input.mmd +0 -8
  154. package/skill-evals/fixtures/state-lifecycle/input.mmd +0 -5
  155. package/skill-evals/fixtures/timeline-release/input.mmd +0 -6
  156. package/skill-evals/fixtures/xychart-growth/input.mmd +0 -5
  157. package/skill-evals/shared-benchmark.json +0 -510
  158. package/src/agent/analyze.ts +0 -157
  159. package/src/agent/apply.ts +0 -146
  160. package/src/agent/architecture-body.ts +0 -458
  161. package/src/agent/certificates.ts +0 -110
  162. package/src/agent/class-body.ts +0 -319
  163. package/src/agent/core.ts +0 -207
  164. package/src/agent/create.ts +0 -106
  165. package/src/agent/describe.ts +0 -364
  166. package/src/agent/er-body.ts +0 -224
  167. package/src/agent/facts.ts +0 -337
  168. package/src/agent/families-builtin.ts +0 -934
  169. package/src/agent/families.ts +0 -232
  170. package/src/agent/family-layouts.ts +0 -826
  171. package/src/agent/flowchart-body.ts +0 -372
  172. package/src/agent/flowchart-unsupported.ts +0 -243
  173. package/src/agent/gantt-body.ts +0 -495
  174. package/src/agent/index.ts +0 -10
  175. package/src/agent/journey-body.ts +0 -414
  176. package/src/agent/label-metrics.ts +0 -28
  177. package/src/agent/layout-to-rendered.ts +0 -63
  178. package/src/agent/mutate.ts +0 -97
  179. package/src/agent/mutation-ops.ts +0 -51
  180. package/src/agent/op-schema.ts +0 -439
  181. package/src/agent/parse.ts +0 -223
  182. package/src/agent/pie-body.ts +0 -270
  183. package/src/agent/png.ts +0 -117
  184. package/src/agent/quadrant-body.ts +0 -336
  185. package/src/agent/quality.ts +0 -363
  186. package/src/agent/readability-audit.ts +0 -92
  187. package/src/agent/rendered-route-audit.ts +0 -61
  188. package/src/agent/sequence-body.ts +0 -345
  189. package/src/agent/serialize.ts +0 -214
  190. package/src/agent/state-body.ts +0 -589
  191. package/src/agent/structural-count.ts +0 -150
  192. package/src/agent/timeline-body.ts +0 -280
  193. package/src/agent/trace-log.ts +0 -43
  194. package/src/agent/types.ts +0 -979
  195. package/src/agent/verify.ts +0 -571
  196. package/src/agent/xychart-body.ts +0 -472
  197. package/src/architecture/config.ts +0 -282
  198. package/src/architecture/layout.ts +0 -496
  199. package/src/architecture/parser.ts +0 -375
  200. package/src/architecture/renderer.ts +0 -611
  201. package/src/architecture/types.ts +0 -113
  202. package/src/ascii/ansi.ts +0 -423
  203. package/src/ascii/architecture.ts +0 -210
  204. package/src/ascii/canvas.ts +0 -443
  205. package/src/ascii/class-diagram.ts +0 -697
  206. package/src/ascii/converter.ts +0 -475
  207. package/src/ascii/draw.ts +0 -1693
  208. package/src/ascii/edge-bundling.ts +0 -328
  209. package/src/ascii/edge-routing.ts +0 -330
  210. package/src/ascii/er-diagram.ts +0 -439
  211. package/src/ascii/gantt.ts +0 -276
  212. package/src/ascii/grid.ts +0 -747
  213. package/src/ascii/index.ts +0 -196
  214. package/src/ascii/journey.ts +0 -189
  215. package/src/ascii/meta.ts +0 -244
  216. package/src/ascii/multiline-utils.ts +0 -80
  217. package/src/ascii/pathfinder.ts +0 -301
  218. package/src/ascii/pie.ts +0 -67
  219. package/src/ascii/quadrant.ts +0 -158
  220. package/src/ascii/reverse.ts +0 -216
  221. package/src/ascii/sequence.ts +0 -499
  222. package/src/ascii/shapes/circle.ts +0 -27
  223. package/src/ascii/shapes/corners.ts +0 -143
  224. package/src/ascii/shapes/diamond.ts +0 -27
  225. package/src/ascii/shapes/hexagon.ts +0 -27
  226. package/src/ascii/shapes/index.ts +0 -106
  227. package/src/ascii/shapes/rectangle.ts +0 -168
  228. package/src/ascii/shapes/rounded.ts +0 -27
  229. package/src/ascii/shapes/special.ts +0 -332
  230. package/src/ascii/shapes/stadium.ts +0 -110
  231. package/src/ascii/shapes/state.ts +0 -192
  232. package/src/ascii/shapes/types.ts +0 -73
  233. package/src/ascii/timeline.ts +0 -128
  234. package/src/ascii/types.ts +0 -312
  235. package/src/ascii/validate.ts +0 -120
  236. package/src/ascii/width.ts +0 -81
  237. package/src/ascii/xychart.ts +0 -919
  238. package/src/browser.ts +0 -29
  239. package/src/class/layout.ts +0 -240
  240. package/src/class/parser.ts +0 -332
  241. package/src/class/renderer.ts +0 -638
  242. package/src/class/types.ts +0 -129
  243. package/src/cli/agent-instructions.ts +0 -1
  244. package/src/cli/am-bin.ts +0 -6
  245. package/src/cli/exit-codes.ts +0 -18
  246. package/src/cli/index.ts +0 -1117
  247. package/src/cli/init-agent.ts +0 -147
  248. package/src/color-resolver.ts +0 -152
  249. package/src/elk-instance.ts +0 -114
  250. package/src/er/layout.ts +0 -187
  251. package/src/er/parser.ts +0 -226
  252. package/src/er/renderer.ts +0 -792
  253. package/src/er/types.ts +0 -99
  254. package/src/font-manifest.ts +0 -27
  255. package/src/gantt/layout.ts +0 -365
  256. package/src/gantt/parser.ts +0 -282
  257. package/src/gantt/pipeline.ts +0 -27
  258. package/src/gantt/renderer.ts +0 -414
  259. package/src/gantt/schedule.ts +0 -513
  260. package/src/gantt/types.ts +0 -255
  261. package/src/index.ts +0 -368
  262. package/src/journey/layout.ts +0 -520
  263. package/src/journey/parser.ts +0 -218
  264. package/src/journey/renderer.ts +0 -811
  265. package/src/journey/types.ts +0 -144
  266. package/src/layout/geometry.ts +0 -182
  267. package/src/layout/pass.ts +0 -142
  268. package/src/layout/passes/index.ts +0 -3916
  269. package/src/layout-engine.ts +0 -1565
  270. package/src/layout-rubric.ts +0 -659
  271. package/src/mcp/artifacts.ts +0 -137
  272. package/src/mcp/dynamic-harness.ts +0 -31
  273. package/src/mcp/dynamic-modules.d.ts +0 -7
  274. package/src/mcp/facade.ts +0 -608
  275. package/src/mcp/harness-runtime.ts +0 -203
  276. package/src/mcp/hosted-server.ts +0 -468
  277. package/src/mcp/mcp-bin.ts +0 -3
  278. package/src/mcp/mcp-cli.ts +0 -82
  279. package/src/mcp/protocol.ts +0 -13
  280. package/src/mcp/sandbox.ts +0 -195
  281. package/src/mcp/sdk-decl.ts +0 -387
  282. package/src/mcp/server.ts +0 -362
  283. package/src/mcp/tool-surface.ts +0 -146
  284. package/src/mermaid-source.ts +0 -655
  285. package/src/multiline-utils.ts +0 -228
  286. package/src/parser.ts +0 -1031
  287. package/src/pie/layout.ts +0 -168
  288. package/src/pie/parser.ts +0 -136
  289. package/src/pie/renderer.ts +0 -234
  290. package/src/pie/types.ts +0 -82
  291. package/src/quadrant/layout.ts +0 -191
  292. package/src/quadrant/parser.ts +0 -183
  293. package/src/quadrant/renderer.ts +0 -322
  294. package/src/quadrant/types.ts +0 -113
  295. package/src/render-family-hooks.ts +0 -244
  296. package/src/renderer.ts +0 -1099
  297. package/src/route-contracts.ts +0 -2723
  298. package/src/scene/backend.ts +0 -76
  299. package/src/scene/fidelity.ts +0 -183
  300. package/src/scene/hybrid-backend.ts +0 -174
  301. package/src/scene/ir.ts +0 -181
  302. package/src/scene/marks.ts +0 -127
  303. package/src/scene/rough-backend.ts +0 -378
  304. package/src/scene/seed.ts +0 -46
  305. package/src/scene/style-registry.ts +0 -556
  306. package/src/sequence/layout.ts +0 -456
  307. package/src/sequence/parser.ts +0 -255
  308. package/src/sequence/renderer.ts +0 -604
  309. package/src/sequence/types.ts +0 -154
  310. package/src/shape-clipping.ts +0 -351
  311. package/src/shared/accessibility-directives.ts +0 -22
  312. package/src/shared/batched.ts +0 -61
  313. package/src/shared/color-math.ts +0 -72
  314. package/src/shared/svg-a11y.ts +0 -29
  315. package/src/shared/syntax-error.ts +0 -17
  316. package/src/shared/unicode-ranges.ts +0 -135
  317. package/src/styles.ts +0 -318
  318. package/src/svg-paths.ts +0 -28
  319. package/src/text-metrics.ts +0 -248
  320. package/src/theme.ts +0 -639
  321. package/src/timeline/layout.ts +0 -381
  322. package/src/timeline/parser.ts +0 -215
  323. package/src/timeline/renderer.ts +0 -538
  324. package/src/timeline/types.ts +0 -105
  325. package/src/types.ts +0 -454
  326. package/src/website-worker-modules.d.ts +0 -18
  327. package/src/xychart/axis-utils.ts +0 -109
  328. package/src/xychart/colors.ts +0 -124
  329. package/src/xychart/config.ts +0 -88
  330. package/src/xychart/layout.ts +0 -656
  331. package/src/xychart/parser.ts +0 -504
  332. package/src/xychart/renderer.ts +0 -640
  333. package/src/xychart/types.ts +0 -282
@@ -1,837 +0,0 @@
1
- # Mermaid layout complaints: catalog, root causes, and coverage
2
-
3
- This document maps what users actually complain about in Mermaid's layout →
4
- why those failures happen → which Agentic Mermaid work addresses each one
5
- (landed, specced, or deliberately out of scope). It is the durable version of
6
- a June 2026 research pass and should be updated when complaint-relevant work
7
- lands.
8
-
9
- Companions:
10
-
11
- - [`issue-derived-test-cases.md`](./issue-derived-test-cases.md) — fixture-level
12
- coverage map for specific upstream issues.
13
- - [`quality.md`](./quality.md) — the project's definition of "good looking" and
14
- its metric gates.
15
- - [Issue #25](https://github.com/adewale/agentic-mermaid/issues/25) and
16
- [issue #26](https://github.com/adewale/agentic-mermaid/issues/26) — the
17
- principled routing/contract specs that several entries below point into.
18
- - [PR #24](https://github.com/adewale/agentic-mermaid/pull/24) — the Gantt
19
- spec and implementation, the model for chart-family layout contracts.
20
- - [Issue #41](https://github.com/adewale/agentic-mermaid/issues/41) — the
21
- diagram-family citizenship matrix that now keeps supported families honest
22
- about parser, serializer, renderer, verifier, and test obligations.
23
-
24
- Method: complaint evidence was gathered in June 2026 from the
25
- `mermaid-js/mermaid` tracker (reaction counts "R" are as of that date), Hacker
26
- News, Reddit, comparison blogs, and Mermaid's own documentation. Root-cause
27
- evidence comes from the graph-drawing literature, competing products'
28
- documentation, diagram interchange standards, and the recorded history of the
29
- three codebases this project descends from (Mermaid, `mermaid-ascii`,
30
- `beautiful-mermaid`).
31
-
32
- Status legend used below:
33
-
34
- | Status | Meaning |
35
- |---|---|
36
- | **landed** | shipped in this repo with tests |
37
- | **partial** | some of the complaint class is covered, the rest is not |
38
- | **specced** | designed in #25/#26/PR #24 with acceptance criteria, not implemented |
39
- | **out of scope** | deliberately not addressed; the reason is stated |
40
-
41
- ---
42
-
43
- ## Part 1 — The complaint catalog
44
-
45
- Thirteen recurring complaint classes, ordered roughly by loudness. Each entry
46
- names its root causes (`R1`–`R5`, defined in Part 2) and its fixture/test
47
- coverage in this repo.
48
-
49
- ### C1. No manual positioning
50
-
51
- Mermaid is auto-layout only: no coordinates, no pinning, no post-hoc nudge.
52
- When the engine makes a bad call, the sanctioned workaround is invisible
53
- `~~~` links — Mermaid's own docs describe them as the way "to alter the
54
- default positioning of a node," and GitLab maintains a handbook page of such
55
- tricks. This is the loudest and oldest theme.
56
-
57
- - Evidence: [mermaid#270](https://github.com/mermaid-js/mermaid/issues/270)
58
- (11R, open since 2016),
59
- [mermaid#2483](https://github.com/mermaid-js/mermaid/issues/2483) (12R),
60
- [mermaid#5420 "Add positioning for elk layout renderer"](https://github.com/mermaid-js/mermaid/issues/5420)
61
- (47R, zero comments — pure demand). HN: "if you don't like the way the
62
- diagram is visually laid out there's not really an easy way to change it"
63
- ([41262756](https://news.ycombinator.com/item?id=41262756)).
64
- - Root cause: R3 (missing control surface).
65
- - Status here: **out of scope, by policy.** Issue #25 (open question 2)
66
- recommends against route/position hints: "Keep route intent inferred from
67
- semantics and author order unless Mermaid core standardizes hints," and
68
- syntax invention is a stated non-goal. The substitute is actuation through
69
- the agent loop: deterministic layout (`measureQuality`, `checkQuality`,
70
- `eval/layout-compare/`) makes bad layout *detectable*, typed mutation makes
71
- source restructuring cheap, and #25's route certificates would make
72
- detours *explained* — so a program can iterate where a human would drag a
73
- node. This substitutes for manual positioning; it does not provide it.
74
-
75
- ### C2. Layout collapses at scale
76
-
77
- Past roughly 20–50 nodes: whitespace oceans, extreme aspect ratios, nodes
78
- unreadably small once the diagram is fit to screen.
79
-
80
- - Evidence: [mermaid#1984 "Massive whitespace"](https://github.com/mermaid-js/mermaid/issues/1984)
81
- (39R, open since 2021),
82
- [mermaid#3262](https://github.com/mermaid-js/mermaid/issues/3262),
83
- [mermaid#2807 "ER graphs tend to get REALLY wide"](https://github.com/mermaid-js/mermaid/issues/2807)
84
- (19R). HN: "more and more acres of white space"
85
- ([30781954](https://news.ycombinator.com/item?id=30781954)).
86
- - Root cause: R1 (layered-algorithm sprawl), aggravated in Mermaid by R4
87
- (dagre, fixed spacing constants).
88
- - Fixture/test: `whitespaceBalance` (5–55% band) and `aspectRatio` (0.2–5.0
89
- band) in `src/agent/quality.ts` flag both failure directions;
90
- `eval/layout-compare/` reports deltas corpus-wide. Generated 20/50/100-node
91
- flowchart corpora now assert finite aspect ratios and non-degenerate
92
- whitespace in `src/__tests__/agent-quality.test.ts`.
93
- - Status here: **partial — detection only.** Nothing in the backlog improves
94
- large-graph compaction, and the source-order priority can *worsen* width:
95
- `docs/quality.md` documents the Auth Flow trade, and
96
- `src/__tests__/agent-auth-flow.test.ts` pins quality with a widened aspect
97
- band (`[0.2, 7]`) for exactly that reason. One candidate mitigation that
98
- needs no syntax invention: the standards-era answer to oversized charts
99
- was never better compaction but **decomposition** — ANSI X3.5/ISO 5807
100
- prescribe named on-page/off-page connectors to split a chart when it
101
- outgrows a page or lines would cross. The agent-loop analogue: when
102
- `checkQuality` flags an oversized diagram, propose or perform splitting
103
- into multiple linked diagrams through the existing mutation API. Mermaid
104
- has no continuation concept (users fake it with duplicated nodes), so
105
- this would be a differentiator rather than a compatibility surface.
106
-
107
- ### C3. Subgraphs: direction ignored, titles overlapped, clusters colliding
108
-
109
- The most-reacted pure layout bug in Mermaid's tracker. `direction` inside a
110
- subgraph is silently ignored the moment any inner node links outside —
111
- documented as a limitation, unfixed since 2021. Titles get covered by nodes;
112
- sibling clusters overlap.
113
-
114
- - Evidence: [mermaid#2509](https://github.com/mermaid-js/mermaid/issues/2509)
115
- (189R, 50 comments),
116
- [mermaid#3806 title overlap](https://github.com/mermaid-js/mermaid/issues/3806)
117
- (54R), [mermaid#4990 cluster overlap](https://github.com/mermaid-js/mermaid/issues/4990)
118
- (32R), [mermaid#287](https://github.com/mermaid-js/mermaid/issues/287) (29R).
119
- - Root cause: R1 (compound layout is genuinely hard), R4 (dagre's cluster
120
- support is weak; title boxes not reserved during layout).
121
- - Fixture/test: `src/__tests__/subgraph-direction.test.ts` pins SVG geometry
122
- for `direction TB` inside an LR flowchart *with an external link to an
123
- inner node* — the exact mermaid#2509 case — plus ASCII one-row inner LR
124
- layout, and container edges attaching to the subgraph border without
125
- phantom node boxes (BUILD-14), in both Unicode and 7-bit ASCII, nested,
126
- labeled/styled, and multi-edge variants. Group titles reserve layout space
127
- via the header-aware `elk.padding` in `src/layout-engine.ts`; breaches are
128
- a Tier 1 `GROUP_BREACH` warning.
129
- - Status here: **landed** (PRs #17, #21, #22). Residual: cross-hierarchy and
130
- container-edge *route classes* — making the SVG router treat boundary
131
- edges semantically rather than via representative children — are specced
132
- (#25 §8.3, #26 workstream 2).
133
-
134
- ### C4. Erratic edge routing: avoidable crossings, overlaps, doglegs
135
-
136
- Edges cross when they obviously need not, overlap each other or pass through
137
- nodes, and acquire small unexplained doglegs ("hitches"). Users untangle by
138
- trial-and-error reordering of source lines.
139
-
140
- - Evidence: [mermaid#6476 "Unnecessary crossing"](https://github.com/mermaid-js/mermaid/issues/6476),
141
- [mermaid#5601 planar graphs rendered non-planar](https://github.com/mermaid-js/mermaid/issues/5601),
142
- [mermaid#1006](https://github.com/mermaid-js/mermaid/issues/1006) ("it often
143
- really handles edges in an erradic way" — closed *Wont Fix*),
144
- [mermaid#5060](https://github.com/mermaid-js/mermaid/issues/5060),
145
- [mermaid#2792 edges overlap boxes](https://github.com/mermaid-js/mermaid/issues/2792).
146
- - Root cause: R1 (crossing minimization is NP-hard, solved per-layer by
147
- heuristic; routing is a late phase that cannot revisit placement), R4
148
- (dagre routes splines without obstacle avoidance), R5 (post-layout passes
149
- move geometry without rerouting).
150
- - Fixture/test: the worked example is issue #25's login/MFA flow. Rendered
151
- with the current engine (June 2026, ASCII):
152
-
153
- ```
154
- | User |---->| Login Page |<No->| Valid Credentials? |-Yes>| MFA Enabled? |----No-->| Create Session | Yes-+--| Code Valid? |
155
- ... | +-----No-------+ |
156
- ... +------Yes------>| Enter MFA Code |----------------+
157
- ```
158
-
159
- `F --> G` (`Code Valid?` → `Create Session`) runs backwards; the `No`
160
- feedback loops read ambiguously inline. Yet `verifyMermaid` returns
161
- `ok: true` with zero warnings, and every perceptual metric passes except
162
- aspect ratio (6.23 vs the 5.0 band): `edgeCrossings: 0`,
163
- `labelLegibility: 1`. That is the measured gap between today's generic
164
- metrics and the visible failure — the gap #25/#26 exist to close.
165
- Current coverage: `edgeCrossings` gate (≤5% of edge pairs),
166
- `ROUTE_SELF_CROSS` Tier 2 warning, edge-vs-node collision heuristics in
167
- `src/__tests__/layout-quality-heuristics.test.ts`, deterministic FIFO A*
168
- tie-breaking in the ASCII pathfinder
169
- (`src/__tests__/ascii-pathfinder-determinism.test.ts`).
170
- - Status here: **partial today, with the route-contract core landed and the
171
- broader program still specced.** #25 defines route classes
172
- (`primary-forward`/`feedback`/fan trunks/…), the straight-primary and
173
- hitch invariants (§11.1–11.2), the certifying simplifier (§12), and the
174
- hard rule "no node-coordinate mutation after route extraction unless all
175
- incident routes are rerouted or recertified" (§9). The current tests now
176
- include route-certificate geometry and property coverage across dotted,
177
- thick, bidirectional, marker, and labeled edge forms. Remaining work lives
178
- in the still-open route/port issues (#32, #35, #38 and the #26 umbrella),
179
- plus cross-renderer adoption.
180
-
181
- ### C5. Edge labels overlap edges, nodes, and each other
182
-
183
- Mermaid places labels at edge midpoints with no collision handling: labels
184
- sit on other edges, get struck through by their own line, or detach from the
185
- edge they describe.
186
-
187
- - Evidence: [mermaid#490](https://github.com/mermaid-js/mermaid/issues/490)
188
- (2017 — labels struck through by their own edge, asking for "integrated
189
- logic which tries to avoid lines going over the texts": literally the
190
- integrated-labeling concept yFiles ships, see R3),
191
- [mermaid#2131 mis-aligned state labels](https://github.com/mermaid-js/mermaid/issues/2131),
192
- [mermaid#2525 "messages appear with line through them"](https://github.com/mermaid-js/mermaid/issues/2525),
193
- [mermaid#7492 C4 label/text/arrow chaos](https://github.com/mermaid-js/mermaid/issues/7492),
194
- [mermaid#1233](https://github.com/mermaid-js/mermaid/issues/1233).
195
- - Root cause: R1 (label placement is NP-hard and classically solved *after*
196
- layout; dagre models labels as mid-edge dummy nodes), R4/R5 (renderers do
197
- not collision-check label boxes afterwards).
198
- - Fixture/test: this engine passes edge labels into layout as first-class
199
- inline ELK labels (`elk.edgeLabels.inline: 'true'`,
200
- `src/layout-engine.ts`), so they reserve space instead of being overlaid;
201
- `labelEdgeProximity` (≥4px to any non-attached node, other edge-label
202
- box, or other edge path) gates regressions in the graph families, and the
203
- 2026-07 overlap audit added a cross-family occlusion gate
204
- (`eval/overlap-audit` + `label-overlap-gate.test.ts`: curated corpus at
205
- zero label/box overlap findings, per-family fuzz ratchets) after finding
206
- label collisions the proximity metric alone had missed in five families.
207
- ASCII branch labels are pinned to sibling branch segments, not shared
208
- trunks: `src/__tests__/ascii-fanout-trunk-labeled.test.ts`,
209
- `ascii-pathfinder-trunk.test.ts`, plus exact goldens under
210
- `src/__tests__/testdata/{ascii,unicode}/`.
211
- - Status here: **partial.** Landed: label-aware layout + proximity gate +
212
- ASCII branch-label placement. Specced: the label invariant (#25 §11.4 —
213
- labels are obstacles *and* capacity constraints; trunks may not host
214
- per-sibling labels) and label-capacity checks before straightening (§12).
215
-
216
- ### C6. No rank/order control; tiny edits reshuffle the diagram
217
-
218
- Users cannot say "these two nodes at the same level" or "keep my declared
219
- order," and adding one edge can scramble a previously good layout — which
220
- also makes diagrams churn across edits.
221
-
222
- - Evidence: [mermaid#3723 same-rank request](https://github.com/mermaid-js/mermaid/issues/3723)
223
- (86R — the most-upvoted open layout-control ask),
224
- [mermaid#815 "Maintain the order of the nodes"](https://github.com/mermaid-js/mermaid/issues/815)
225
- (45R), [mermaid#2834](https://github.com/mermaid-js/mermaid/issues/2834),
226
- [mermaid#6527 "flowchart-elk … reshuffled every time you add a node"](https://github.com/mermaid-js/mermaid/issues/6527).
227
- - Root cause: R3 (no constraint surface) over R1 (layered layouts are
228
- input-order sensitive unless order is made an explicit objective).
229
- - Fixture/test: source order *is* the constraint surface here:
230
- `elk.layered.considerModelOrder.strategy: NODES_AND_EDGES`,
231
- `cycleBreaking.strategy: MODEL_ORDER`, and
232
- `crossingMinimization.forceNodeModelOrder: true`
233
- (`src/layout-engine.ts`) make author order the layout's primary input.
234
- `src/__tests__/agent-auth-flow.test.ts` asserts the primary LR chain stays
235
- in source order (`A < B < … < H` by x-center) and feedback edges route
236
- backwards — the mermaid#5227 "backwards arrows" class. Edit stability is
237
- the determinism guarantee plus typed mutation: a one-op change re-lays-out
238
- as a pure function of the new source
239
- (`src/__tests__/agent-determinism.test.ts`). The same file now pins
240
- edit-stability for small source mutations: label edits, inserted nodes,
241
- appended leaves, style-only changes, and feedback-edge additions must
242
- preserve the left-to-right order of the unchanged primary chain.
243
- - Status here: **partial.** Landed: deterministic source-order layout (the
244
- practical answer to #815/#6527). Not offered: an explicit same-rank
245
- constraint (#3723's literal ask) — that is C1's policy decision again.
246
- Graphviz has had `rank=same` since the 1990s (see R3); if Mermaid core
247
- ever standardizes an equivalent, this fork's policy is to follow, not
248
- invent.
249
-
250
- ### C7. "It's just ugly": dated default aesthetics
251
-
252
- An aesthetic judgment independent of geometric correctness: default colors,
253
- shapes, curves, and contrast read as dated next to D2 or hand-drawn
254
- diagrams; some embeddings are unreadable (dark-theme contrast).
255
-
256
- - Evidence: HN "why does it have to be so ugly"
257
- ([30339032](https://news.ycombinator.com/item?id=30339032)); "Both PlantUML
258
- and Mermaid mostly produce (Mermaid more) ugly-looking diagrams"
259
- ([33704875](https://news.ycombinator.com/item?id=33704875));
260
- [Cursor forum on unreadable contrast](https://forum.cursor.com/t/mermaid-diagrams-are-hard-to-read-poor-contrast/153850).
261
- - Root cause: R5 (renderer/theming defaults, not the layout algorithm).
262
- Mermaid's v11 `handDrawn`/`neo` "looks" are its own remediation.
263
- - Fixture/test: inherited from upstream Beautiful Mermaid: two-color theme
264
- derivation, 21 built-in themes, Shiki/VS Code theme compatibility. Fork
265
- additions: Style + Palette stacks, Tufte/Salmon theme families (PR #10),
266
- auto-contrast on custom fills
267
- (upstream #115 class) pinned by
268
- `src/__tests__/renderer-contrast.test.ts`.
269
- - Status here: **landed** (largely upstream's credit; see
270
- [`comparison.md`](./comparison.md)).
271
-
272
- ### C8. Text clipped, overflowing, or hand-wrapped
273
-
274
- Node boxes don't reliably fit their text. In Mermaid the classic causes are
275
- HTML labels in `foreignObject` (SVG exports drop them), browser font metrics
276
- at layout time, and no width budget for CJK/long words.
277
-
278
- - Evidence: [mermaid#58](https://github.com/mermaid-js/mermaid/issues/58)
279
- ("Generated SVG works poorly outside web browsers" — opened December
280
- 2014, six weeks after Mermaid's first release, still open),
281
- [mermaid#2688 foreignObject](https://github.com/mermaid-js/mermaid/issues/2688)
282
- (24R), [mermaid#790](https://github.com/mermaid-js/mermaid/issues/790),
283
- [mermaid#4918](https://github.com/mermaid-js/mermaid/issues/4918),
284
- [mermaid#7359 Korean clipped on export](https://github.com/mermaid-js/mermaid/issues/7359);
285
- GitLab converted diagrams to tables rather than fight it
286
- ([gitlab#583608](https://gitlab.com/gitlab-org/gitlab/-/issues/583608)).
287
- - Root cause: R5 (browser-first text pipeline), R2 for the ASCII lineage
288
- (`string.length` width assumptions on fullwidth text).
289
- - Fixture/test: structurally avoided here — text is plain SVG `<text>`
290
- measured by deterministic metrics (`src/text-metrics.ts`), never
291
- `foreignObject`; PNG embeds pinned fonts (DejaVu default plus the built-in style faces) so rasterization cannot
292
- font-substitute. Guards: Tier 1 `LABEL_OVERFLOW`, `labelLegibility` ≥85%
293
- gate, CJK fullwidth handling
294
- (`src/__tests__/ascii-cjk-width.test.ts`, upstream #119 class), ER/class
295
- label truncation fixes with exact goldens (upstream #121 class,
296
- `er-integration.test.ts`, `class-integration.test.ts`).
297
- - Status here: **landed**, with an honest gap: the 7px/char SVG heuristic is
298
- approximate (`docs/quality.md`), and the shared text-measurement contract
299
- that would unify SVG/ASCII/quality measurement (CJK, emoji, ambiguous
300
- width) is specced as #26 workstream 8. Regression coverage now includes
301
- emoji-presentation selectors and East Asian ambiguous-width symbols, so
302
- common Unicode labels cannot silently drift between SVG metrics and
303
- terminal-width assumptions.
304
-
305
- ### C9. Stuck on dagre; ELK bolted on as an escape hatch
306
-
307
- The meta-complaint: Mermaid's default engine is dagre — widely described as
308
- abandoned — and the community's fix (ELK) is opt-in, a separate package,
309
- unavailable in GitHub's native rendering, and not itself a cure-all.
310
-
311
- - Evidence: "Dagre is pretty good but I think ELK is better and Dagre has
312
- been abandoned"
313
- ([r/programming](https://www.reddit.com/r/programming/comments/z1qoxc/d2_is_now_open_source_a_new_modern_language_that/ixlwqce/));
314
- Mermaid docs: "The elk renderer is better for larger and/or more complex
315
- diagrams" ([flowchart docs](https://mermaid.js.org/syntax/flowchart.html));
316
- HN: "the layout renderer is pretty bad … the layout algorithm is so bad"
317
- ([41277795](https://news.ycombinator.com/item?id=41277795)).
318
- - Root cause: R4.
319
- - Status here: **landed structurally.** ELK layered is this engine's only
320
- graph layout (synchronous bundled `elkjs`, `src/elk-instance.ts`), with
321
- pinned options (`src/layout-engine.ts`) and #25 §10 as the documented
322
- option policy — node placement is Brandes–Köpf, the same default
323
- Mermaid's own ELK package exposes via `nodePlacementStrategy`, so
324
- opting into `flowchart-elk` in Mermaid lands on the placement family this
325
- engine uses by default. Two honest caveats: (1) ELK is not a panacea — upstream
326
- #83 (TD flowcharts flipping horizontal) was *ELK cycle-breaking* behavior,
327
- countered here by model-order options; (2) none of this changes what
328
- GitHub/GitLab render natively (see Part 4).
329
-
330
- ### C10. Self-loops and back-edges render awkwardly
331
-
332
- A node linking to itself draws a kinked doubled-back path; loops in flows
333
- take long unexplained detours.
334
-
335
- - Evidence: [mermaid#6336](https://github.com/mermaid-js/mermaid/issues/6336)
336
- (31R; the issue contrasts Graphviz doing it "So much more natural"),
337
- [mermaid#6049](https://github.com/mermaid-js/mermaid/issues/6049) (11R —
338
- also a version regression: "pretty" in 11.0.2, "Ugly since 11.1.1").
339
- - Root cause: R1/R4 (layered frameworks have no native self-loop concept;
340
- the route is synthesized late).
341
- - Fixture/test: ASCII self-loops currently render compactly (verified June
342
- 2026: `B --> B` draws a tight two-cell side loop). `ROUTE_SELF_CROSS`
343
- (Tier 2) and self-loop clearance heuristics
344
- (`layout-quality-heuristics.test.ts`) guard regressions. SVG self-loop
345
- port policy (N/S side by clearance) is #25 §8.1; mermaid#6049 is listed as
346
- a future fixture in [`issue-derived-test-cases.md`](./issue-derived-test-cases.md).
347
- - Status here: **partial** (ASCII decent + guarded; SVG semantics specced).
348
-
349
- ### C11. Unstable output across versions and renderers
350
-
351
- The same source renders differently in the live editor, CLI, GitHub, and
352
- Obsidian, and upgrades silently regress committed diagrams.
353
-
354
- - Evidence: [mermaid#5813 v11 regression](https://github.com/mermaid-js/mermaid/issues/5813)
355
- (28R), [mermaid#1485 live editor vs CLI](https://github.com/mermaid-js/mermaid/issues/1485),
356
- [mermaid#5969 editor silently uses ELK](https://github.com/mermaid-js/mermaid/issues/5969),
357
- [gitlab#583608](https://gitlab.com/gitlab-org/gitlab/-/issues/583608),
358
- [Obsidian forum "Mermaid arrows are a mess"](https://forum.obsidian.md/t/mermaid-arrows-are-a-mess/104633).
359
- - Root cause: R5 (browser/CSS/version-coupled rendering) plus R1 (layout
360
- sensitivity amplifies small engine changes into big visual diffs).
361
- - Fixture/test: this is the fork's categorical answer rather than a
362
- mitigation. Byte-identical output across runs, processes, and runtimes is
363
- CI-gated (`agent-determinism.test.ts`); ASCII output is hash-stable across
364
- the full 271-entry docs corpus (`ascii-determinism.test.ts`); PNG bytes
365
- are pinned via exact-version resvg + bundled fonts
366
- (`agent-png-determinism.test.ts`). Intentional layout changes must pass
367
- the before/after comparison harness (`eval/layout-compare/`,
368
- regressions-first verdicts) and update exact goldens — so every visual
369
- change is deliberate, evidenced, and reviewed.
370
- - Status here: **landed.** No Mermaid-syntax renderer we know of makes this
371
- guarantee.
372
-
373
- ### C12. Sequence-diagram alignment and overlap
374
-
375
- Sequence diagrams (bespoke layouter in Mermaid, not dagre) have their own
376
- class: uncontrollable/overlapping activations, off-center `alt`/`loop`
377
- titles, notes colliding with lifelines.
378
-
379
- - Evidence: [mermaid#1765 activations](https://github.com/mermaid-js/mermaid/issues/1765)
380
- (28R), [mermaid#3216](https://github.com/mermaid-js/mermaid/issues/3216),
381
- [mermaid#7651](https://github.com/mermaid-js/mermaid/issues/7651),
382
- [mermaid#7682](https://github.com/mermaid-js/mermaid/issues/7682).
383
- - Root cause: R5 (hand-rolled per-family geometry, no shared invariants) +
384
- R3 (no spacing overrides).
385
- - Fixture/test: layout geometry tests exist
386
- (`src/__tests__/sequence-layout.test.ts`, `ascii-sequence-blocks.test.ts`)
387
- and the sequence `RenderedLayout` adapter feeds the generic metrics.
388
- Sequence property coverage now checks activation spans, note stacking and
389
- bounds, and block/divider containment/non-overlap geometry over generated
390
- activation/note/block combinations. The broader productized verifier set
391
- — lifeline x-order, message y-order, activation span containment, and
392
- note/block containment as user-facing warnings — remains #25 §14.2 and
393
- #26 workstream 11.
394
- - Status here: **partial, with first family-specific properties landed.**
395
-
396
- ### C13. Chart families: hard-coded geometry breaks on real data
397
-
398
- Gantt axis dates overlap on long ranges, pie titles/labels clip, radar axis
399
- labels compress, C4 is widely considered the worst-layouted type. These are
400
- not dagre problems — each chart type has bespoke geometry with no collision
401
- handling.
402
-
403
- - Evidence: [mermaid#1301 gantt axis overlap](https://github.com/mermaid-js/mermaid/issues/1301)
404
- (23R), [mermaid#6232 pie title cut off](https://github.com/mermaid-js/mermaid/issues/6232),
405
- [mermaid#7683 radar labels clipped](https://github.com/mermaid-js/mermaid/issues/7683),
406
- [mermaid#7492 C4](https://github.com/mermaid-js/mermaid/issues/7492).
407
- - Root cause: R5 (per-family renderer-first geometry; semantics inferred at
408
- draw time — the exact anti-pattern #26's guiding principle names).
409
- - Fixture/test: pie and quadrant landed source-level with geometry tests
410
- (PR #22; quadrant point placement verified against the upstream Mermaid
411
- reference). Gantt is now implemented from PR #24's principled model — a
412
- pure, clock-free schedule resolver *before* layout, family validators
413
- (deterministic task intervals, milestone zero-width markers,
414
- non-overlapping compact rows) designed against precisely the mermaid#1301
415
- class. C4, radar, and mindmap are not supported at all.
416
- - Status here: **partial** (pie/quadrant/gantt landed; C4/radar/mindmap
417
- absent — see [`comparison.md`](./comparison.md) for the current
418
- family-coverage trade).
419
-
420
- ---
421
-
422
- ## Part 2 — Root causes
423
-
424
- Five root causes explain the catalog. R1–R3 apply to every auto-layout
425
- text-to-diagram tool, including this one; R4–R5 are specific lineages.
426
-
427
- ### R1. The layered framework solves NP-hard problems in irreversible phases
428
-
429
- Every engine in this story — dagre, ELK, dot — descends from the layered
430
- method of
431
- [Sugiyama, Tagawa & Toda 1981](https://doi.org/10.1109/TSMC.1981.4308636)
432
- (IEEE Trans. SMC-11(2)), extended since into the standard pipeline: break a
433
- directed graph drawing into sequential phases (cycle removal → layer
434
- assignment → crossing minimization → coordinate assignment → edge
435
- routing). The framework is powerful and is the right baseline for flow-like
436
- diagrams, but it has three structural consequences users experience
437
- directly:
438
-
439
- 1. **The subproblems are intractable, so every phase is heuristic.**
440
- Crossing number is NP-complete
441
- ([Garey & Johnson 1983](https://dl.acm.org/doi/10.1137/0604033), SIAM
442
- J. Alg. Disc. Meth. 4(3)); crossing minimization stays NP-complete even
443
- for two layers with one layer's order already fixed
444
- ([Eades & Wormald 1994](https://link.springer.com/article/10.1007/BF01187020),
445
- Algorithmica 11(4)) — the exact subproblem inside every layered engine;
446
- label placement is NP-complete even in simple variants
447
- ([Marks & Shieber 1991](https://dash.harvard.edu/entities/publication/73120379-247a-6bd4-e053-0100007fdf3b),
448
- Harvard TR-05-91), and edge-label placement specifically is NP-hard
449
- ([Kakoulis & Tollis 2001](https://www.sciencedirect.com/science/article/pii/S0925772100000250),
450
- Comput. Geom. 18(1)). No engine "chooses" the avoidable crossing in
451
- C4 — it fails to find the better optimum it cannot afford to search for.
452
- 2. **Phases cannot revisit earlier decisions.** Layering fixes ranks before
453
- crossing minimization sees them; coordinates are assigned before routing.
454
- A route that needs a node nudged one lane over cannot get it. This is
455
- the literature's own characterization of the framework's failure mode —
456
- "decisions made at previous steps influence later steps and yet cannot
457
- be undone"
458
- ([Healy & Nikolov, *Handbook of Graph Drawing and Visualization* ch. 13](https://cs.brown.edu/people/rtamassi/gdhandbook/chapters/hierarchical.pdf));
459
- "since layer assignment and crossing reduction are realized as
460
- independent steps, the resulting drawing might have many unnecessary
461
- crossings caused by an unfortunate layer assignment"
462
- ([Chimani, Gutwenger, Mutzel & Wong, JGAA 15(1), 2011](https://jgaa.info/index.php/jgaa/article/view/paper220/2748)).
463
- It is why locally-reasonable pipelines emit globally wrong results — the
464
- "hitch" of issue #25 is a phase-boundary artifact, and #25 §2 names it a
465
- *contract failure*: nothing in the pipeline encodes "this edge should be
466
- straight when its lane is clear" as an invariant any phase must preserve.
467
- 3. **Labels and shapes are afterthoughts in the classic formulation.**
468
- Labels enter as dummy nodes or post-hoc annotations (C5); non-rectangular
469
- shapes are approximated by their bounding boxes until a final clipping
470
- pass (#25 principle 6).
471
-
472
- Empirical work confirms users are right to care:
473
- [Purchase 1997](https://link.springer.com/chapter/10.1007/3-540-63938-1_67)
474
- (Graph Drawing, LNCS 1353) found reducing edge crossings "by far the most
475
- important" aesthetic for human comprehension, with bend minimization also
476
- significant — exactly the two artifacts the phase structure produces.
477
- Compound (subgraph) layout multiplies the difficulty: nested clusters with
478
- cross-cluster edges constrain layering and crossing minimization
479
- simultaneously
480
- ([Sander 1996](https://publikationen.sulb.uni-saarland.de/bitstream/20.500.11880/25862/1/tr-A03-96.pdf),
481
- TR A/03/96, Universität des Saarlandes), which is why C3 is hard for
482
- everyone — and weak cluster handling is dagre's most visible gap (open for
483
- years in its own tracker:
484
- [dagre#125](https://github.com/dagrejs/dagre/issues/125),
485
- [dagre#238](https://github.com/dagrejs/dagre/issues/238)).
486
-
487
- ### R2. Greedy per-edge grid routing in the ASCII lineage
488
-
489
- [`mermaid-ascii`](https://github.com/AlexanderGrooff/mermaid-ascii)
490
- (Alexander Grooff, Go) works in three stages — parse, map components onto a
491
- character grid, route each edge independently by pathfinding — and this
492
- repo's ASCII engine is a TypeScript port of it
493
- (`src/ascii/edge-routing.ts` is "ported from
494
- AlexanderGrooff/mermaid-ascii cmd/direction.go + cmd/mapping_edge.go").
495
- Per-edge greedy routing with no shared intent produces the ASCII-specific
496
- complaint classes visible in both trackers: in the original,
497
- single-edge-per-node-pair limits, floating arrowheads on labeled
498
- back-edges, and East Asian width breakage
499
- ([mermaid-ascii#56](https://github.com/AlexanderGrooff/mermaid-ascii/issues/56),
500
- [#63](https://github.com/AlexanderGrooff/mermaid-ascii/issues/63),
501
- [#59](https://github.com/AlexanderGrooff/mermaid-ascii/issues/59)); in
502
- this lineage, equal-cost path nondeterminism, labels landing on shared
503
- detours instead of their own branch (upstream #111/#112), fan-in groups
504
- merging into ambiguous trunks (#68/#69), connectors floating off node
505
- borders, phantom boxes for subgraph-id endpoints, and fullwidth/CJK text
506
- breaking column math (#119, #121) — inherited and then fixed here
507
- case-by-case. The durable fix is the same as for R1: route intent shared
508
- across edges before geometry (#25 §13 — ASCII consumes route classes;
509
- trunks, reserved feedback channels, label capacity).
510
-
511
- ### R3. Layout is authored content everywhere except text-to-diagram tools
512
-
513
- The standards world treats positions as part of the artifact:
514
- [OMG Diagram Definition](https://www.omg.org/spec/DD/) distinguishes
515
- "graphical information … users have control over, such as position of
516
- nodes and line routing points," which is "captured for interchange between
517
- tools," from styling fixed by the notation — and its predecessor UML DI
518
- spec states the failure mode plainly: without diagram interchange, "all
519
- diagram information is lost" when a model moves between tools. BPMN DI is a
520
- normative part of BPMN 2.0
521
- ([ISO/IEC 19510](https://www.iso.org/standard/62652.html)): "the
522
- interchange of laid out shapes and edges," carrying shape bounds and edge
523
- waypoints. UML 2.5 normatively defines notation but is silent on layout,
524
- delegating persistence to the DD-based UML DI annex. Even drafting
525
- conventions were standardized:
526
- [ANSI X3.5-1970 §4.4.1](https://www.bitsavers.org/pdf/ansi/X3/X3.005-1970_Flowchart_Symbols_and_Their_Usage_in_Information_Processing.pdf)
527
- is normative that "normal direction of flow is from left to right and top
528
- to bottom," with arrowheads *required* only on reverse-direction lines —
529
- and its successor [ISO 5807:1985](https://www.iso.org/standard/11955.html)
530
- keeps the conditional-arrowhead rule (§9.3.1: "solid or open arrowheads
531
- shall be added to indicate direction of flow where necessary (see
532
- 10.2.1.2)"; clause 10 "Conventions" carries the direction rules). Issue
533
- #25's primary-forward/feedback route classes are that half-century-old
534
- convention, restated as a checkable invariant — and the same convention
535
- family yields further validator candidates (unlabeled decision branches;
536
- single-entry/labeled-exit analysis), tracked in
537
- [`issue-derived-test-cases.md`](./issue-derived-test-cases.md).
538
-
539
- Mature tools likewise expose constraint surfaces. Graphviz dot has had
540
- [`rank=same`/`min`/`max`](https://graphviz.org/docs/attrs/rank/),
541
- [compass-point ports](https://graphviz.org/docs/attr-types/portPos/)
542
- (`a:port:nw -> b`), per-edge
543
- [`constraint`](https://graphviz.org/docs/attrs/constraint/)/[`weight`](https://graphviz.org/docs/attrs/weight/)
544
- knobs, and obstacle-avoiding spline routing
545
- ([`splines=true`: "edges are drawn as splines routed around nodes"](https://graphviz.org/docs/attrs/splines/))
546
- since the 1990s. D2 ships [`near`](https://d2lang.com/tour/positions/)
547
- (anchor a shape near a named other shape),
548
- [grid diagrams](https://d2lang.com/tour/grid-diagrams/) for exact
549
- row/column placement, and the architecture-tuned
550
- [TALA engine](https://d2lang.com/tour/tala/) — "first-class consideration
551
- for containers," position locking via `top`/`left`, per-container
552
- direction, dynamic label positioning (and, honestly documented, its own
553
- instability: a small label change "can cascade into an entirely different
554
- layout"). yFiles distinguishes post-hoc "generic" labeling from
555
- [*integrated* labeling computed during layout](https://docs.yworks.com/yfiles-html/dguide/layout/label_placement.html),
556
- which "prevent[s] label overlaps completely."
557
-
558
- Text-to-diagram tools deliberately drop that half of the artifact: source
559
- in, geometry recomputed every render, nothing persisted, no constraints.
560
- That is the actual root of C1 and C6 — not dagre. It is also a real trade
561
- (zero-friction authoring, diffable sources, no stale coordinates), which is
562
- why this project keeps the contract but changes who absorbs the cost: the
563
- layout is a *deterministic function* of source (C6, C11), its quality is
564
- *measurable* (`checkQuality`), and its decisions are to become
565
- *explainable* (#25 certificates) — so an editing program gets back the
566
- agency a human loses by not being able to drag nodes.
567
-
568
- ### R4. dagre: a partial dot port, frozen
569
-
570
- Mermaid (2014, Knut Sveidqvist) was built browser-first on d3 + dagre-d3;
571
- layout was delegated wholesale to dagre, Chris Pettitt's JavaScript
572
- implementation of the Sugiyama/dot pipeline — a delegation Mermaid's
573
- maintainer named himself when opening
574
- [mermaid#867 "Support multiple layout algorithms"](https://github.com/mermaid-js/mermaid/issues/867)
575
- in 2019: "Currently the layout mechanism mermaid is using is a dagre
576
- algorithm."
577
-
578
- What dagre ports — and what it omits — maps directly onto the catalog. The
579
- dot paper
580
- ([Gansner, Koutsofios, North & Vo 1993](https://www.graphviz.org/documentation/TSE93.pdf),
581
- IEEE TSE 19(3)) is a *four*-pass algorithm: ranking, ordering, coordinates,
582
- then a spline-routing pass that computes piecewise-Bézier edges inside a
583
- feasible region so they avoid node obstacles — the paper explicitly calls
584
- out tools that "make no attempt to avoid situations where line segments
585
- overlap unrelated nodes." dot also guarantees that edge labels, modeled as
586
- virtual nodes, "never overlap other nodes, edges or labels," and exposes
587
- rank constraints. dagre implements the first three passes (its coordinate
588
- assignment is
589
- [Brandes & Köpf 2001](https://link.springer.com/chapter/10.1007/3-540-45848-4_3),
590
- in `lib/position/bk.js`) and then stops: there is no routing phase at all —
591
- edges are interpolated through dummy-node points.
592
- [dagre-d3#291](https://github.com/dagrejs/dagre-d3/issues/291) is the
593
- user-visible result, and C4/C5 are the Mermaid-visible results. Cluster
594
- support follows Sander/Forster on paper (per
595
- [dagre's wiki](https://github.com/dagrejs/dagre/wiki)) but fails on nesting
596
- and compound edges in practice
597
- ([dagre#125](https://github.com/dagrejs/dagre/issues/125),
598
- [dagre#238](https://github.com/dagrejs/dagre/issues/238)) — C3. dot-style
599
- rank constraints existed in early dagre, were dropped in the 0.7 rewrite,
600
- and the restoration request —
601
- [dagre#159 "Add back support for rank constraints"](https://github.com/dagrejs/dagre/issues/159)
602
- — has been open since November 2014.
603
-
604
- The "abandoned" framing needs one nuance. D2's engine-comparison page
605
- states ["Unmaintained. Development stopped in 2018"](https://d2lang.com/tour/dagre/)
606
- ("battle tested (thanks to MermaidJS, which exclusively uses Dagre for its
607
- flowcharts)"; cons include "makes some inexplicable edge routing decisions
608
- occasionally"), and that was accurate for the era it described — but the
609
- `@dagrejs` org resumed releases in 2023 (1.0.0 May 2023; 3.0.0 March 2026).
610
- What has *not* changed is the feature picture: no routing phase, no ports,
611
- rank constraints still unrestored after a decade, and Mermaid ships the
612
- dormant `dagre-d3` line via the `dagre-d3-es` fork.
613
-
614
- Mermaid's own remediations concede the diagnosis. The migration ask —
615
- [mermaid#1969 "Migrate flowchart from dagre to elkjs"](https://github.com/mermaid-js/mermaid/issues/1969)
616
- (2021: dagre draws "edges … through other blocks instead of around them")
617
- — was answered by the maintainer himself with the experimental
618
- `flowchart-elk` renderer in v9.4.0 (February 2023), then v11.0.0 (August
619
- 2024) made layout pluggable with ELK as the opt-in
620
- [`@mermaid-js/layout-elk`](https://www.npmjs.com/package/@mermaid-js/layout-elk)
621
- package ("better for larger and/or more complex diagrams," per its own
622
- docs) — selected via frontmatter `config.layout`, and per the
623
- [syntax reference](https://mermaid.js.org/intro/syntax-reference.html)
624
- "currently … supported for flowcharts and state diagrams" only. The
625
- edge-overlap ask
626
- [mermaid#1006](https://github.com/mermaid-js/mermaid/issues/1006) was
627
- closed *Wont Fix*. GitHub's native rendering still runs the dagre default —
628
- so most readers see the unfixed engine (C2, C3, C4, C9), and even opted-in
629
- users get the better engine for two of ~25 families. PlantUML made the
630
- opposite bet decades earlier: it
631
- [delegates class/state/component/usecase layout to Graphviz dot](https://plantuml.com/graphviz-dot),
632
- inheriting dot's router and rank constraints along with its weaknesses.
633
-
634
- This engine's answer is architectural: ELK layered
635
- ([Schulze, Spönemann & von Hanxleden 2014](https://www.sciencedirect.com/science/article/abs/pii/S1045926X13000943),
636
- JVLC 25(2) — the port-constraint extension of Sugiyama) as the only graph
637
- engine, bundled synchronously, with model-order options pinned so source
638
- order drives cycle breaking and crossing minimization
639
- ([`considerModelOrder`](https://eclipse.dev/elk/reference/options/org-eclipse-elk-layered-considerModelOrder-strategy.html):
640
- "preserves the order of nodes and edges in the model file if this does not
641
- lead to additional edge crossings"; the backing paper is Domrös &
642
- von Hanxleden, IVAPP 2022). ELK brings the port constraints
643
- (`FIXED_SIDE`/`FIXED_ORDER`/`FIXED_POS`) that #25 §8 builds on and dagre
644
- never had, plus compound layout and an optional libavoid-based
645
- obstacle-avoiding router. It is not sufficient by itself: upstream #83
646
- showed ELK's default cycle breaking flipping TD diagrams horizontal until
647
- model order was enforced; ELK's own docs restrict what composes with
648
- `INCLUDE_CHILDREN` hierarchy handling (which is why
649
- `src/layout-engine.ts` falls back to `SEPARATE` when a subgraph overrides
650
- direction); and ELK still knows nothing about *semantic* edge roles, which
651
- is exactly the intent layer #25 adds.
652
-
653
- ### R5. Renderer-first semantics, in three generations
654
-
655
- The recurring design flaw across all three codebases is the one #26's
656
- guiding principle names: *the renderer is the first place semantics are
657
- guessed.*
658
-
659
- - **Mermaid (November 2014–):** born, per its own 0.1.0 README, to "avoid
660
- heavy tools like Visio" with "a simple markdown-like script language" —
661
- the design optimized authoring friction, not layout quality. Per-family
662
- Jison grammars feed per-family bespoke renderers (the sequence renderer
663
- uses no layout engine at all — hand-maintained vertical-position
664
- bookkeeping, hence C12); text is measured via the browser DOM with HTML
665
- labels in `foreignObject` — the C8 export-clipping family, first reported
666
- six weeks after the first release
667
- ([mermaid#58](https://github.com/mermaid-js/mermaid/issues/58), December
668
- 2014, still open) — styling is coupled to page CSS, chart geometry is
669
- hard-coded per type with no collision handling (C13), and there is no IR
670
- contract between parse and render, so every embedder/version pair renders
671
- differently (C11).
672
- - **`mermaid-ascii`:** grid geometry computed during drawing; labels and
673
- containers handled by local painter logic (R2).
674
- - **`beautiful-mermaid` (Craft/Luki Labs, January 2026):** re-implemented
675
- rendering as synchronous zero-DOM TypeScript with bundled elkjs (run
676
- synchronously via a worker bypass, `src/elk-instance.ts`) — fixing C8 and
677
- the browser half of C11 — but kept lenient line-by-line regex parsers
678
- (the ER cardinality parser silently dropped valid relationships — upstream
679
- #124, fixed here in PR #17) and accumulated post-ELK geometry passes:
680
- layer alignment introduced in upstream v1.0.1 ("Layout quality
681
- improvements and layer alignment"), edge-point orthogonalization, and
682
- post-routing shape clipping. Each pass is locally reasonable; together
683
- they move geometry after routes are extracted, which is #25's diagnosed
684
- source of hitches and stale bends (§2, §9).
685
-
686
- This fork's trajectory is the inversion of that flaw: parse to a typed
687
- model, derive layout intent, compute geometry, certify, then render —
688
- with renderers as projections of shared intent rather than the place where
689
- intent is invented.
690
-
691
- ### Root causes → issue #26 workstreams
692
-
693
- | Root cause | #26 workstream(s) |
694
- |---|---|
695
- | R1 phase separation, no invariants | WS1 layout-intent/certificates; WS4 certifying simplifier |
696
- | R1 labels as afterthoughts | WS8 text-measurement contract; #25 §11.4 label invariant |
697
- | R1 compound difficulty | WS2 route classes (`cross-hierarchy`, `container-edge`) |
698
- | R2 greedy grid routing | WS6 ASCII/Unicode as first-class projections of route intent |
699
- | R3 no control surface | WS14 analysis outputs (explain, don't invent syntax); #25 certificates |
700
- | R4 rectangular/port-less model | WS3 semantic ports and shape-aware anchors |
701
- | R5 renderer-first semantics | WS5 Gantt resolver model (landed); WS7 class/ER contracts; WS10 region tree; WS13 preservation ladder |
702
- | Unreviewable visual change (meta) | WS12 reproducible before/after evidence |
703
- | Generic metrics miss failures (meta, C4 worked example) | WS11 family-specific validators |
704
-
705
- ---
706
-
707
- ## Part 3 — Coverage scorecard
708
-
709
- | # | Complaint | Loudest evidence | Status here | Key references |
710
- |---|---|---|---|---|
711
- | C1 | Manual positioning | mermaid#5420 (47R), #270 (2016–) | **out of scope** by policy | #25 OQ2; agent loop as substitute |
712
- | C2 | Scale collapse | mermaid#1984 (39R) | **partial** (detection only) | `quality.ts` bands; `eval/layout-compare/` |
713
- | C3 | Subgraphs | mermaid#2509 (189R) | **landed** | `subgraph-direction.test.ts`; PRs #17/#21/#22 |
714
- | C4 | Erratic routing | mermaid#6476, #5601 | **partial**; fix **specced** | #25 §11–12; MFA worked example above |
715
- | C5 | Edge-label overlap | mermaid#2131, #7492 | **partial** | inline ELK labels; `labelEdgeProximity`; #25 §11.4 |
716
- | C6 | Order control / edit stability | mermaid#3723 (86R), #815 (45R) | **partial** | model-order ELK opts; `agent-auth-flow.test.ts`; edit-stability tests |
717
- | C7 | Default aesthetics | HN 30339032 | **landed** (upstream + fork) | theming; Style + Palette; contrast tests |
718
- | C8 | Text clipping | mermaid#2688 (24R) | **landed** | zero-DOM text; `LABEL_OVERFLOW`; CJK tests; WS8 specced |
719
- | C9 | dagre stagnation | Mermaid docs' own ELK advice | **landed** structurally | `layout-engine.ts`; `elk-instance.ts`; #25 §10 |
720
- | C10 | Self-loops | mermaid#6336 (31R) | **partial** | clearance heuristics; #25 §8.1 specced |
721
- | C11 | Version/renderer instability | mermaid#5813 (28R) | **landed** | determinism suite; `eval/layout-compare/`; goldens |
722
- | C12 | Sequence alignment | mermaid#1765 (28R) | **partial**; first properties landed | #25 §14.2; #26 WS11; `sequence-layout.test.ts` |
723
- | C13 | Chart-family geometry | mermaid#1301 (23R) | **partial** | PR #24 (gantt); pie/quadrant/gantt geometry tests |
724
-
725
- ---
726
-
727
- ## Part 4 — What this project deliberately does not address
728
-
729
- Stated plainly so the scorecard cannot oversell:
730
-
731
- 1. **Manual positioning (C1).** The loudest single ask is answered with a
732
- substitute (deterministic + measurable + explainable auto-layout for
733
- editing programs), not a solution. If Mermaid core standardizes layout
734
- hints, this fork follows; it will not invent them (#25 non-goals).
735
- 2. **Large-diagram compaction (C2).** Detection exists; no compaction work
736
- is scheduled. Source-order priority can make wide diagrams wider — the
737
- Auth Flow aspect band in `agent-auth-flow.test.ts` is widened to 7
738
- because of it. The only candidate direction on record is the
739
- decomposition idea noted in C2, which sidesteps compaction rather than
740
- solving it.
741
- 3. **Reach.** Most complainers experience Mermaid through GitHub/GitLab/
742
- Notion native rendering, which no fork renderer can change. Work here
743
- applies to diagrams rendered through this stack (agent pipelines, CI,
744
- terminals, the editor) plus whatever is upstreamed per the
745
- [upstreaming strategy](./fork-differences.md#upstreaming-strategy).
746
- 4. **Family coverage.** 12 families vs Mermaid's ~25. Gantt is now rendered
747
- and characterized in this fork; C4/radar/mindmap and many other Mermaid
748
- families remain outside the current engine.
749
- 5. **Metric honesty.** Today's perceptual metrics pass diagrams whose
750
- routing is visibly wrong (C4 worked example). Until #25 certificates and
751
- #26 family validators land, `verify.ok` + `checkQuality` must not be
752
- read as "looks right" — `docs/quality.md` already says this; the MFA
753
- fixture proves it.
754
-
755
- ---
756
-
757
- ## Sources
758
-
759
- Complaint evidence (June 2026): the `mermaid-js/mermaid` issues linked
760
- inline above; Mermaid flowchart docs
761
- (<https://mermaid.js.org/syntax/flowchart.html>); Hacker News items linked
762
- inline; the GitLab handbook Mermaid-layout page
763
- (<https://handbook.gitlab.com/handbook/tools-and-tips/mermaid/>);
764
- diagrams.so's diagram-as-code comparison
765
- (<https://diagrams.so/learn/diagram-as-code-comparison>).
766
-
767
- Literature (all verified June 2026; venue/page details via dblp or
768
- publisher pages):
769
-
770
- - Sugiyama, Tagawa & Toda, "Methods for Visual Understanding of
771
- Hierarchical System Structures," IEEE Trans. SMC-11(2), 1981.
772
- <https://doi.org/10.1109/TSMC.1981.4308636>
773
- - Garey & Johnson, "Crossing Number is NP-Complete," SIAM J. Algebraic
774
- Discrete Methods 4(3), 1983. <https://dl.acm.org/doi/10.1137/0604033>
775
- - Eades & Wormald, "Edge crossings in drawings of bipartite graphs,"
776
- Algorithmica 11(4), 1994.
777
- <https://link.springer.com/article/10.1007/BF01187020>
778
- - Marks & Shieber, "The Computational Complexity of Cartographic Label
779
- Placement," Harvard TR-05-91, 1991.
780
- <https://dash.harvard.edu/entities/publication/73120379-247a-6bd4-e053-0100007fdf3b>
781
- - Kakoulis & Tollis, "On the complexity of the Edge Label Placement
782
- problem," Comput. Geom. 18(1), 2001.
783
- <https://www.sciencedirect.com/science/article/pii/S0925772100000250>
784
- - Gansner, Koutsofios, North & Vo, "A Technique for Drawing Directed
785
- Graphs," IEEE TSE 19(3), 1993.
786
- <https://www.graphviz.org/documentation/TSE93.pdf>
787
- - Brandes & Köpf, "Fast and Simple Horizontal Coordinate Assignment,"
788
- GD 2001, LNCS 2265.
789
- <https://link.springer.com/chapter/10.1007/3-540-45848-4_3> (authors'
790
- 2020 erratum: <https://arxiv.org/abs/2008.01252>)
791
- - Schulze, Spönemann & von Hanxleden, "Drawing layered graphs with port
792
- constraints," JVLC 25(2), 2014.
793
- <https://www.sciencedirect.com/science/article/abs/pii/S1045926X13000943>
794
- - Domrös & von Hanxleden, "Preserving Order during Crossing Minimization
795
- in Sugiyama Layouts," IVAPP 2022.
796
- <https://www.scitepress.org/Papers/2022/108338/108338.pdf>
797
- - Purchase, "Which aesthetic has the greatest effect on human
798
- understanding?", GD 1997, LNCS 1353.
799
- <https://link.springer.com/chapter/10.1007/3-540-63938-1_67>
800
- - Sander, "Layout of Compound Directed Graphs," TR A/03/96, Universität
801
- des Saarlandes, 1996.
802
- <https://publikationen.sulb.uni-saarland.de/bitstream/20.500.11880/25862/1/tr-A03-96.pdf>
803
- - Wybrow, Marriott & Stuckey, "Orthogonal Connector Routing," GD 2009
804
- (libavoid). <https://users.monash.edu/~mwybrow/papers/wybrow-gd-2009.pdf>
805
-
806
- Products: Graphviz attribute docs (`rank`, `portPos`, `splines`,
807
- `constraint`, `weight`, linked inline); D2/Terrastruct docs (TALA, `near`,
808
- grid diagrams, dagre/ELK engine pages, linked inline); yFiles automatic
809
- label placement
810
- (<https://docs.yworks.com/yfiles-html/dguide/layout/label_placement.html>);
811
- PlantUML–Graphviz delegation (<https://plantuml.com/graphviz-dot>);
812
- Mermaid v11.0.0 release
813
- (<https://github.com/mermaid-js/mermaid/releases/tag/v11.0.0>) and
814
- `@mermaid-js/layout-elk`
815
- (<https://www.npmjs.com/package/@mermaid-js/layout-elk>); ELK option
816
- reference (<https://eclipse.dev/elk/reference.html>) and the ELK overview
817
- paper (<https://arxiv.org/abs/2311.00533>).
818
-
819
- Standards: OMG Diagram Definition v1.1 (<https://www.omg.org/spec/DD/>);
820
- BPMN 2.0.2 (<https://www.omg.org/spec/BPMN/2.0.2/>) / ISO/IEC 19510:2013
821
- (<https://www.iso.org/standard/62652.html>); UML 2.5.1
822
- (<https://www.omg.org/spec/UML/2.5.1/About-UML>); ISO 5807:1985
823
- (<https://www.iso.org/standard/11955.html>); ANSI X3.5-1970 (scan:
824
- <https://www.bitsavers.org/pdf/ansi/X3/X3.005-1970_Flowchart_Symbols_and_Their_Usage_in_Information_Processing.pdf>).
825
-
826
- Origins: Mermaid 0.1.0 (November 2014, Knut Sveidqvist;
827
- <https://github.com/mermaid-js/mermaid/releases/tag/0.1.0> — the 0.1.0
828
- README credits d3 and dagre-d3 and states the Visio-avoidance motive);
829
- dagre (Chris Pettitt; wiki reading list
830
- <https://github.com/dagrejs/dagre/wiki>; rank-constraint regression
831
- dagre#159; `@dagrejs` revival releases 2023–2026); `mermaid-ascii`
832
- (Alexander Grooff, <https://github.com/AlexanderGrooff/mermaid-ascii>;
833
- Show HN October 2024 <https://news.ycombinator.com/item?id=41847407>);
834
- `beautiful-mermaid` (Luki Labs/Craft, npm January 2026; HN thread
835
- <https://news.ycombinator.com/item?id=46804828>; upstream v1.0.1
836
- layout/layer-alignment commit; upstream issues
837
- #63/#68/#69/#83/#89/#98/#111/#112/#113/#115/#119/#121/#124).