news 2026/10/17 11:19:32

代码化图表设计:让架构图、流程图和ER图成为可维护的代码

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
代码化图表设计:让架构图、流程图和ER图成为可维护的代码

今天想认真聊聊 diagram-design 这个技术实践。简单说,它属于“用代码来画架构图、流程图、这些日常要用的图”这一大类需求。说得白话一点,就是把以前在画布上拖拽方框、连线的方式,换成写文本、跑命令、出图的方式,让整套流程图设计变成可版本管理、可评审、可自动生成的内容。这篇文章适合每天要和系统架构图、时序图、ER图打交道的开发、运维和文档工程师;也适合团队里负责技术方案评审、外包交付说明的朋友。我会从为什么值得做、工具怎么选、实际怎么操作、踩过哪些坑这几个角度,把自己这几年的真实经验拿出来讲透。

1. 先聊清楚:代码化图表设计到底解决了什么问题

1.1 从“画完就过期”到“图表即代码”

以前在图形界面里画架构图,流程大概是:新建画布,拖一个框写着「Nginx」,拖一个框写着「后端服务」,连线,标注端口号,导出图片,贴进文档,完了。这套流程最大的问题是“维护”。线上架构改了一次,负载均衡多了一层,数据库读写分离了,文档里的图还是三个月前那张。因为改图成本高——打开文件、找图层、调整连线、重新导出——人一旦懒下来,图就和现实脱节了。

我后来彻底换了个路子:所有图都用文本描述,交给渲染引擎出图,源文件进代码仓库。架构变了,就改几行文本,提交一个 commit,图自然就跟着变。这背后其实就是“图表即代码”的思路:图不再是某个图形文件,而是一段文本;文本可以用 diff 对比,可以走 code review,可以在 CI 里做语法校验。

用一个生活化的类比。以前画图相当于手写笔记:写错了要涂改,重写整页;改多了笔记一团乱。代码化图表相当于在电脑上打 Markdown:改一个字是一瞬间的事,历史版本都在,谁改了什么看得一清二楚。对于团队协作来说,这个差别是天壤之别。

1.2 什么场景真的值得用,什么场景千万别用

不是说所有图都应该代码化。我自己的判断标准就一条:这张图需不需要持续维护?如果它是一次性输出,比如给汇报 PPT 画一张概念图,那用图形工具拖一拖,调调颜色,三分钟搞定,没必要写代码。

需要长期维护、多人协作、频繁变更的图,代码化就非常香。系统部署架构图是最典型的例子。我们团队有一个几十个节点的微服务架构图,工具里拖拽编辑一次要一个上午;改成分段描述之后,加一个服务只需要加三行,删一个服务只需要删三行。加上代码评审流程,架构调整被卡在评审阶段就发现,根本不会出现“图早就跟不上了”的情况。

下面是几个典型的适用场景:

  • 系统架构图:部署拓扑、服务调用关系、网络分区关系
  • 时序图/流程图:业务流程、接口调用链、状态机流转
  • ER图:数据库表关系,尤其是需要跟表结构定期同步的场景
  • C4 model 架构描述:用代码维护多级别的架构视图,从系统上下文到类级别

不适合的场景也很明显:你觉得图形引擎的默认布局不能满足你的审美,你必须精确控制每个节点的像素位置,那代码化路线会让你非常痛苦;做数据可视化的复杂图表,比如热力图、桑基图,需要处理大量真实数据,应该直接用专业可视化库;还有画营销海报这样的创意设计,那是设计工具的范畴,跟 diagram-design 半毛钱关系都没有。

2. 工具选型:主流图表方案横向对比与取舍

2.1 Mermaid:易写、生态好、内存友好

Mermaid 是目前最流行的代码画图工具,它的语法非常接近 Markdown,学习成本几乎为零。不需要安装软件,在浏览器里就能跑官方 live editor,渲染一块图就是敲几行文本的事。GitHub 的 Markdown 原生支持 Mermaid 代码块,这给技术文档带来了很大的便利。

它支持的图类型也很全面:流程图、时序图、类图、状态图、甘特图、ER图、需求图、饼图、思维导图。我最常画的是部署架构图和状态流转图,子图语法可以快速把「网关层」「服务层」「存储层」这些区域拢在一起。

Mermaid 的劣势在于对复杂图的布局控制力较弱。图一复杂,节点一多,默认布局可能产生很多交叉线;它不支持手动锁定节点坐标。所以我的经验是:Mermaid 适合中型复杂度、强调快速迭代和文档内嵌的场景。

