diagram-design 进阶指南:从代码化绘图到架构可视化体系
发布时间:2026/9/15 7:38:53 作者:尧图编辑部 阅读量:1,286

diagram-design 这个词你在 GitHub 上能看到一堆同名仓库在 Figma 社区里也能搜到同名插件但真要问一句“它到底是干什么的”十个人能给你八个答案。我自己折腾了几年架构图、流程图、时序图从最开始的 Visio 画到吐到后来用代码写图、用白板工具随手勾再到现在团队里把 diagram-design 当基础设施来搭最大的感受是图的本质不是“画得好看”而是“把关系说清楚”。这篇文章我不打算只聊某一个工具而是把 diagram-design 当成一个完整的技术方向来拆讲清楚它解决什么问题、有哪些靠谱的落地路径、实操中会遇到什么坑以及怎么在自己的项目里快速用起来。如果你正在做技术文档建设、系统设计评审、团队知识库整理或者单纯被“画图两小时、改动五分钟”折磨过这篇文章应该能帮上忙。我会从思路、工具选型、实操流程、踩坑实录四个角度展开尽量做到看完就能上手。1. 内容整体设计与思路拆解1.1 先想清楚你画的是图还是沟通协议很多人一上来就纠结用哪个工具其实顺序反了。diagram-design 的第一个核心问题不是“用什么画”而是“这幅图给谁看、回答什么问题”。我给团队做技术方案评审的时候最常遇到的情况是一张架构图塞了三十个组件、十几条箭头乍一看很唬人仔细看谁也不知道核心链路是什么。这就是典型的“把图当画来设计”而不是“把图当沟通协议来设计”。站在从业者的角度我把 diagram-design 的目标拆成三层记录把已经存在的系统结构、业务流程、接口关系固化下来方便后续查阅。推演在设计阶段用图来验证方案的可行性提前暴露依赖关系、单点故障、数据流向等问题。对齐让不同角色老板、产品、研发、运维在同一个视觉框架下达成一致减少口头沟通的模糊地带。这三层目标对应着不同的设计侧重点。记录型图表重准确性元素不能缺推演型图表重逻辑箭头方向和数据流向必须严谨对齐型图表重表达要控制信息密度突出关键路径。我自己踩过的坑是一上来就追求“全量全景图”结果图越画越大最后没人愿意打开看。后来我给自己定了一个规矩一张图只回答一个核心问题。如果你的系统复杂到一张图说不完那就拆成多张图用层级索引把它们串起来。1.2 为什么“代码化绘图”正在成为主流方案diagram-design 近几年最大的变化是“用代码写图”逐渐取代了“用鼠标拖图”。我能明显感觉到GitHub 上跟 diagram 相关的开源项目热度几乎都集中在 Mermaid、D2、Graphviz、PlantUML 这类代码驱动方案上。核心原因有三个版本管理图是跟随代码走的架构调整了图也要更新。用代码写图可以直接进 Git 做 diffreview 的时候一眼就能看出改了什么。而拖拽画图工具导出的文件基本没法做有意义的差异对比。自动布局手拖图的痛点是“挪一个方块所有线都要重拉”。代码化绘图把布局算法交给了工具你只需要描述节点和关系工具帮你算位置。虽然不算完美但大多数场景够用。复用和生成代码是文本可以被脚本批量处理。比如我写了一个 Python 脚本扫描 Kubernetes 的 Ingress 配置自动生成服务调用关系图——这种能力是手动画图永远做不到的。当然代码化也不是银弹。它的学习曲线比拖拽工具陡自由排版能力也差一些。我的经验是双轨并行正式文档里的架构图、时序图用代码写方便维护头脑风暴、方案速写用 Excalidraw 这类白板工具追求的是快和随意。1.3 信息架构好图是“设计”出来的不是“画”出来的如果把 diagram-design 当成一门设计学科来看它跟 UI 设计有相通之处都在处理信息层级、视觉节奏、注意力引导。我画图之前会先列一个信息清单这个习惯是从写技术方案文档带过来的核心实体有哪些实体之间的关键关系是什么依赖、调用、继承、聚合……哪些是读者必须第一眼看到的哪些是细节可以折叠或用注释标注然后才是视觉设计的部分。这里我借鉴了一些平面设计的基本原则用颜色区分层级但一个图里不超过三种主色用箭头粗细表达流量主次用分组边框表达边界和归属。这些说起来都是基本功但实际见过太多图是“五彩斑斓的黑”——颜色用得越多信息传达效率越低。2. 核心类型解析与工具选型要点2.1 搞清楚你需要的图属于哪个类别diagram-design 不是一个单一的图形类型而是一整族视觉表达方式的集合。把类型搞混后续一切的选型都会跑偏。按我日常的高频用途可以分成四类图形类型表达重点典型场景我的常用工具流程图步骤顺序、分支判断业务流程、算法逻辑、部署流程Mermaid、D2架构图系统组件、层次关系、部署边界系统设计、微服务架构、运维拓扑D2、Structurizr时序图对象间消息交互的时间顺序API 调用链、协议握手、用例交互Mermaid、PlantUML关系图实体间的关联、依赖、网络结构数据模型、依赖图谱、组织架构Graphviz、Cytoscape有一个很容易被忽视的点同一个工具在不同图形类型上的表现力差距极大。比如 Mermaid 的流程图和时序图都很好用但画复杂架构图时布局控制力就偏弱Graphviz 的图论布局算法很强大但默认样式很丑需要花心思调样式。所以正经做 diagram-design通常不是“只用一个工具”而是“按图选工具”。2.2 代码化绘图工具怎么选这块我把市面上主流的方案都试过一遍说点真实体会。Mermaid应该是目前生态最火的选择。优点是语法简单、十分钟就能上手而且 GitHub 原生支持、Notion 内置、各种文档平台都嵌入了它的渲染引擎。缺点是复杂布局控制力有限节点坐标基本不可控遇到精英网状的复杂调用关系会乱成一团。D2是这几年的新秀定位是“现代声明式图表语言”。它的语法也很简洁但布局引擎比 Mermaid 聪明尤其是画架构图时能自动做容器分组和边界计算。C4 风格的架构图用 D2 来画非常顺手。缺点是生态还在成长社区模板和示例比 Mermaid 少很多。Graphviz是老牌经典核心思想是“描述图结构由布局引擎自动计算位置”。它的 dot 语言功能非常强大适合画依赖关系图、状态机图。但默认输出确实丑而且学习曲线比较陡那套属性语法够你研究一阵子。PlantUML在 Java 生态里地位很高尤其是时序图和活动图的语法设计得很优雅。缺点是渲染速度偏慢遇到大图容易卡。Structurizr是 C4 模型的开源实现严格来说它不是画图工具而是一个“把架构描述成代码”的 DSL。它的思路是你先用代码定义系统、容器、组件、人与人之间的关系然后工具自动生成多层级架构图。适合做长期演进的架构治理但初期投入成本比较高。我把选择逻辑整理成一个简单判断只是想快速画图、发给别人看 → Mermaid认真做架构文档、希望自动布局好看 → D2画数据关系/依赖图谱、需要算法布局 → Graphviz团队协作、长期维护架构资产 → Structurizr2.3 白板和手绘类工具的价值不可替代代码化方案讲了这么多但我不建议完全抛弃手动工具。diagram-design 里有一部分工作是“探索性”的这时候用 Excalidraw、draw.io、Figma 反而效率更高。Excalidraw 是我个人最常用的速写工具。它的手绘风格天然带一种“草稿感”反而降低了读者对美观度的预期让人更聚焦内容本身。画架构草图、画方案对比、画 UI 线框图都非常好用。而且它支持端到端加密的多人协作临时拉个链接就能一起画。draw.io现在叫 diagrams.net是老牌免费方案胜在功能全面、支持离线、集成丰富。VS Code 有它的插件可以直接在编辑器里编辑 .drawio 文件。不过界面确实有点老旧但作为免费工具已经很良心了。说一个我的工作习惯探索阶段用 Excalidraw最终沉淀到文档里用 Mermaid 或 D2。前者是用来“想”的后者是用来“存”的。两个用途不要混在一起否则你会在“追求美观”上浪费大量时间。3. 实操过程从零到一搭一套可演进的 diagram-design 工作流3.1 搭建本地绘图环境实操这部分我会以“在 VS Code 里用 Mermaid 画图并沉淀到项目文档”为主线因为这是上手成本最低、收益最明显的一条路径。首先需要准备环境。我用的是 VS Code配合官方插件安装 VS Code 后在扩展商店搜索Mermaid安装支持 Mermaid 的 Markdown 插件我推荐 Markdown Preview Mermaid Support也有集成度更高的 mermaid-in-editor 之类的插件按喜好选就行。准备一个测试用的.md文件写一个基本示例# 订单模块流程 mermaid graph TD A[用户提交订单] -- B{库存校验} B --|通过| C[创建订单] B --|不通过| D[返回错误] C -- E[支付] E -- F[完成]3. 打开 Markdown 预览正常的话就能看到自动渲染出来的流程图。 这个流程本身很简单但我还是要强调“环境即工作流”的思路。把绘图语言嵌入 Markdown 文档意味着图表跟文档正文共用一个文件、同一套版本管理、同一个 review 流程。技术人员在看设计文档的时候改了代码顺手把图也改了而不是等到文档评审前临时补一张架构图然后很快就过期了。 ### 3.2 用 D2 画一张可读性更高的架构图 如果你对图表的美观度有更高要求我建议直接学 D2。它的上手成本跟 Mermaid 差不多但默认样式的专业感高出一大截。 安装 D2 很简单macOS 上可以直接 brew install d2或者下载预编译二进制。装完以后写一个 architecture.d2 d2 direction: right 用户: 用户端 网关: API 网关 服务A: 用户服务 服务B: 订单服务 服务C: 库存服务 数据库A: 用户库 数据库B: 订单库 数据库C: 库存库 用户 - 网关: HTTPS 网关 - 服务A: gRPC 网关 - 服务B: gRPC 网关 - 服务C: gRPC 服务A - 数据库A 服务B - 数据库B 服务C - 数据库C在终端执行d2 architecture.d2 architecture.svg生成 SVG 之后可以直接放进文档或 PPT。D2 会自动做容器布局和连接的排线画出来的效果比我手拖出来的还整齐。这里有一个实用技巧D2 支持把对象嵌套到容器里用来表达“服务部署在哪个环境”非常直观云环境: { K8s集群: { 服务A 服务B } RDS: { 数据库A 数据库B } }用这种方式架构图天然就有了“环境边界”这一层语义读者一眼就能看出哪些组件在同一个部署单元里这是传统手绘拖拽很难表达的。3.3 用 Mermaid 画时序图梳理接口调用时序图在技术文档里出现频率极高因为它能讲清楚“谁先调谁、消息长什么样、异常怎么走”。Mermaid 的时序图语法非常直观基本就是“参与者 实线/虚线 消息描述”。我举一个真实的例子排查支付回调幂等性问题时我用时序图把正常回调、重复回调、超时补偿三条路径画在一起问题瞬间就清晰了。sequenceDiagram participant C as 客户端 participant G as 网关 participant P as 支付服务 participant O as 订单服务 participant DB as 数据库 C-G: 支付请求 G-P: 转发支付 P-P: 幂等校验 P-O: 异步回调 O-DB: 更新订单状态 O--P: 确认收到 P--C: 返回支付结果画这种图有一个需要注意的逻辑要点谁发起调用谁就是箭头起点。很多人画时序图喜欢按“数据从哪来”当起点结果把箭头方向画反看的人要猜很久。时序图表达的是“控制权转移”不是“数据流向”。3.4 让图表纳入文档自动化流水线单张图画得再好如果不能跟文档构建流程打通最终也难逃“过期”的命运。我的做法是把绘图文件的生成纳入 CI/CD 流程。具体来说在docs/diagrams目录下维护.d2或.mmd源文件。通过 pre-commit 钩子或 CI 任务自动把源文件编译成 SVG/PNG。生成的图片输出到docs/assets然后在 Markdown 文档里引用。这样团队在改架构的时候只需要改.d2源文件提交时 CI 会重新渲染图片文档站点自动更新。这个流程的核心价值是图跟上代码节奏而不是靠人记忆去维护。如果你用 D2GitHub Actions 里可以这样简写- name: Render D2 diagrams run: | for file in docs/diagrams/*.d2; do d2 $file docs/assets/$(basename ${file%.d2}).svg done放到docs构建的上游就完成了自动化。对于小团队来说这十分钟的配置投入回报是长期不用再为“文档图和代码不一致”吵架。4. 常见问题与排查技巧实录4.1 Mermaid 中文乱码与样式问题Mermaid 在中国开发者这里最常见的问题就是中文乱码。这个问题的根源不在 Mermaid 本身而在渲染环境的字体配置。浏览器渲染时如果找不到合适的中文字体就会显示成豆腐块。我的排查套路是先确认用的是什么渲染器。VS Code 的 Markdown 预览用的是系统字体一般没这个问题但如果用 Puppeteer 做服务端渲染导出图片就非常依赖容器的字体。Docker 环境里记得装中文字体比如fonts-noto-cjkDebian/Ubuntu 系或者wqy-zenhei。如果还是乱码检查一下 HTML 容器的lang属性和 CSS 的font-family把中文字体显式指定上去。另一个高频问题是graph TD默认布局下节点挤压。我的经验是节点文字里不要塞太多内容每个节点只放核心关键词细节放段落里解释。实在控制不住可以给出节点样式配置graph TD A[下单] -- B[支付] B -- C[发货] style A fill:#e1f5fe,stroke:#0288d1 style C fill:#c8e6c9,stroke:#388e3c适当用颜色区分状态图表会好读很多。4.2 布局乱成一团代码图不是万能的代码化布局算法虽然方便但遇到节点太多、连线交叉密集的图效果往往不尽人意。我画微服务调用关系图的时候踩过不少坑——画三四十个服务节点布局算法排出来的图跟蜘蛛网一样完全没法看。这时候我会回头审视一个问题是不是一张图承载了太多信息一个比较实用的解决方案是分层拆分。把“所有服务的调用关系全景图”拆成“按领域拆分的多张局部图”再加上一张“领域间依赖的粗粒度图”。从可读性来讲一张不完美的局部图比一张完全准确的蜘蛛网要有用得多。另外也可以利用 Mermaid 的subgraph显式分组把相关的节点包在一个组里让布局引擎先做组内排布再做组间排布graph TD subgraph 订单域 A[订单服务] B[支付服务] end subgraph 库存域 C[库存服务] end A -- C B -- A4.3 导出图片模糊或空白导出环节最容易出问题。很多人写好了 Mermaid想在文档里放高清大图却发现导出 PNG 模糊或者白屏。Mermaid CLImmdc导出高清图的参数我常用的有两种mmdc -i input.mmd -o output.png --scale 3 mmdc -i input.mmd -o output.svg用--scale 3可以放大渲染分辨率适合输出到 PPT 或印刷。如果导出 SVG 后图片空白通常是渲染引擎或权限问题。这时候优先检查 CLI 的版本是否跟 mermaid 内核版本匹配mmdc的版本迭代很快旧 CLI 配新语法是兼容性问题的重灾区。另外一个容易被忽视的点很多图表平台如 GitHub对 Mermaid 的安全策略越来越严某些你可能已经习惯的“前端交互语法”在平台上会被屏蔽。所以重要的图建议在本地渲染成 SVG 再提交到文档而不是依赖平台动态渲染。4.4 团队协作时“图的分歧比代码还多”最后说一个团队层面的问题这其实是我写 diagram-design 这么久以来觉得最有价值的部分。代码有编译器和 linter 做强制约束图没有。一个人画图的时候节点叫“用户服务”另一个人叫“User Service”第三个人叫“用户端”一张架构图里三个名字一混读者就懵了。我的建议是给团队定一套“图形元素命名规范”哪怕只有一条也行所有系统/服务必须使用官网或代码仓库中的统一名称不能自创简称。方向定义要统一箭头统一表示“调用/依赖方向”如果没有特殊说明时间流默认从左到右、从上到下。颜色语义要统一红色只能表示异常或重点警示绿色只能表示正常或已实现灰色表示规划中。如果颜色不统一图表的表达力会大打折扣甚至误导人。这些规则听起来很基础但效果立竿见影。我们团队用了这套规范之后图表的 review 成本大幅下降大家把精力放在“画得对不对”而不是“画的什么玩意儿”。5. 从图到体系diagram-design 的进阶方向5.1 用 C4 模型解决“一张图说不清”的难题前面提到过 Structurizr背后是 Simon Brown 提出的 C4 模型。它的核心思想是不要试图用一张图描述整个系统而是用四个层级来递进表达Context语境系统在人、外部系统之间的位置。Container容器系统由哪些可独立部署的进程/存储组成。Component组件容器内有哪些主要模块。Code代码组件内部的关键类或接口关系这一层一般仅在必要时画。这种分层思路对设计文档的演进特别友好。我也是在自己设计一个中大型系统时开始用 C4发现它给我最大的启发不是“多了一种画图方式”而是逼我先想清楚“我到底在哪个层级讨论问题”。日常讨论系统时很多人把“网关调用用户服务”这种容器级关系和“用户服务内部有 controller/service/mapper”这种组件级关系混在一张图里讨论永远吵不清。C4 模型天然规避了这个问题。如果你不想引入 Structurizr 的重型 DSL用 D2 手动维护 C4 分层图也很容易。第一张图只画“用户、企业系统、我们的系统、第三方支付”第二张图再展开容器第三张图展开组件每张图信息密度都不高但合在一起能把系统讲透。5.2 让图“活”起来从静态图到交互式图表diagram-design 还有一个容易被忽视的进阶方向是让图表从静态文件变成可交互的信息系统。大概两年前我用过 Mermaid 的点击事件能力让图中的节点可跳转。它的基本用法是graph LR A[订单服务] -- B[订单数据库] click A href https://github.com/org/order-service _blank这样架构图就变成了一个导航入口看文档的人点节点就能跳到对应代码仓库或详细设计页。在内部 wiki 系统里这种体验比翻目录高效得多。更进一步如果团队有自己的前端开发资源可以考虑 D3.js 或 AntV G6 这类可视化库。它们已经不是“画图工具”的范畴而是图表可视化开发框架能实现拖拽、缩放、聚焦高亮、实时数据绑定等能力。我自己用 G6 做过一个服务依赖排查工具把 SkyWalking 的调用链数据拉下来实时渲染成依赖图点击服务节点能看到上下游所有依赖——这在生产环境的故障排查中帮了大忙。当然G6 的接入成本比 Mermaid 高一个数量级适合属于“图的消费者较多、且存在动态变化”的场景比如监控大屏、运维拓扑、数据分析平台。如果你只是写技术文档完全没必要上这种重量级方案。5.3 与 AI 结合自然语言生成图的边界最后提一嘴 AI 生成图表的现状。说实话现在用 LLM 生成 Mermaid 代码已经很成熟了。你让 AI “画一个用户下单的序列图”它通常能给出基本可用的 Mermaid 代码。我也经常用这种方式快速生成初稿再手动调整逻辑和细节。但要泼一盆冷水AI 能生成“像样的图”但很难生成“对的图”。因为它不了解你系统里真正的服务名称、依赖关系、异常分支它只会根据训练数据里的常见模式来猜测。所以我的建议是把 AI 当加速器不要当设计者。用 AI 搭骨架、出草稿用人的领域知识去修正和定稿这才是目前性价比最高的模式。我也测试过让 AI 直接生成 D2 或 Graphviz 代码效果比 Mermaid 稍弱因为这类语言生态小、训练语料少但是基本的结构生成问题不大。近一年这个方向的迭代速度很快说不定再过段时间AI 生成图的准确度会有明显提升到时 diagram-design 的入门门槛会更低但设计判断力依然是人类的价值所在。写到这里我想起自己最开始折腾 diagram-design 的动机。当时团队刚拆微服务系统一多文档里的架构图全过期了没人说得清服务间到底谁调谁。我就花了一个周末研究 Mermaid 和 D2把核心链路都画了出来又设计了一套自动化渲染的流程。之后每次系统演进我都逼自己同步改图。这个习惯一开始很别扭但坚持几个月后我再也不需要靠脑子记整个系统的结构翻开文档看图就行。我个人最大的体会是diagram-design 的难点从来不在工具而在于你有没有把“信息准确、层级清晰、表达克制”当回事。工具最多帮你把线画直但把哪两个点连起来、用什么颜色、以什么层级呈现永远是需要人来判断的。如果你也想在团队里落地这套思路别贪多挑一个工具从一张核心架构图开始。画完以后问自己一个问题一个刚入职的新人不看任何代码只看这张图能不能复述出系统里有哪些模块、它们之间怎么协作如果能这幅图就成功了。