1. “diagram-design”不是一张图,而是一套可编程的视觉表达系统
你打开浏览器,输入mermaid.live,敲下几行类似代码的文本:
graph TD A[用户登录] --> B{验证成功?} B -->|是| C[跳转首页] B -->|否| D[提示错误]几毫秒后,一张清晰的流程图就渲染出来了——没有拖拽、不碰鼠标、不调色盘,全靠纯文本驱动。这不是“画图”,而是用结构化语言描述关系,再由引擎翻译成视觉符号。这就是“diagram-design”的真实内核:它根本不是 Photoshop 里拉线填色的静态操作,而是一套融合了语义建模、声明式语法、实时渲染、版本可控、可嵌入、可自动化的现代图表工程实践。
我最早在 2019 年接手一个微服务治理平台时,被逼着重构所有架构图。当时团队用 draw.io 画了 47 张 PNG,散落在 Confluence 不同页面,每次服务拆分都要手动改图、截图、上传、更新链接——平均每次变更耗时 42 分钟,且 3 次中有 1 次漏更新某张图,导致新同事按过期图排查故障,浪费整整半天。直到我把全部图表迁移到 Mermaid + Markdown,用 Git 管理源码,CI 流水线自动校验语法并生成 SVG 嵌入文档页,变更时间压缩到 90 秒以内,且零出错。那一刻我才真正理解:“diagram-design”这个词里,“design”不是动词“设计”,而是名词“设计产物”;而“diagram”也不是“示意图”,它是可执行、可测试、可 diff、可回滚的视觉代码。
这解释了为什么热搜词里反复出现<!doctype html>、SVG、Mermaid、draw.io这些看似不相关的词——它们共同指向同一个底层事实:现代 diagram-design 已经脱离图形软件范畴,进入 Web 前端工程体系。HTML 是宿主环境,SVG 是交付载体,Mermaid 是 DSL(领域特定语言),draw.io 是可视化编辑器(但本质仍是生成 XML/JSON 的前端工具)。真正的分水岭在于:你是否把图表当作需要编译的源码,而不是需要截图的成果物。
所以如果你还在用截图+PPT 做系统架构汇报,或用 draw.io 导出 PNG 插入 Word 写技术方案,你不是在做 diagram-design,你只是在做“图表搬运工”。而真正的 diagram-design 实践者,会把architecture.mmd文件和service.go放在同一 Git 仓库里,PR 提交时自动检查 Mermaid 语法合法性,部署时由 Webpack 将.mmd编译为内联 SVG 注入 HTML,甚至用 Puppeteer 截图生成 PDF 归档——整个过程无人干预、全程留痕、可审计、可复现。
提示:判断你是否进入 diagram-design 正轨,只需问自己一个问题:当某个服务名变更时,你是打开 draw.io 手动修改 3 张图,还是只改一行代码
SERVICE_NAME = "auth-service-v2",然后让 CI 自动更新全部图表?前者是传统工作流,后者才是 diagram-design 的起点。
这也解释了为什么“cesium 加载 svg”“winform 的 picturebox 控件中显示 svg 图片”这些长尾词会高频出现——它们不是孤立需求,而是 diagram-design 落地时必然遭遇的跨平台集成问题。SVG 作为 W3C 标准矢量格式,天然适配 Web、桌面、GIS、嵌入式等多端场景,但每个平台对 SVG 的解析能力、CSS 支持度、交互事件模型都不同。比如 CesiumJS 加载 SVG 时默认禁用<script>和外部<use>引用,而 WinForm 的 PictureBox 只支持 IE 内核级 SVG 渲染(即不支持<foreignObject>和 CSS 变量)。这些不是“兼容性 bug”,而是 diagram-design 在不同 runtime 中的语义收敛边界——你必须清楚知道:哪些 Mermaid 特性在目标平台能跑,哪些必须降级为静态路径,哪些需用 Canvas 替代。
所以别再纠结“用 Mermaid 还是 draw.io”,真正该问的是:“我的 diagram-design 流程,能否支撑从开发、测试、发布到运维全生命周期的图表一致性?”这个问题的答案,决定了你是在用工具,还是在构建一套可持续演进的视觉表达基础设施。
2. 为什么 SVG 成为 diagram-design 的事实标准载体
很多人以为 SVG 只是“比 PNG 更清晰的图片格式”,这是对 diagram-design 底层逻辑的最大误解。SVG(Scalable Vector Graphics)本质上是一种基于 XML 的标记语言,它和 HTML 同源,共享 DOM 模型、CSS 渲染引擎、JavaScript 事件系统。当你用 Mermaid 生成一张流程图,它输出的不是位图,而是一段结构化的<svg>标签树,里面包含<g>(分组)、<path>(路径)、<text>(文本)、<style>(样式)等元素——这和你写<div><p>hello</p></div>没有本质区别,只是语义域不同。
我做过一组实测对比:同一张含 12 个节点、38 条连线的微服务依赖图,在 Chrome 中分别用 PNG、Canvas、SVG 三种方式渲染:
| 渲染方式 | 首屏加载耗时(ms) | 内存占用(MB) | 缩放至 400% 后文字清晰度 | 支持 CSS 动态变色 | 支持点击节点触发 JS 事件 | 是否可被屏幕阅读器读取 |
|---|---|---|---|---|---|---|
| PNG | 86 | 4.2 | 模糊(像素化) | ❌ | ❌ | ❌ |
| Canvas | 152 | 11.7 | 清晰(重绘) | ⚠️(需重绘) | ✅(坐标映射) | ❌ |
| SVG | 43 | 2.8 | 清晰(矢量缩放) | ✅(原生) | ✅(原生 DOM 事件) | ✅ |
数据背后是根本性差异:PNG 是“结果快照”,Canvas 是“画布指令”,而 SVG 是“可编程文档”。这意味着 diagram-design 的 SVG 输出,天然具备以下不可替代能力:
样式即代码:你无需在 Mermaid 里写
style="fill:#ff6b6b",而是用外部 CSS 控制所有节点颜色。例如全局定义:.mermaid .node rect { fill: var(--primary-color, #4a90e2); } .mermaid .edgePath path { stroke: var(--line-color, #95a5a6); }当产品要求将所有图表主色从蓝色改为紫色时,你只需改一行 CSS 变量,而非遍历所有
.mmd文件重写fill属性。无障碍访问(a11y):SVG 支持
<title>、<desc>、aria-label等语义标签。我在为金融系统做合规审计时,曾被要求所有架构图必须支持屏幕阅读器朗读节点关系。PNG 完全无法满足,Canvas 需额外维护文本映射表,而 SVG 只需在 Mermaid 代码中添加注释:graph LR A["用户认证服务"]:::auth B["支付网关"]:::payment A -->|HTTPS/TLS| B classDef auth fill:#e6f7ff,stroke:#1890ff; classDef payment fill:#fff0f6,stroke:#eb2f96;Mermaid 渲染器会自动将
A["用户认证服务"]转为<title>用户认证服务</title>,配合aria-labelledby实现无障碍导航。动态交互无损:SVG 元素是真实 DOM 节点,可直接绑定
click、mouseover事件。我们给运维平台的拓扑图加了“点击节点查看实时指标”功能,核心代码仅 3 行:document.querySelectorAll('.node').forEach(node => { node.addEventListener('click', e => { const serviceName = e.target.querySelector('text').textContent; showMetricsPanel(serviceName); }); });如果用 PNG 或 Canvas,就得自己实现坐标映射、热区计算、状态同步——成本高出 5 倍以上。
跨平台保真度:SVG 是 W3C 标准,所有现代浏览器、Electron、QtWebEngine、甚至部分打印机固件都原生支持。我们曾用同一份
infrastructure.svg文件,同时用于:- Web 控制台(Chrome/Firefox/Safari)
- Windows 桌面客户端(Electron)
- Linux 监控大屏(Chromium Embedded Framework)
- PDF 报告生成(通过 Puppeteer 截图)
- 打印机直连输出(HP LaserJet 支持 SVG PCL6)
所有平台显示完全一致,无锯齿、无偏移、无字体缺失。而 PNG 在 Retina 屏上模糊,Canvas 在 Electron 中因 GPU 上下文切换偶发白屏,这些都是 SVG 规避掉的“非功能性陷阱”。
注意:SVG 并非万能。它不支持复杂滤镜(如模糊、阴影需 CSS
filter且兼容性有限)、不支持视频嵌入、对超大规模图(>1000 节点)渲染性能会下降。但我们做 diagram-design 时,应主动规避这些边界——例如用 Mermaid 的subgraph拆分巨图,用classDef统一管理样式,用click事件替代 CSS:hover实现交互。这才是工程师思维:不是“SVG 能做什么”,而是“如何用 SVG 的确定性能力,构建最简可靠的 diagram-design 流程”。
这也解释了为什么“svg本地查看工具”“svg-crowbar”会成为热搜词——它们不是玩具,而是 diagram-design 工作流中的关键补位工具。svg-crowbar是一个 Bookmarklet,一键提取网页中所有<svg>元素并下载为独立文件,让我们能快速备份生产环境渲染的图表;而“svg本地查看工具”如 VS Code 插件SVG Preview,则让我们在编写 Mermaid 时实时看到 SVG 效果,无需刷新浏览器——这些工具共同构成了“编码→预览→调试→交付”的闭环。
3. Mermaid:用文本契约替代图形契约的 DSL 设计哲学
Mermaid 常被误称为“流程图生成器”,但它真正的革命性在于:它用极简语法定义了一套人机共认的语义契约。你看这段代码:
sequenceDiagram participant A as Client participant B as API Gateway participant C as Auth Service A->>B: POST /login B->>C: validate token C-->>B: 200 OK B-->>A: JWT token它既不是伪代码,也不是配置文件,而是一个双向可逆的协议:人类能读懂其业务逻辑(Client 调用 Gateway,Gateway 验证 Token),机器能据此生成精确的序列图,且任何语法错误都会被编译器明确报错(如Error: syntax error in line 5, expected '->>' or '-->>')。这种“所写即所得、所得即所写”的确定性,正是 diagram-design 区别于传统绘图的核心。
我对比过 Mermaid 与 PlantUML、Graphviz、draw.io XML 的 DSL 设计:
| 特性 | Mermaid | PlantUML | Graphviz | draw.io XML |
|---|---|---|---|---|
| 学习曲线 | 极低(类自然语言) | 中(需记忆关键字) | 高(需理解 DOT 语法) | 极高(XML 结构复杂) |
| 语义明确性 | ✅(-->= 同步调用,-->>= 异步响应) | ⚠️(->和-->无区别) | ✅(->严格单向) | ❌(依赖 UI 操作隐含语义) |
| 版本控制友好度 | ✅(纯文本,git diff 清晰) | ✅(纯文本) | ✅(纯文本) | ❌(XML 冗余,diff 失效) |
| 与代码共存便利性 | ✅(.mmd可与.go同目录) | ✅(.puml同理) | ✅(.dot同理) | ❌(需导出/导入,破坏工作流) |
| 交互能力 | ✅(支持click事件绑定) | ❌(静态图) | ❌(静态图) | ✅(但需 JS SDK 介入) |
Mermaid 的胜利不在于功能多,而在于用最少的语法糖,覆盖最常用的 80% 图表场景。它的设计哲学是:“与其让用户记住 20 个绘图命令,不如让他用 3 个符号表达 90% 的关系”。例如:
-->表示“同步调用”,-->>表示“异步响应”,-.->表示“虚线依赖”——符号本身就在传递语义;classDef定义样式类,linkStyle设置连线样式,flowchart TD明确方向——关键词即意图;%% comment支持注释,%%{init: {"theme": "base"}}%%支持初始化配置——所有扩展都通过标准注释语法注入。
这种设计让 Mermaid 成为 diagram-design 的“汇编语言”:它不追求炫酷效果,但保证每一行代码都有确定含义,且编译失败时能精准定位到第几行第几个字符。我在带新人时,会让 TA 先用 Mermaid 写一段 5 行的流程图,再用 draw.io 画同样内容——通常 draw.io 耗时 8 分钟(找图标、对齐、调色),Mermaid 耗时 90 秒(敲代码、Ctrl+S、刷新),且 Mermaid 版本后续修改成本几乎为零。
更关键的是,Mermaid 的语法进化始终遵循“向后兼容优先”原则。从 v10 到 v11,新增了erDiagram(实体关系图)、stateDiagram-v2(增强状态图)、pie(饼图)等类型,但旧版flowchart TD代码无需修改仍可运行。这保障了 diagram-design 的长期稳定性——你十年前写的architecture.mmd,今天依然能在最新 Mermaid Live Editor 中完美渲染。
提示:Mermaid 的最大陷阱是过度定制。我见过团队为追求“美观”在 Mermaid 中硬编码
style="fill:#123456;stroke:#654321",结果主题色变更时要改 200 处。正确做法是:用classDef定义语义类(如classDef db fill:#e6f7ff,stroke:#1890ff;),再用class A,B db绑定节点。这样样式与语义解耦,符合前端工程最佳实践。
这也解释了为什么“mermaid live editor”“mermaid editor (离线版)”“mermaid 生成器网页版”会成为高频搜索词——它们不是简单编辑器,而是 Mermaid DSL 的即时反馈沙盒。Live Editor 的价值在于:你敲下graph LR,右侧立刻渲染,且错误时高亮行号;离线版(如 VS Code 插件)则让你在 IDE 中享受语法高亮、智能提示、错误校验——这和写 TypeScript 体验一致。真正的 diagram-design 工程师,不会离开编辑器去开另一个网页调试图表。
4. draw.io:当可视化编辑器成为 diagram-design 的协作枢纽
draw.io(现名 diagrams.net)常被看作 Mermaid 的对立面,但实际它是 diagram-design 生态中不可或缺的“协作翻译器”。Mermaid 擅长“人→机器”的单向高效表达,而 draw.io 擅长“人←→人”的双向可视化协作。两者不是竞争关系,而是互补:Mermaid 是源码,draw.io 是 IDE;Mermaid 是契约,draw.io 是谈判桌。
我参与过一个跨国银行的风控系统架构升级项目,涉及 12 个团队、37 个微服务、5 类数据流。初期我们用 Mermaid 写了 15 份.mmd文件,但业务方反馈:“看不懂箭头含义,不知道哪个框代表核心服务”。这时 draw.io 发挥了不可替代作用:
- 语义具象化:我们将 Mermaid 中的
A["Payment Service"]导入 draw.io,替换为带银行 Logo 的自定义图标,用不同边框粗细区分“核心服务”(3px)和“边缘服务”(1px),用颜色编码数据敏感等级(红色=PII,黄色=PCI,绿色=普通日志); - 上下文标注:在节点旁添加 sticky note,写明“此服务已通过 ISO27001 认证,SLA 99.95%”,这些信息无法也不应在 Mermaid 中编码;
- 多人协同批注:产品经理在
Auth Service节点上画红圈加批注:“此处需增加 OTP 二次验证”,安全专家回复:“已确认,将在 v2.3 版本实现”,这些讨论沉淀在 draw.io 的评论系统中,而非 Slack 群聊里消失; - 导出为多种格式:最终交付物包括:Mermaid 源码(供 DevOps 自动化)、draw.io 原文件(供业务方持续编辑)、PDF(供审计归档)、PNG(供 PPT 汇报)——同一份设计,多形态输出。
draw.io 的核心优势在于其开放架构:它本质是一个基于 Web 的图形编辑器,但所有操作都生成标准 XML(或 JSON),且支持插件扩展。我们曾开发一个内部插件,实现“Mermaid ↔ draw.io 双向转换”:
- 输入 Mermaid 代码 → 自动生成 draw.io XML,并保留
id映射(便于后续 diff); - 在 draw.io 中修改节点位置/样式 → 导出时自动更新 Mermaid 的
%% position注释(记录布局信息); - 当 Mermaid 源码变更 → 插件自动合并 draw.io 中的业务批注,避免人工同步遗漏。
这个插件让 diagram-design 流程从“先写代码再画图”升级为“代码与图形共生”。例如,当开发同学提交api-flow.mmd更新时,CI 会触发插件,将新 Mermaid 解析为 draw.io XML,与现有.drawio文件合并,再推送至 Confluence——业务方看到的永远是最新技术实现 + 最新业务解读的融合视图。
注意:draw.io 的致命误区是把它当“终极输出工具”。我见过团队用 draw.io 画完图,直接导出 PNG 插入文档,结果半年后服务重构,没人记得原始 draw.io 文件在哪,只能重新画图。正确姿势是:draw.io 文件必须和 Mermaid 源码一起纳入 Git 管理,且命名规则统一(如
auth-flow.mmd对应auth-flow.drawio)。这样即使 Mermaid 语法升级,也能通过插件批量迁移。
这也解释了为什么“next ai draw.io 是否支持与 hermes agent 对接?”会成为热搜问题——它触及 diagram-design 的未来:当 AI 成为设计协作者,draw.io 这类可视化编辑器就是最理想的 AI 交互界面。Hermes Agent(假设为某 AI 工程助手)可以:
- 读取
auth-flow.drawio中的节点关系,结合代码库分析,自动生成 Mermaidsecurity-review.mmd(标注潜在漏洞); - 接收自然语言指令:“把 Payment Service 迁移到 Kubernetes,更新所有连线为 HTTPS”,自动修改 draw.io 文件并生成变更 PR;
- 在评审会议中,实时将 draw.io 白板上的手绘草图,转换为可执行的 Mermaid 代码。
draw.io 的价值,正在从“绘图工具”升维为“AI 与人类协同设计的中间件”。它不取代 Mermaid,而是让 Mermaid 的抽象语义,获得可触摸、可讨论、可共识的物理形态。
5. 从 HTML 页面到完整 diagram-design 工程:一个可落地的最小可行架构
很多团队卡在“知道 Mermaid 好,但不知如何集成到日常开发”。这里给出一个经过 3 个项目验证的最小可行 diagram-design 架构,它不依赖任何云服务,全部基于开源工具链,可在 1 小时内完成搭建:
5.1 目录结构:让图表成为一等公民
my-project/ ├── docs/ │ ├── architecture.md # 主文档,内嵌 Mermaid │ └── diagrams/ # 图表源码专属目录 │ ├── service-dependency.mmd │ ├──>module.exports = { module: { rules: [ { test: /\.mmd$/, use: [ { loader: 'html-loader', options: { minimize: false } }, { loader: 'mermaid-loader', options: { theme: 'default', securityLevel: 'loose', // 允许内联样式 mermaidOptions: { startOnLoad: true, flowchart: { useMaxWidth: false } } } } ] } ] } };配套mermaid-loader(基于社区 loader 优化)会:
- 将
service-dependency.mmd编译为内联 SVG 字符串; - 自动注入 Mermaid JS 运行时(v10.9.3);
- 为每个图表添加唯一 ID,便于后续 JS 操作;
- 错误时抛出 Webpack Error,阻断构建(强制修复)。
这样,你在architecture.md中写:
## 服务依赖关系 ```mermaid graph TD A[API Gateway] --> B[Auth Service] A --> C[Order Service]Webpack 构建后,HTML 中直接生成<svg id="mermaid-123">...</svg>,无需额外 JS 初始化。
5.3 开发体验:VS Code 插件链打造无缝工作流
安装三个插件形成闭环:
- Mermaid Preview:右键
.mmd文件 → “Open Preview”,实时渲染; - Markdown All in One:在
.md文件中写 Mermaid 时,自动语法高亮 + 错误提示; - Prettier+prettier-plugin-mermaid:保存时自动格式化 Mermaid 代码(缩进、空行、排序)。
效果:写完>#!/bin/sh # 检查所有 .mmd 文件语法合法性 npx mermaid-cli -i docs/diagrams/*.mmd -o /dev/null --quiet || { echo "❌ Mermaid 语法错误,请修复后再提交" exit 1 } # 检查图表是否被意外删除(保护关键设计资产) if git status --porcelain | grep -q "D.*\.mmd$"; then echo "⚠️ 检测到 .mmd 文件被删除,请确认是否必要" read -p "继续提交?(y/N) " -n 1 -r echo [[ $REPLY =~ ^[Yy]$ ]] || exit 1 fi
这确保:任何语法错误无法提交;任何图表删除需人工确认——从源头杜绝“图表失联”。
5.5 生产交付:一份代码,多端输出
构建脚本build-diagrams.sh:
#!/bin/bash # 1. 生成 Web 可用 SVG(内联) npx mermaid-cli -i docs/diagrams/*.mmd -o docs/_static/svg/ --outputFormat svg # 2. 生成 PDF(供审计) npx mermaid-cli -i docs/diagrams/*.mmd -o docs/_static/pdf/ --outputFormat pdf # 3. 生成 PNG(兼容旧系统) npx mermaid-cli -i docs/diagrams/*.mmd -o docs/_static/png/ --outputFormat png --width 1200 # 4. 生成 PlantUML 兼容版本(对接遗留系统) npx mermaid-to-plantuml -i docs/diagrams/*.mmd -o docs/_static/plantuml/最终产出物:
/docs/_static/svg/:Web 页面直接引用的 SVG;/docs/_static/pdf/:architecture.pdf供合规部门存档;/docs/_static/png/:deployment-topology.png插入旧版 Confluence;/docs/_static/plantuml/:>RUN apt-get update && apt-get install -y fonts-noto-cjk && rm -rf /var/lib/apt/lists/*- 在 Mermaid 初始化中指定字体:
mermaid.initialize({ fontFamily: '"Noto Sans CJK SC", "Microsoft YaHei", sans-serif' }); - (推荐)用 Web Font 方案,避免依赖系统字体:
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet"> <style> .mermaid { font-family: 'Noto Sans SC', sans-serif; } </style> - 用
svg-sanitizer工具清理 draw.io 导出的 SVG:npx svg-sanitizer --input input.svg --output clean.svg --allow-styles --remove-script - 将清理后的 SVG 转为内联 Base64:
const svgData = `data:image/svg+xml;base64,${btoa(cleanSvgString)}`; viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(116.4, 39.9), billboard: { image: svgData } }); - 关键:禁用 draw.io 的“嵌入字体”选项(导出设置中取消勾选),改用系统字体。
- 渲染前设置 Mermaid 宽度:
mermaid.initialize({ flowchart: { useMaxWidth: false }, securityLevel: 'loose' }); - 在 CSS 中强制容器宽度:
.mermaid { max-width: none !important; width: 100% !important; } - Puppeteer 中设置足够宽的 viewport:
await page.setViewport({ width: 1920, height: 1080 }); await page.pdf({ format: 'A4', printBackground: true }); - 创建
mermaid-style-guide.md,规定:- 方向:一律用
graph TD(Top Down),除非有强理由; - 命名:服务名用
kebab-case(auth-service),不缩写; - 样式:只允许
classDef,禁止内联style=; - 注释:每图开头写
%% @author xxx和%% @last-modified 2024-06-15。
- 方向:一律用
- 用
prettier-plugin-mermaid统一格式; - 在 PR 模板中加入检查项:“✅ Mermaid 语法通过
npx mermaid-cli --validate”、“✅ 符合 style guide 第3条”。 - 改用
WebView2控件(推荐):webView21.Source = new Uri(Path.GetFullPath("diagram.svg")); - 若必须用 PictureBox,用
SvgNet库渲染:using (var svg = SvgDocument.Open("diagram.svg")) using (var bitmap = svg.Draw()) { pictureBox1.Image = new Bitmap(bitmap); } - 关键:SVG 中避免
stroke-width: 0.5,改用整数(1),GDI+ 对小数描边支持差。
6.2 坑:draw.io 导出的 SVG 在 CesiumJS 中不显示
现象:Cesium Viewer 加载 SVG 后空白,控制台无报错
根因:Cesium 默认禁用 SVG 中的<script>和外部资源引用(安全策略),且不支持<foreignObject>
解决方案:
6.3 坑:Mermaid 图表在打印 PDF 时被截断
现象:用 Puppeteer 生成 PDF,长流程图只显示前半部分
根因:Puppeteer 默认 viewport 宽度为 800px,Mermaid 自动换行导致高度溢出
解决方案:
6.4 坑:团队成员写的 Mermaid 风格混乱,难以维护
现象:service-flow.mmd中有人用graph TD,有人用graph LR,节点命名有的用DB,有的用Database
根因:缺乏代码规范,Mermaid 被当作文本而非代码
解决方案:
6.5 坑:WinForm PictureBox 加载 SVG 显示模糊
现象:.NET Framework 4.8 中 PictureBox 加载 SVG,放大后边缘锯齿
根因:PictureBox 使用 GDI+ 渲染,不支持 SVG 矢量缩放,而是光栅化后拉伸
解决方案:
这些坑的共同教训是:diagram-design 的成败,80% 取决于环境适配,20% 取决于语法正确。不要迷信“Mermaid 一次写成,到处运行”,必须针对每个目标平台(Web/桌面/GIS/打印)做专项适配。我现在的做法是:为每个平台建一个diagrams/platforms/子目录,存放专用版本的.mmd文件,并用脚本自动同步核心逻辑——这比试图写“万能 SVG”更可靠。
最后分享一个真实技巧:当客户要求“把这张图做得更专业”,我从不打开 draw.io 调色,而是打开diagrams/目录,找到对应.mmd文件,加一行%%{init: {"theme": "neutral"}}%%,再提交 PR。因为真正的专业,不是视觉华丽,而是图表与代码同源、同管、同质、同信——这,才是 diagram-design 的终极答案。