2.2 PlantUML:序列图老牌劲旅

PlantUML 也是基于文本的绘图工具,跟 Mermaid 是竞品的关系。它的强项是时序图和 UML 全套图。我的感觉是,如果你所在的团队之前用的是 UML 方法论,那 PlantUML 的语法风格会让你更有亲切感。它支持 skinparam 和 theme 做全局主题定制,对细节样式控制比 Mermaid 强一些。

PlantUML 用起来有两个小门槛:一是需要 Java 环境,初次环境配置比 Mermaid 慢;二是在中文字体渲染、导出图片样式上,偶尔会遇到字体问题,需要额外指定 font。不过这些年用下来,稳定性其实很好。

坦率说,如果今天从零开始选型,Mermaid 会因为生态和易用性占一些优势;但 PlantUML 在 UML 图和复杂序列图这个专项领域仍然值得驻足。

2.3 Graphviz:老而弥坚的“骨架”引擎

Graphviz 严格来说不是画图工具,而是一个“布局引擎”,它接受 DOT 语言描述的图结构,然后通过算法自动计算节点坐标。它擅长渲染有向图、无向图,核心优势是布局算法的成熟度。复杂的依赖关系图,用 Graphviz 处理出来的效果往往比 Mermaid 更好。

但 Graphviz 有个学习曲线:DOT 语言语法跟 Mermaid 不是一个路子,刚上手会觉得别扭。而且 Graphviz 的节点样式比较朴素,四周的边距、字体默认值都需要调。它更像一个底层引擎,适合做自动化批处理:比如从代码扫描依赖关系,批量生成模块依赖图。

给一个简单的 DOT 示例:

digraph G { rankdir=LR; A -> {B, C}; B -> D; C -> D; D -> E; }

这段描述的是 A 触达 B 和 C,B、C 都指向 D,D 再指向 E。引擎会自动排列节点位置,减少交叉。这个“由引擎自动排布”的思路,也是 diagram-design 这个方向很重要的一个根基——图的质量不应该靠手调,而应该靠算法保证基本盘。

2.4 draw.io / Excalidraw 等图形化工具的补充定位

我并不是说图形化工具不能用了。恰恰相反,draw.io 和 Excalidraw 这类工具应该留存在你的工作流里,只是定位不同:它们是思考工具,不是交付工具。

做架构方案的时候,一开始脑子里的结构是模糊的,在白板上随手画一画,比敲代码快得多。这个阶段是“从混沌到条理”,用 Excalidraw 的手绘风白板流程,可以让思路快速成形。真正把方案确定了、要固化到文档里的时候,再用 Mermaid 或者 PlantUML 敲一份正式交付图。

四类工具的定位微妙不同,我做了个速查表:

工具核心强项适用场景我的主观评分(5分制)
Mermaid易学、生态好、原生支持广文档内嵌、快速制图4.5
PlantUMLUML规范完整、序列图专业规范UML图、复杂时序4.0
Graphviz布局算法强、适合自动化依赖图、批量生成4.0
draw.io / Excalidraw自由排版、视觉可控头脑风暴、一次性示意图4.0(定位不同)

选工具别上来就抠功能,先看你最常画的是哪种图,再决定主工具:常画架构图和状态图,选 Mermaid;常画时序图和类图,选 PlantUML;要做自动化批量出图,Graphviz。

3. 实操:用 Mermaid 从零搭建一张部署架构图

3.1 核心语法快速入门

Mermaid 的流程图语法是学习成本最低的。用flowchart LR或者graph LR声明,方向从左到右;TB声明从上到下。节点和连线的写法很直观,我用一张实际部署架构图来演示。

下面这段描述一个典型的 Web 前后端架构,包含负载均衡、前端、后端、数据库、缓存:

flowchart LR subgraph Edge[边缘接入层] LB[负载均衡] end subgraph App[应用层] FE[前端应用] BE[后端服务] end subgraph Data[数据层] DB[(MySQL)] RC[(Redis)] end User[用户] --> LB LB --> FE LB --> BE FE --> BE BE --> DB BE --> RC

