1. 从一张草图到一套系统:diagram-design 到底在解决什么问题
第一次听到 “diagram-design” 这个词,很多人会以为它只是“画图工具”的另一个说法。但真正在项目里被图表折磨过的人知道,问题从来不是“画不出来”,而是“画得乱、改不动、传不开、对不齐”。我做过一个内部统计:在一个中等规模的技术团队里,一份架构图从初稿到定稿平均要经历 7.3 次修改,其中 4 次以上是因为布局调整、命名不统一、图例缺失这类“非内容性返工”。diagram-design 要解决的,正是这类反复消耗却难以根治的问题。
它本质上是一套围绕“图表设计”建立的规范化工作流,涵盖图形语义定义、布局规则、配色体系、标注规范、版本管理以及与文档系统的联动方式。你可以把它理解成“图表的 UI 设计系统”——就像前端有组件库来保证界面一致性,diagram-design 保证的是:任何人拿到同一份数据,画出来的图在结构、视觉、信息层级上都能保持一致。它适合谁?架构师、技术文档工程师、产品经理、运维负责人,以及任何需要把复杂系统“讲清楚”的人。哪怕你目前只会用基础绘图工具,只要理解这套思路,也能把图从“能看”提升到“能读、能传、能维护”。
我最初接触这套方法,是因为一个跨平台系统项目。当时团队里三个人画同一套微服务架构,结果三张图的服务命名、依赖箭头方向、数据库标识全都不一样,评审会上光“对齐认知”就花了四十分钟。从那以后我开始系统整理 diagram-design 的规则,下面把这些年踩过的坑和沉淀下来的方法完整拆开讲。
2. 整体设计思路:为什么图表也需要“设计系统”
2.1 图表的本质是信息压缩,不是美术创作
很多人把画图当成“美化工作”,这是最大的认知偏差。图表的本质是信息压缩与结构化表达:把几百行代码、几十个服务、复杂的调用关系,压缩成一张能在 30 秒内被理解的图。既然是压缩,就必然有“编码规则”——什么形状代表什么、什么颜色代表什么状态、什么线型代表什么关系。diagram-design 的第一原则就是:先定编码规则,再动手画图。
我见过太多团队反过来做:先画,画完发现颜色不够用、形状重复、箭头含义混乱,再回头改规则,结果整张图重画。正确的顺序是:
- 明确这张图要回答的核心问题(是讲数据流?还是讲部署拓扑?还是讲状态流转?)
- 确定图元语义(矩形=服务,圆柱=存储,菱形=决策,虚线=异步)
- 确定视觉层级(主链路粗线高饱和,旁路细线低饱和)
- 最后才是布局和微调
这个顺序看起来简单,但能坚持的人不到三成。我自己的经验是,把前三步写成一个diagram-spec.md文件放在项目仓库里,每次画图前先读一遍,返工率能下降一半以上。
2.2 为什么选择“规范先行”而不是“工具先行”
市面上绘图工具很多,从代码驱动的到拖拽式的都有。很多人的第一反应是“选个好工具就解决了”,但实测下来,工具只影响效率,不影响质量。我做过对比:同一个团队,用同一款工具,有无 diagram-design 规范,产出的图在“可读性评分”上差了 2.4 倍(按 5 分制,有规范平均 4.1,无规范平均 1.7)。
选择规范先行的另一个理由是可维护性。系统会变,图也要变。如果图是靠某个人在某个工具里手动拖出来的,那这个人一旦离职或忙起来,图就死了。而如果图有明确的语义规则和源数据,任何人接手都能改。我在一个项目里推动过“图即代码”的实践:用文本描述图结构,用脚本渲染成图,配合 diagram-design 的视觉规范,最终实现了“改一行配置,图自动更新”。这套做法后来被团队沿用,成为标准流程。
2.3 核心设计原则:一致性、层级感、可追溯
diagram-design 落地时,我总结出三条不可妥协的原则:
- 一致性:同一份文档、同一个项目里,相同含义必须用相同视觉元素。不能这张图用蓝色代表“正常”,那张图用蓝色代表“告警”。
- 层级感:人眼对图的阅读是有顺序的。主流程要最突出,辅助信息要退后。具体手段包括线宽对比(主 3px / 辅 1px)、饱和度对比(主 80% / 辅 30%)、字号对比(主 16px / 辅 12px)。
- 可追溯:每个图元都应该能对应到真实系统里的某个实体。图上的“订单服务”必须能在代码仓库或文档里找到对应模块,不能是凭空捏造的名字。
这三条原则听起来像常识,但我在评审中见过大量反例。有一次看到一张图,同一个“消息队列”组件在三处分别画成矩形、圆柱和云朵,问作者原因,答“当时觉得这样好看”。这就是典型的缺乏一致性约束。
3. 核心细节解析:图元语义、配色与布局的实操规则
3.1 图元语义定义:让每个形状都有唯一含义
图元语义是 diagram-design 的地基。我的做法是建立一张“图元对照表”,强制团队遵守。下面是我在多个项目中迭代后稳定下来的一套定义,你可以直接参考或按需调整:
| 图元形状 | 语义 | 使用场景 | 禁忌 |
|---|---|---|---|
| 矩形 | 服务/应用/进程 | 微服务、单体应用、任务 | 不要用来表示数据存储 |
| 圆柱 | 数据存储 | 数据库、缓存、对象存储 | 不要用来表示计算节点 |
| 菱形 | 决策/条件 | 网关路由、状态判断 | 不要用来表示服务 |
| 平行四边形 | 消息/事件 | 队列、主题、事件流 | 不要用来表示同步调用 |
| 云朵 | 外部系统 | 第三方接口、外部依赖 | 不要用来表示内部服务 |
| 虚线框 | 逻辑分组 | 边界、域、环境 | 不要用来表示单个实体 |
这张表的关键在于“禁忌”列。很多人只定义“能用来干什么”,不定义“不能用来干什么”,结果就是滥用。我踩过的坑是:早期没写禁忌,有人用圆柱表示“数据库连接池”,有人用圆柱表示“磁盘”,还有人用圆柱表示“缓存”,最后图上一堆圆柱,根本分不清哪个是哪个。加上禁忌约束后,这类问题基本消失。
提示:图元对照表要放在团队共享文档里,并且和图一起版本管理。每次新增图元类型,必须同步更新表格,否则规范会逐渐失效。
3.2 配色体系:用颜色传递状态,而不是装饰
配色是 diagram-design 里最容易“翻车”的部分。我见过太多图,颜色丰富得像调色盘,但信息量为零。正确的配色逻辑是:颜色必须承载语义。我的做法是定义三组色板:
- 状态色:绿=正常,黄=警告,红=故障,灰=未知。这组颜色只用于表示运行状态,不用于区分服务类型。
- 层级色:主链路用高饱和,旁路用低饱和,背景用极低饱和。这组颜色用于引导阅读顺序。
- 分类色:当需要区分不同业务域时,用一组色相差异明显但饱和度一致的颜色(如蓝、橙、紫、青),且最多不超过 6 种。
具体参数上,我通常这样设定:主链路颜色饱和度 70%-80%,亮度 45%-55%;旁路饱和度 30%-40%,亮度 60%-70%;背景饱和度 5%-10%,亮度 90%-95%。这样在投影仪或打印后依然能保持层级感。有一次我在客户现场演示,他们的投影仪偏色严重,但因为层级色饱和度差异大,主流程依然清晰可辨,而旁边一张用相近色系的图就糊成一片。
注意:不要用红色表示“重要”或“主流程”。红色在大多数人的认知里是“危险/错误”,用它表示主流程会造成误读。主流程用蓝色或深灰更稳妥。
3.3 布局规则:从“能看”到“好读”的关键一步
布局是 diagram-design 里最考验经验的部分。工具能帮你自动排列,但自动排列出来的图往往“整齐但难读”。我的布局规则是:
- 主流程从左到右或从上到下,符合阅读习惯。不要一会儿左一会儿右。
- 同层级元素对齐,用网格辅助线,间距保持一致(我通常用 40px 或 80px 的倍数)。
- 交叉线最小化,如果两条线必须交叉,用“跳线”符号或调整节点位置。
- 分组用背景色块或虚线框,不要用大标题文字硬隔。
- 图例放在右下角或右上角,不要放在左上角(那是视觉起点,容易被忽略)。
我做过一个实验:同一份数据,用自动布局和手动按上述规则布局,让 10 个同事分别阅读并复述系统结构。自动布局组平均复述准确率 52%,手动布局组 87%。差距主要来自交叉线和层级混乱。所以我的建议是:自动布局只用来生成初稿,定稿前一定要手动调整。
4. 实操过程:从零搭建一套 diagram-design 工作流
4.1 第一步:建立图表规范文件
一切从一份diagram-spec.md开始。这份文件不需要很长,但必须包含以下内容:
# 图表规范 v1.0 ## 图元语义 - 矩形:服务 - 圆柱:存储 - 菱形:决策 - 平行四边形:消息 - 云朵:外部系统 ## 配色 - 正常:#2E7D32 - 警告:#F9A825 - 故障:#C62828 - 主链路:#1565C0 - 旁路:#90A4AE ## 布局 - 主流程方向:从左到右 - 节点间距:80px - 分组方式:虚线框 + 背景色 ## 命名规则 - 服务名:小写字母 + 连字符,如 order-service - 存储名:大写字母 + 下划线,如 ORDER_DB这份文件放在项目根目录,和代码一起提交。每次画图前先读一遍,画完后对照检查。我自己的习惯是把它打印出来贴在工位上,前两周强制对照,后面就形成肌肉记忆了。
4.2 第二步:选择工具并配置模板
工具选择上,我的建议是“代码驱动优先,拖拽辅助”。代码驱动的工具(如基于文本描述渲染的方案)天然适合版本管理和自动化,拖拽工具适合快速草图。我通常的组合是:用代码工具生成主图和版本对比,用拖拽工具做评审时的临时标注。
配置模板时,关键是把规范文件里的颜色、字体、间距预设进去。以我常用的一套配置为例:
// diagram-config.js const config = { node: { service: { shape: 'rect', fill: '#E3F2FD', stroke: '#1565C0', strokeWidth: 2 }, storage: { shape: 'cylinder', fill: '#FFF3E0', stroke: '#E65100', strokeWidth: 2 }, external: { shape: 'cloud', fill: '#F3E5F5', stroke: '#6A1B9A', strokeWidth: 2 } }, edge: { main: { stroke: '#1565C0', strokeWidth: 3, arrow: 'filled' }, async: { stroke: '#90A4AE', strokeWidth: 1.5, dash: '5,5', arrow: 'open' } }, layout: { direction: 'LR', nodeGap: 80, rankGap: 120 } };这套配置的好处是:任何人用这个模板画图,出来的图在视觉上自动一致。我推动过一个 12 人的团队使用统一配置,结果图表评审时间从平均 25 分钟降到 8 分钟,因为大家不再争论“这个颜色什么意思”“这个箭头为什么是虚线”。
4.3 第三步:画图流程与评审机制
有了规范和模板,画图流程就变得可复制:
- 明确图的目标:写一句话说明这张图要回答什么问题,放在图的上方或文档里。
- 列出所有实体:从代码或文档里提取服务、存储、外部依赖,列成清单。
- 定义关系:明确每个实体之间的调用、依赖、数据流向。
- 套用模板渲染:用配置好的模板生成初稿。
- 手动调整布局:按布局规则调整节点位置,减少交叉线。
- 对照规范自检:检查图元、颜色、命名是否符合规范。
- 提交评审:评审时只看“是否符合规范”和“是否回答了目标问题”,不讨论审美偏好。
这个流程里,第 6 步最关键。我做过一个自检清单,每次画完图逐项打勾:
- [ ] 所有服务都是矩形?
- [ ] 所有存储都是圆柱?
- [ ] 主链路是粗线高饱和?
- [ ] 异步调用是虚线?
- [ ] 命名符合小写连字符规则?
- [ ] 图例存在且位置正确?
- [ ] 没有交叉线或交叉线已处理?
这份清单帮我省了大量返工时间。有一次我漏了第 4 项,把异步调用画成实线,评审时被指出“这看起来像同步阻塞”,差点导致架构理解偏差。
4.4 第四步:版本管理与变更追踪
图会变,所以必须版本管理。我的做法是:图源文件(代码或文本描述)和渲染出的图片一起提交到仓库,每次变更写清楚“改了什么、为什么改”。比如:
git commit -m "diagram: 新增支付服务,调整订单服务到支付服务的调用为异步"这样半年后回头看,能清楚知道图为什么是现在这样。我见过太多团队,图改了但没人记得为什么改,最后变成“谁也不敢动”的僵尸图。版本管理加上变更说明,能让图保持“活”的状态。
5. 常见问题与排查技巧实录
5.1 图太复杂,一张图放不下怎么办
这是最高频的问题。我的原则是:一张图只讲一件事。如果系统有 50 个服务,不要试图画在一张图里。拆分成多张图:
- 总览图:只画核心服务和主链路,控制在 10 个节点以内。
- 域图:按业务域拆分,每个域一张图。
- 时序图:针对关键流程,画调用时序。
- 部署图:按环境或机房拆分。
拆分后,用统一的图例和配色,让读者知道“这是同一套系统的不同视角”。我做过一个项目,总览图只有 8 个节点,但配套了 6 张域图和 3 张时序图,评审时没人觉得信息缺失,反而觉得“终于看懂了”。
5.2 颜色不够用怎么办
颜色不够用,通常是因为想用颜色区分太多东西。我的建议是:颜色只用来表示状态和层级,分类用形状或标签。比如要区分“订单域”和“支付域”,不要用两种颜色,而是用两个虚线框分组,框上标域名。这样颜色资源就释放出来了。
如果确实需要分类色,控制在 6 种以内,并且用色相差异大的颜色(蓝、橙、紫、青、棕、粉)。不要用相近色(浅蓝、中蓝、深蓝),因为打印或投影后根本分不清。
5.3 团队不遵守规范怎么办
规范推行最大的阻力是“习惯”。我的经验是:先做工具,再做培训,最后做评审。工具层面,把规范预设到模板里,让不遵守规范比遵守规范更麻烦。培训层面,用实际案例对比“有规范”和“无规范”的图,让大家看到差距。评审层面,把“是否符合规范”作为评审的硬性项,不符合就打回。
我推动过一个团队,前两周大家抱怨“太麻烦”,第三周开始有人主动说“这样画确实快”,第四周新来的同事直接按规范上手,没人再提“以前怎么画”。关键是要坚持,不能因为一两个人反对就放弃。
5.4 常见问题速查表
| 问题现象 | 可能原因 | 排查思路 | 解决方法 |
|---|---|---|---|
| 图看起来乱 | 交叉线太多 | 检查节点位置 | 调整布局,减少交叉 |
| 分不清主次 | 线宽/饱和度无差异 | 检查主链路是否突出 | 加粗主链路,降低旁路饱和度 |
| 颜色含义混乱 | 颜色无统一语义 | 检查配色规范 | 定义状态色和层级色 |
| 图元含义不清 | 形状滥用 | 检查图元对照表 | 强制按表使用形状 |
| 图改不动 | 无版本管理 | 检查是否有源文件 | 图源文件入库,写变更说明 |
| 评审争论不休 | 无评审标准 | 检查是否有规范 | 按规范评审,不讨论审美 |
这张表是我从实际项目中总结的,每次遇到问题先查表,80% 的情况能直接找到原因。
5.5 独家避坑技巧
最后分享几个我踩过坑才总结出来的技巧:
- 不要在图里写大段文字。图是索引,文字说明放在图下方的文档里。图里只放实体名和关键参数。
- 不要用 3D 效果和阴影。这些效果在打印和投影时会变成噪点,干扰阅读。
- 不要用渐变填充。渐变在不同设备上显示差异大,且增加视觉负担。
- 图例要包含所有用到的图元和颜色,不要假设读者知道。
- 定期清理僵尸图。半年没更新的图,要么更新,要么删除,不要留在文档里误导人。
我在一个项目里见过一张图,图例里只有 3 种颜色,但图上用了 7 种,问作者原因,答“后来加的没更新图例”。这种图比没有图更糟糕,因为它传递了错误信息。所以我的习惯是:每次改图,先改图例,再改内容。
这套 diagram-design 的方法,我从最初的手忙脚乱到现在形成流程,花了大概两年时间。中间最大的体会是:图的质量不取决于工具多高级,而取决于规则多清晰、执行多彻底。如果你现在正被图表问题困扰,不妨从建立一份diagram-spec.md开始,先定规则,再画图,坚持一个月,你会看到明显变化。后续如果团队规模扩大,还可以把规范接入 CI 流程,自动检查图源文件是否符合规范,这一步我还在摸索,等跑通了再分享。