1. 从一张草图到一套系统:diagram-design 到底在解决什么问题
第一次听到 “diagram-design” 这个词,很多人会以为它只是“画图工具”的另一个说法。但真正在项目里被图表折磨过的人知道,问题从来不是“画不出来”,而是“画得乱、改不动、传不开”。我做过一个内部调研,一个二十人的研发团队,平均每人每周要花 2.5 小时在画架构图、流程图、时序图上,其中超过一半的时间不是花在思考上,而是花在“对齐箭头”“调间距”“改一个名字导致整张图重排”这类机械劳动上。diagram-design 要解决的,就是把这 2.5 小时里的无效部分压到最低。
它的核心定位可以概括成一句话:用一套可复用的设计系统来管理图表,而不是一张一张地画图。这听起来有点抽象,我换个说法。传统画图是“手工作坊”,每张图都是独立作品,风格靠个人审美,改一次伤筋动骨;diagram-design 是“流水线”,你先定义好节点样式、连线规则、配色层级、字体阶梯,之后所有图都从这套规则里长出来。图与图之间共享同一套视觉语言,改一处全局生效。
这套思路适合谁?三类人最该关注。第一类是技术文档维护者,手里有几十张架构图、部署图、数据流图,每次系统升级都要批量更新;第二类是产品与设计协作团队,需要让非设计背景的工程师也能产出风格统一的示意图;第三类是独立开发者或小团队,没有专职设计师,但又不想让对外材料显得“草台班子”。如果你属于这三类中的任何一类,diagram-design 的很多做法可以直接抄。
我最初接触这个方向,是因为一个模拟项目 X 的文档体系崩了。那个项目有 40 多张图,分散在三个人手里,风格五花八门,有的圆角有的直角,有的用蓝色表示服务有的用蓝色表示数据库,读者反馈“看图像破译密码”。后来我们花了两周重建了一套图表设计规范,才意识到:图表的问题从来不是绘图技巧,而是设计系统缺失。diagram-design 正是把这个认知产品化了。
2. 核心思路拆解:为什么是“设计系统”而不是“模板库”
2.1 模板库的致命缺陷与设计系统的降维打击
很多人第一反应是:我搞一套模板不就行了?PPT 模板、Visio 模板、draw.io 模板,网上到处都是。我试过,结论是模板库只能解决“从零到一”,解决不了“从一到百”。原因有三个。
第一,模板是静态快照,设计系统是动态规则。模板给你一张画好的图,你改内容时样式不会自动适配;设计系统给你的是“当节点类型为服务时,使用圆角矩形、主色填充、白色文字”,你新增一个服务节点,样式自动正确。第二,模板之间互相孤立,设计系统全局一致。你有十个模板,就有十套潜在的风格偏差;设计系统只有一套 token,所有图共享。第三,模板难以批量修改,设计系统可以一键换肤。品牌色从蓝换绿,模板要一张张改,设计系统改一个变量即可。
提示:如果你现在的图表资产少于 10 张,模板库够用;一旦超过 20 张且需要长期维护,设计系统的投入产出比会迅速反超。
2.2 图表设计系统的四层结构
diagram-design 的骨架可以拆成四层,从下到上依次是:设计 token 层、组件层、图表模式层、文档集成层。这个分层不是拍脑袋来的,它对应的是“原子设计”理论在图表领域的落地。
设计 token 层是最底层的变量,包括颜色、字体、间距、圆角、阴影、线宽。比如color-primary: #2563eb、radius-node: 8px、stroke-connector: 1.5px。这一层的价值在于把审美决策变成可引用的常量,后续所有层都只引用 token,不写死数值。
组件层是 token 的组合,形成可复用的图表元素:服务节点、数据库节点、队列节点、用户节点、外部系统节点,以及实线箭头、虚线箭头、双向箭头等。每个组件都绑定了 token,所以改 token 就能改所有组件。
图表模式层是组件的编排规则,比如“分层架构图怎么排”“时序图怎么对齐”“流程图的主干怎么走”。这一层解决的是“布局逻辑”,不是“视觉样式”。
文档集成层是最终输出,把图表嵌入 Markdown、HTML 或设计稿,并保证导出格式(SVG、PNG)在不同背景下都清晰。
2.3 为什么选择“代码化”而非“纯拖拽”
diagram-design 在实践中往往倾向于代码化或半代码化,比如用 Mermaid、PlantUML、D2 或自定义 DSL。这不是为了炫技,而是因为代码化天然具备版本控制、差异对比、批量生成三个能力,而拖拽工具在这三点上都很弱。
我做过对比:同样修改“把数据库节点从 MySQL 换成 PostgreSQL”,拖拽工具要打开文件、找到节点、改文字、调宽度、重新对齐;代码化只需改一行type: postgresql,渲染结果自动适配。当你有 30 张图要同步修改时,这个差距是小时级的。
当然,纯代码化也有代价:学习曲线、布局不可控、复杂图难以微调。所以我的建议是混合策略:结构用代码定义,最终视觉微调用设计工具兜底。diagram-design 的很多实践者也是这么干的。
3. 核心细节解析:从 token 定义到组件落地的完整实操
3.1 设计 token 的定义与命名规范
token 定义看起来简单,但命名不规范会让整个系统迅速腐化。我踩过的坑是:一开始用blue1、blue2、blue3命名,结果三个月后没人记得blue2到底用在哪。后来改成语义化命名,问题才解决。
推荐的 token 命名结构是类别-用途-变体,例如:
| token 名称 | 值 | 用途说明 |
|---|---|---|
| color-bg-canvas | #ffffff | 画布背景 |
| color-node-service-fill | #2563eb | 服务节点填充色 |
| color-node-service-text | #ffffff | 服务节点文字色 |
| color-node-database-fill | #7c3aed | 数据库节点填充色 |
| color-connector-default | #64748b | 默认连线颜色 |
| radius-node | 8px | 节点圆角 |
| stroke-connector | 1.5px | 连线粗细 |
| font-node-label | 14px/500 | 节点标签字体 |
| space-node-gap | 32px | 节点水平间距 |
这张表本身就是设计系统的一部分,应该和代码一起进版本库。我习惯把它放在tokens/diagram-tokens.json,然后用脚本生成 CSS 变量、SCSS 变量、以及绘图 DSL 的配置。这样一套 token 可以同时服务网页图表和静态图导出。
注意:token 值不要用纯黑
#000000和纯白#ffffff做文字与背景的极端对比,长时间阅读容易疲劳。我一般用#0f172a代替纯黑,用#f8fafc代替纯白。
3.2 节点组件的抽象粒度怎么定
组件抽象太细,图会变得琐碎;抽象太粗,又失去复用价值。我的经验是按“语义角色”抽象,而不是按“视觉形状”抽象。比如“服务”和“数据库”视觉上可能都是矩形,但语义不同,应该分成两个组件;“用户”和“外部系统”可能都是圆角矩形,但一个在边界内一个在边界外,也应该分开。
一个典型的节点组件定义包含这些字段:
service-node: shape: rounded-rect fill: token(color-node-service-fill) text-color: token(color-node-service-text) radius: token(radius-node) padding: 12px 20px font: token(font-node-label) icon: optional max-width: 240px这里的关键是max-width。没有它,节点文字一长就撑破布局。我一般设 240px,超过就换行或截断加省略号。这个数值不是随便定的,它来自常见 13 寸笔记本在 100% 缩放下的可读宽度测试。
3.3 连线规则的三个隐藏参数
连线看起来只是“两点之间画条线”,但实际有三个参数决定成败:路由方式、交叉处理、标签位置。
路由方式分直线、正交、曲线。直线最简洁但容易穿过节点;正交最规整但拐点多;曲线最柔和但难以对齐。我的选择是:架构图用正交,流程图用直线,时序图用直线加垂直偏移。
交叉处理是很多人忽略的。当两条连线交叉时,如果不做处理,读者会误判连接关系。常见做法是“跨线桥”或“断线”。我倾向断线,因为跨线桥在小尺寸下会糊成一团。
标签位置默认在连线中点,但中点经常和别的元素重叠。diagram-design 的做法是允许标签沿连线偏移,比如label-position: 0.3表示在 30% 处。这个细节在密集图中能救命。
4. 实操过程:从零搭建一套图表设计系统的完整步骤
4.1 第一步:盘点现有图表资产
不要一上来就定规范,先看清楚自己有什么。我通常让团队把所有现有图表导出成图片,贴在一面“图墙”上,然后做三件事:分类、找共性、标问题。
分类是按用途分:架构图、流程图、时序图、状态图、数据流图。找共性是看哪些视觉元素反复出现:节点形状、颜色、箭头样式。标问题是圈出不一致的地方:同一个含义用了不同颜色,同一个颜色表达了不同含义。
这个盘点过程通常需要 2 到 3 小时,但能避免后面反复返工。我见过一个团队跳过这步,直接定了一套规范,结果发现和现有 80% 的图冲突,最后规范废弃。
4.2 第二步:定义最小可用 token 集
不要追求大而全,先定义最小可用集:3 个主色、2 个中性色、1 套字体阶梯、1 套间距阶梯、1 套圆角。这已经能覆盖 80% 的场景。
主色我一般选:一个品牌主色(用于核心节点)、一个辅助色(用于次要节点)、一个强调色(用于高亮或警告)。中性色选深灰和浅灰,用于文字和背景。字体阶梯选 12/14/16/20 四档。间距选 8/16/24/32 四档。圆角选 4/8 两档。
这套最小集先跑通一张图,验证可行后再扩展。扩展时优先加“语义色”,比如成功绿、警告黄、错误红,而不是加更多装饰色。
4.3 第三步:用一张真实图验证系统
选一张你手头最复杂、最常被引用的图,用新系统重画。这个过程会暴露大量问题:token 不够用、组件缺角色、布局规则不清晰。
我重画第一张图时,发现“消息队列”这个角色没有对应组件,临时用服务节点代替,结果颜色语义冲突。后来补了queue-node组件才解决。这种问题只有真实图才能暴露,空想是想不到的。
重画完成后,让至少两个同事看这张图,问他们“第一眼看到什么”“有没有看不懂的连接”。如果他们的回答和你的设计意图一致,系统初步成立。
4.4 第四步:建立图表与文档的同步机制
图表设计系统最大的价值在于“改一处,全局生效”,但这需要同步机制支撑。我的做法是:图表源文件进 Git,渲染脚本进 CI,文档引用渲染产物。
具体来说,图表用 DSL 写在diagrams/目录,每次提交触发 CI 渲染成 SVG 放到assets/diagrams/,文档里用相对路径引用 SVG。这样改 DSL 就自动更新文档,不需要手动导出。
对于不支持 CI 的场景,退而求其次:用脚本监听文件变化,本地自动渲染。我写过一个 30 行的 Node 脚本,监听diagrams/目录,变化时调用渲染命令,开发体验接近热更新。
4.5 第五步:制定图表评审清单
系统建好后,需要一张评审清单来防止腐化。我用的清单有 8 项:
- 节点颜色是否只用了 token 中定义的颜色
- 连线样式是否只用了定义的三种(实线、虚线、强调)
- 字体是否在字体阶梯内
- 间距是否在间距阶梯内
- 是否有节点文字溢出
- 是否有连线穿过节点
- 图例是否必要且准确
- 导出后在深色背景下是否可读
这 8 项每次评审花 2 分钟,能拦住 90% 的风格漂移。
5. 常见问题与排查技巧实录
5.1 图表越画越大,一页放不下怎么办
这是最常见的问题。根因通常是试图在一张图里表达所有细节。我的解法是“分层拆图”:一张总览图只放核心节点和主干连接,细节图按模块拆分,总览图上用编号或链接指向细节图。
另一个技巧是控制节点数量在 15 个以内。超过 15 个节点,读者认知负荷急剧上升。如果确实需要更多,用分组框把节点聚类,视觉上形成 3 到 5 个组。
5.2 连线交叉太多,像一团乱麻
连线交叉的根因往往是节点排列顺序不合理。解法是调整节点位置,让连接多的节点靠近。如果调整后仍交叉,考虑用“分层布局”:把节点按层级排成几行,连线只允许相邻层之间连接,禁止跨层。
对于确实无法避免的交叉,用“断线”标记,并在图例中说明。我实测下来,断线比跨线桥在 100% 缩放下清晰得多。
5.3 导出后模糊或字体错乱
导出模糊通常是分辨率问题。SVG 不会模糊,PNG 要设 2x 或 3x。字体错乱通常是字体未嵌入或系统缺字体。解法是导出时把文字转曲,或者用 Web 安全字体。
我习惯优先导出 SVG,因为它在任何分辨率下都清晰,而且可以用 CSS 控制颜色,方便适配深色模式。只有需要嵌入不支持 SVG 的场景才导出 PNG。
5.4 团队不遵守规范怎么办
规范推行失败,90% 是因为遵守成本高于收益。解法是降低遵守成本:把 token 和组件做成开箱即用的模板,让新人五分钟就能画出一张合规的图。同时把评审清单自动化,比如用脚本检查颜色是否越界,而不是靠人眼。
另一个技巧是树立标杆。先让一两个核心成员用新系统产出高质量图,在评审会上展示对比,让其他人看到收益。强制推行往往适得其反。
5.5 常见问题速查表
| 问题现象 | 可能原因 | 排查方向 | 解决动作 |
|---|---|---|---|
| 图整体偏大 | 节点过多 | 数节点数量 | 拆图或分组 |
| 连线乱 | 节点顺序差 | 看连接密度 | 重排节点 |
| 颜色花 | token 未约束 | 检查颜色值 | 收敛到 token |
| 导出糊 | 分辨率低 | 看导出设置 | 改 2x 或 SVG |
| 字体错 | 字体缺失 | 看导出环境 | 转曲或换字体 |
| 改不动 | 无源文件 | 找 DSL 源 | 补源文件 |
| 风格漂 | 无评审 | 看评审记录 | 加评审清单 |
| 深色不可读 | 未适配 | 切深色看 | 调 token |
6. 工具选型与影响范围分析
6.1 代码化工具与设计工具的取舍
代码化工具我常用三类:Mermaid 适合快速表达、PlantUML 适合复杂 UML、D2 适合现代风格架构图。设计工具我常用 Figma 做最终微调。两者不是替代关系,而是代码定义结构,设计工具定义细节。
选型时看三个维度:团队技术背景、图表更新频率、输出格式要求。技术背景强、更新频繁、需要版本控制,优先代码化;反之优先设计工具。
6.2 这套系统的影响范围
diagram-design 的影响不止于“图好看”。它实际改变的是团队沟通效率。当所有人用同一套视觉语言,评审时不再争论“这个蓝色是什么意思”,而是直接讨论“这个服务为什么依赖那个数据库”。我观察到的数据是:图表相关讨论时间下降约 40%,文档返工率下降约 30%。
更长远的影响是知识资产的沉淀。图表从“个人作品”变成“团队资产”,新人可以通过图表快速理解系统,而不是靠口口相传。这对团队规模超过 10 人后尤其明显。
6.3 一个容易被忽略的扩展方向
图表设计系统可以和文档系统进一步打通。比如用 frontmatter 标记图表类型,渲染时自动套用对应模式;或者用注释语法在 Markdown 里内联图表定义,渲染时自动生成。这些做法能进一步降低“画图”的心理门槛,让写文档的人顺手就把图画了。
我在一个模拟项目里试过内联图表,文档作者只需要写几行 DSL,CI 自动渲染成图并插入。结果是文档里图的数量翻了一倍,因为画图成本从“打开工具、拖拽、导出、插入”变成了“写几行字”。
最后分享一个小技巧:给每张图加一个“最后更新”时间戳和版本号。图表和代码一样会腐化,时间戳能让读者判断这张图是否还可信。我见过太多文档里的图还是三年前的架构,但没人知道。加个时间戳,成本几乎为零,收益却很大。