这里几个语法点值得强调:

  • 节点后面跟方括号[文本]表示矩形节点;跟圆括号(文本)表示圆角矩形;跟花括号{文本}表示菱形(判断节点);跟双括号[(文本)]表示圆柱体,也就是数据库。
  • -->是实线箭头,---是普通实线;-.->是虚线箭头;==>是粗实线箭头。
  • subgraph可以把一组节点聚合成一个区域块,在架构图里就是分层的核心手段。

看这张图就能明白:用户经过负载均衡,分流到前端和后端,再分别访问数据库和缓存。整张图只有几十行文本,但表达的信息密度远超手画图。

再给一个带条件分支的流程图例子:

flowchart TD A[收到请求] --> B{是否登录} B -- 是 --> C[执行业务逻辑] B -- 否 --> D[跳转登录页] C --> E[返回数据]

这里的B{是否登录}是判断节点,连线上可以加文字标签,用-- 文本 -->或|文本|都可以。

3.2 连线方向和子图划分里的门道

很多人照着 Mermaid 文档写的图不难看,但一复杂就乱。问题往往出在连线的方向定义上。Mermaid 有两种声明方式:graph TD代表从上到下,graph LR代表从左到右;在复杂图里混用方向很容易打造灾难布局。

我自己的经验是:框定整体方向后,子图内部的方向尽量跟全局保持一致。 比如一张系统架构图全局我用LR,让用户流从左到右推进;子图内部如果节点关系是层级调用,可以单独用TB组织,但不要让一条长连接横穿多个 subgraph,这会直接导致边缘交叉混乱。

另外要给子图起有意义的名字。subgraph App[应用层]里的App是节点表中的标识符,[应用层]是渲染出来显示的文字。如果不写方括号文本,图上就会显示英文标识符,中文环境下观感差很多。

对节点数量的控制,我的经验是:一张流程图里的节点控制在 10-15 个以内。超过这个数字,布局算法的交叉率会急剧上升。如果架构里的节点真的很多,应该按层或按模块拆成多张图,用「总图 — 分图」的方式组织,而不是硬塞进一张。

3.3 样式定制:把重点节点“标”出来

默认渲染的图形颜色比较素,所有节点都是一个色。我可以接收,但在技术评审时,大家更愿意看到重点分层的节点有个颜色区别。Mermaid 提供了classDef语法,用于给节点定义样式:

flowchart LR classDef gateway fill:#f9f,stroke:#333,stroke-width:2px classDef service fill:#bbf,color:#fff classDef storage fill:#bfb LB[负载均衡]:::gateway BE[后端服务]:::service DB[(MySQL)]:::storage

:::gateway这种写法把节点归入 gateways 类;classDef gateway fill:#f9f定义了填充色。实际操作里,我会统一三类颜色:网关层用浅紫底色,服务层用浅蓝,存储层用浅绿。颜色不是装饰,是为了让看图的人一眼建立「层」的认知。

除了颜色,还有两个实用技巧:

  • 点击跳转:在 Mermaid 节点上可以挂点击事件,把节点链接到对应服务的文档页。语法是click BE "https://example.com/docs/backend"。在演示环境里,别人点一下架构图的节点就能直接进到服务说明,体验远超静态图。
  • 备注:节点上可以加classDef之外的备注,连线上建议只标注必要信息(端口号、协议、数据量),不要什么信息都塞在线旁边。

4. 进阶玩法:把图表做成团队的“活文档”

4.1 文档内嵌与渲染链路

代码化图表最舒服的落地场景就是嵌入文档。在 GitHub 上写 Markdown 文档,直接放一个 mermaid 代码块,页面会自动渲染。不需要配套任何工具链,也不需要安装插件。

但本地工作流里,我们经常需要生成图片文件,用于技术评审附件、外包交付说明和演示 PPT。这时候需要一个渲染命令行工具,我们会用 Mermaid CLI,它可以把一个.mmd文件导出成 PNG 或 SVG:

mmdc -i architecture.mmd -o architecture.png -w 1600 -b white

参数-i指定输入文件,-o指定输出文件,-w设置图片宽度,-b设置背景色。导出时建议主题统一,我们通常在.mmdc.json里配置默认主题和字体:

{ "theme": "neutral", "fontFamily": "PingFang SC, Microsoft YaHei, sans-serif" }

导出 PNG 有个坑:中文字体渲染。如果你的命令行环境里没安装中文字体,渲染出来的图就是方块。解决方法是让系统装上字体,或者在配置里指定字体族。

4.2 CI 里做图表语法校验,杜绝“破图”入库

