跳转到内容

20260913-0146-product-matrix-readability Make the product matrix diagrams readable

  • status: completed
  • createdAt: 2026-09-13 01:46
  • approvedAt: 2026-09-13 02:05
  • relatedTask: 20260913-0144-product-matrix-readability
  • What the published page actually looks like. The on-boat chart draws edges across three subgraph boxes, sends two long reverse arcs from the Hub back up to Core and Sense, leaves the P05 Switch and 执行与采集 boxes mostly empty while packing their area with routed edges, and places free nodes (P07 Studio, P10 View, 直流负载与区域馈线, 交流负载) inside the drawn area of subgraphs they do not belong to. The 交流配电箱 label is clipped: its third line, 过流与漏电保护, is cut off because the label carries three phrases with only one <br/>.
  • Primary cause is the chart, not the renderer. One flowchart TB holds 14 nodes, 4 subgraphs, 20 edges and three peripheral product lines (Eye, View, Tag) that have no ordering relationship to the main chain. dagre assigns ranks by edge direction, so every reverse edge (HUB -- 配置与 OTA --> CORE, HUB -- 配置与 OTA --> SENSE) forces a back-arc across the whole drawing, and every free node is placed at whatever rank its single edge implies — which is why they land visually inside other subgraphs.
  • Secondary cause is the layout engine. Mermaid's default dagre renderer has no concept of subgraph separation; it routes edges straight through cluster rectangles. @mermaid-js/layout-elk replaces it with ELK's layered algorithm, which respects cluster boundaries and reduces crossings substantially on exactly this shape of graph.
  • Version compatibility is already checked (npm registry, 2026-09-13). @mermaid-js/layout-elk@0.2.3 declares peerDependencies.mermaid ^11.0.2, so the repository's mermaid 11.17.2 needs no major upgrade. @mermaid-js/layout-elk@1.0.0 requires mermaid ^12, and vitepress-plugin-mermaid@2.0.17 declares peerDependencies.mermaid "10 || 11" — so upgrading mermaid to 12 would break the plugin. 0.2.3 is the version to pin.
  • Verification gap from the previous task. bun run docs:build does not render Mermaid (it is client-side), and mermaid.parse() only proves syntax. Nothing in the last change inspected the drawing, which is why an unreadable chart shipped. Any fix here must be checked as an image.
章节标题:“A. Recommended: restructure the charts, then add ELK”

Restructuring is the part that must happen; ELK is an additional improvement that does not depend on it.

A1 — Split one on-boat chart into two.

Chart Scope Direction
图 1 · 控制与配电 Switch control surfaces (Air, Key, Air Hub) → Core / Sense → DC loads, plus the P04 AC boundary (coil drive out, dry contact back) LR — the chain is naturally horizontal
图 2 · 船舶主控与集成 Core / Sense → Hub → Mate software/cloud/App; Studio configuration downlink; NMEA 2000 to MFDs; Eye over LAN/PoE; View and Tag as dashed non-baseline paths; the AC metering module over RS-485 TB
图 3 · 船外形态 Unchanged from the current second chart (Air / Key → Air Hub → P09 Control → actuators and ecosystems) LR

A2 — Structural rules applied to all three.

  1. Every node belongs to a subgraph; 直流负载, 交流负载 and MFD get their own 负载与外部设备 group rather than floating.
  2. No reverse edges. 遥测 and 配置与 OTA between Core/Sense and the Hub become one bidirectional edge (CORE <-- YBO CAN 遥测 / 配置与 OTA --> HUB) in 图 2 only.
  3. One <br/> per phrase in every label, so nothing clips.
  4. Peripheral lines (Eye, View, Tag) appear only in 图 2, never in the main chain.

A3 — Layout engine.

  • Add @mermaid-js/layout-elk@0.2.3 as a dev dependency.
  • Register it client-side in .vitepress/theme/index.ts via mermaid.registerLayoutLoaders(elkLayouts) inside enhanceApp, and select it per chart with %%{init: {"layout": "elk"}}%%.
  • Risk and fallback. vitepress-plugin-mermaid imports its own mermaid instance; if module resolution does not share that instance, the registration will not take effect. This is verified by rendering, not assumed. If it does not work, the restructured charts ship on dagre and the dependency is reverted — A1/A2 alone already fix the clipping, the free nodes and the reverse arcs.

B. Alternative: restructure only, no new dependency

章节标题:“B. Alternative: restructure only, no new dependency”

Same A1/A2, dagre unchanged. Zero dependency and build-config risk, and it fixes every defect that is the chart's own fault. It does not fix edges routed through cluster rectangles, which is a renderer limitation. Cheapest option if the result is judged good enough.

C. Rejected: switch to a different diagram tool

章节标题:“C. Rejected: switch to a different diagram tool”
  • D2 produces the best layout of the three and handles containers properly, but it is a Go binary that must run at build time, needs a CI install step and a committed SVG or a VitePress plugin, and the diagrams must be rewritten in D2 syntax. Disproportionate for one page.
  • Graphviz dot has the same build-time requirement with a lower-level syntax and weaker CJK label handling.
  • Hand-drawn SVG / Excalidraw gives full control but cannot be maintained alongside PRODUCT-PLAN.md revisions.
File Change
bizplan/product/index.md Rewrite the 产品矩阵 section: three charts, regrouped nodes, no reverse edges, fixed labels, reading notes redistributed per chart
package.json, bun.lock Add @mermaid-js/layout-elk@0.2.3 (A only)
.vitepress/theme/index.ts Register the ELK layout loader client-side (A only)
docs/changelog.md Record the change

No product statement changes; every node and edge keeps tracing to PRODUCT-PLAN.md §2/§3.

  1. mermaid.parse() on every block in a jsdom host — syntax. → verify: all blocks report flowchart-v2.
  2. Render each chart to PNG with the mermaid-cli container image and read the images. → verify: no clipped label, no edge crossing a subgraph rectangle, no node inside a subgraph it does not belong to.
  3. bun run docs:build. → verify: build succeeds and the ELK chunk is emitted when A is taken.
  4. git diff --check. → verify: clean.
  5. Report the images before deploying, so the layout is judged before it is published.
  • Whether A3's ELK registration works through vitepress-plugin-mermaid is unknown until rendered; the plan carries the fallback rather than assuming success.

Option A was implemented in full, including the display fixes.

  • Charts: three (控制与配电 LR, 船舶主控与集成 TB, 船外形态 LR); every node sits in a subgraph except the P12 Tag extension node; no reverse edges; every label is at most two lines.
  • A third defect surfaced during rendering and is fixed by the two-line cap: mermaid under-sizes a node box for three or more label lines, clipping the last line. This affected both dagre and ELK, so it was the chart's own fault, not the renderer's.
  • ELK registration through vitepress-plugin-mermaid works (open item closed). Vite must pre-bundle fastdom and fastdom/extensions/fastdom-promised.js, otherwise the page script fails with a CommonJS interop error and no diagram renders at all.
  • Display: flowchart.useMaxWidth: false plus .mermaid { overflow-x: auto } keeps diagrams at natural size; htmlLabels: false keeps labels crisp when scaled; clicking a diagram opens it 1:1 in a full-screen <dialog> that closes on click or Escape.
  • Verified against the production build in a headless browser: three charts, no syntax error, each container scrollable, dialog opens with the diagram and is removed on Escape. bun run docs:build and git diff --check pass.