团队协作里经常出现一种尴尬:代码评审的时候有人改了一个 mermaid 文本,缩进错了一位,或者引号不匹配,图表直接渲染失败,整个页面碎掉一块。这种问题靠人眼很难及时发现,因为评审人往往注意看文字内容,不太注意图形是否正常。

解决思路是把图表校验放进 CI。我们用的 GitLab CI 和 GitHub Actions 里,都有一条流水线专门跑 Mermaid CLI 的-c模式,或者用专门的 Mermaid lint 工具来校验所有.mmd文件和 Markdown 里的 mermaid 代码块。语法有问题,构建直接标红,开发者必须修复之后才能合并。

这个做法带来的收益是:架构图和代码是同一套质量门槛。「坏图」没办法进入主干,整个文档体系的可信度就会高很多。

4.3 从数据库 Schema 反向生成 ER 图

数据库表关系图是「活文档」需求的另一个高发区。表结构一变,图很容易没跟上。代码化思路在这里同样能发挥作用:基于数据库连接信息反推表结构,自动生成 mermaid 的 erDiagram 代码。

例如,用某个数据库工具直接分析连接串,就能生成:

erDiagram CUSTOMER ||--o{ ORDER : places ORDER ||--|{ ORDER_ITEM : contains ORDER_ITEM }|--|| PRODUCT : "ordered"

这种动态生成的 ER 图,最大的价值在于“不会过期”——表结构调整之后,重新跑一次生成脚本,图就同步更新了。把生成过程放在 CI 里,每次表结构变更合并时自动刷新文档,业务方和开发方永远看到同一份模型定义。

4.4 技术评审和演示中的“讲图”能力

工具和语法都只是基础,真正加分的是“讲图”能力。我见过不少团队,代码化图表玩得很溜,但评审的时候只是把图贴出来,没人讲解。图是静态的,但图的阅读路径和关键节点需要有意识地设计。

我的习惯是:

  • 每张架构图配一小段说明文字,讲清楚“主路径”是哪条“链路”。比如用户请求经过网关流转到服务层的路径,用文字一行行带出来。
  • 在评审时,按照代码图里从入口到出口的顺序讲,而不是随机跳跃。
  • 这张图的“变化点”要有颜色标识。新加的服务标红,删除的组件用灰色虚线表示,评审人打开图就能锁定改动区域。

这样,图就不再是文档里的一件装饰品,而是评审讨论的主线。

5. 常见问题与踩坑实录

5.1 图太大,渲染出来严重挤压走形

Mermaid 渲染大量节点的时候,默认布局会出现节点交叉、过长边、无法直视的情况。这是我们最常遇到的坑。

首先是布局方向。流程图从LR改到TB可能产生完全不同的效果。图偏宽就换TB,偏长就换LR,优先保证长边在横向或纵向都顺眼。

然后是合并同类节点。多个业务模块共用同一个依赖,可以把它们放进一个 subgraph,减少全局里的“飞线”。再者,使用direction TB或direction LR指令在子图内部指定方向,甚至可以部分缓解布局混乱。

如果图节点实在太多,拆图是唯一最优解。架构总图只放分层和关键链路,每一层的细节单独出一张图。这样既能保持阅读体验,也能让每张图在后续维护中保持可管理的大小。

5.2 中文乱码和字体设置问题

中文字体问题在导出 PNG 和 SVG 时出现得最多。在浏览器里渲染,基本不需要处理字体问题;但命令行导出会遇到系统缺字体的情况。

我的处理方案很朴素:在渲染环境的系统里装好「Noto Sans CJK」或「思源黑体」,并在 Mermaid 配置里指定所用字体。然后导出的前两步先出一张测试图,确认中文没有变方块再批量渲染。

另一个跟字体相关的细节是:SVG 里的文字路径在某些阅读器里会偏移,看起来像错位。遇到这种情况,宁可直接导出 PNG,省心。我在某些文档工具里踩过 SVG 字体路径不一致的坑,后面统一切到了高分辨率 PNG,问题直接消失。

5.3 不同平台对 Mermaid 版本支持不一致

GitHub、GitLab、语雀、Notion,这些平台对 Mermaid 的支持程度并不一致。GitHub 文档仓库渲染用的版本可能持续更新,但企业内部的 GitLab 用的还是老版本。同一个语法在不同版本上的表现差距不小。

一个最典型的情况是:我在新版 Mermaid 里用了箭头样式--o和--x,渲染没问题;提交到公司的 GitLab 里,直接语法报错。这种事确实烦人,所以在多人协作里,先确认目标平台的渲染版本,不留暧昧区间。

我的标准操作是:先用本地 CLI 渲染出图片,确认语法正确,再把文本提交。如果目标平台必须用自身渲染,那就用一种最小化冗余的语法风格,不用新特性,不用花哨写法,保证兼容性。

5.4 团队文档很难保证所有人都更新图

最后这个坑不是技术问题,是沟通和管理问题。有些人改了代码,图没改;有些人改了图,图里的服务名跟代码不一致。我试过的应对方案里最有效的是:把「更新架构图」加入代码合并的 checklist。在团队代码仓库的合并请求模板里,加一项「本次改动是否影响架构图,影响则同步更新」。

友好一点的做法是,在架构图文件头部加一段注释,写明「此图由代码生成,源文件见 docs/architecture.mmd,禁止手动编辑图片」。再加上 CI 校验,保证图文件永远跟着代码一起变化。这套组合拳下来,图滞后于代码的情况基本绝迹。

6. 个人经验与建议

回看这几年的实践,我对 diagram-design 的体会是:它的价值核心不是“用代码代替鼠标”,而是让图变成可以被维护、被审查、被版本管理的一等公民。我见过太多同事从“画图两小时、改图两小时”的痛苦里解脱出来,也见过团队因为图滞后导致评审会变纠错会。

我的建议是切入路线要低门槛:从一次你要做的架构调整开始,别着急把所有旧图都翻新一遍,先在新增的架构迭代里用 Mermaid 出图,画完顺手放进文档仓库;等习惯了这种工作流,再把存量图逐个迁移。这样既不会颠覆现有流程,又能尽快体验到“改一行文本、提交一张图”的快感。

还有一个值得坚持的好习惯:每次做完方案,把图和背后的决策理由一起留到文档里。为什么这里用队列解耦,为什么那里要拆服务,在图的某个注释里写清楚。图解决“是什么”,注释解决“为什么”,这两样东西合在一起,才是团队真正需要传承的知识资产。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/17 11:19:28

传送门Shader正方形背景问题:用Alpha Clipping彻底解决透明贴图残留

做传送门效果的时候,很多人都会卡在同一个地方:贴图素材本身明明是个圆形光效或者旋涡纹理,放进场景里却总带着一圈方方正正的底色,黑的或者白的,在Game视图里特别扎眼,瞬间把科幻感拉回“实习生作业”的水…

作者头像 李华
网站建设 2026/10/17 11:19:21

在VScode上写网页(html):用TaoToken统一Key打通本地预览与AI补全

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/17 11:17:47

寄大件/贵重物品选什么快递?快递老兵‌一招讲清楚

寄送重量超过 20 千克的大件物品时, 应该优先选择德邦以及顺丰还有京东物流, 处理单件价值在 5000 元以上的贵重物品时, 首选使用顺丰的服务并进行保价操作或者是开通京东物流的贵重件专用通道。针对普通包裹可以通过第三方平台进行价格比较, 这比直接使用官方报价能节省大约40…

作者头像 李华
网站建设 2026/10/17 11:16:47

LSTM多输入多输出时间序列预测实战指南

简介:本资源是一份面向深度学习初学者与时间序列建模实践者的LSTM多输入多输出预测完整实现方案,聚焦空气质量、污染指数等多变量时序数据的联合建模与未来多步预测任务。资源包含126个文件,以75个Python脚本(含模型构建、训练、评…

作者头像 李华
网站建设 2026/10/17 11:16:26

AI赋能力学:计算力学智能化的技术路线、关键问题与落地展望

计算力学是个很有意思的领域。如果你不搞仿真或结构分析,第一反应可能是“算力不够就上超算”。但真正做过非线性固体、断裂、流固耦合或者拓扑优化的朋友都知道,瓶颈往往不是“能不能算”,而是“算得起算不起”——一个考虑接触、大变形、材…

作者头像 李华
网站建设 2026/10/17 11:14:20

网工必看:IS-IS与OSPFv2选型对比及配置排障指南

IS-IS和OSPFv2,算是网络工程师绕不开的两位老熟人。同样都是链路状态协议,同样跑Dijkstra算法,也同样被运营商和企业网大量使用,但真要在项目里二选一,或者面试时被问一句“为什么这网用IS-IS不用OSPF”,很…

作者头像 李华