从同事随手甩过来的“画个架构图呗”,到后来我们专门为一个内部平台整理成套的 diagram-design 规范,前后踩过的坑可能比画的图还多。很多人觉得 diagram-design 就是拉几个框、连几根线、选个顺眼的配色,可真把一张图放到评审会上,被问得最惨的时候,往往不是业务逻辑有多复杂,而是“你这个箭头到底什么意思”“这两个方块为什么放在同一层”“为什么时序图里有两根线颜色一模一样”。这些问题的根源,不是不会用工具,而是没把图表当成一件需要认真设计的产品。
这篇文章想聊的,就是 diagram-design 背后那些文档里很少写清楚的东西:怎么在动手前拆解信息层级,怎么让不同类型的图真正服务于表达,怎么用一整套可复用的规范减少返工,以及我在真实项目里遇到过的那些哭笑不得的图和对应的处理办法。不管你是要画系统架构图、业务流程图、时序图还是数据看板,只要还在跟图表打交道,这里的内容应该能帮你在下一次动手前少走一段弯路。
1. 从“画框图”到“diagram-design”:我为什么把它当成一门手艺
1.1 一个看似简单的画图需求,背后藏着一堆坑
最早接触图表设计是在一个数据中台项目里,当时的任务说起来非常简单:把十几个微服务之间的调用关系画出来,交付给运维和研发做评审。我打开画图工具,按照自己的理解把服务框一个个摆好,用箭头连起来,半小时出图,看起来还挺清爽。结果评审会上第一个问题就是:“你这个箭头是指调用方向还是数据流向?”我当时愣了一下,因为真的没想过这个问题,只是觉得连线默认是“有关系”。
紧接着第二个问题更致命:“订单服务为什么放在用户服务的右边?中间那个网关为什么不跟数据库分开?”这些问题本质上都不是画图技巧问题,而是我在动手前没有回答清楚三个基本问题:这张图给谁看?他想从中获得什么?哪些信息应该被强调、哪些应该被弱化?
那次评审之后,我开始把 diagram-design 当作一门正经手艺来研究——它不是美术课上的装饰,也不是软件工程里的辅助文档,而是一门“通过空间关系、图形语义、标注规范和视觉层级来精确传递复杂信息”的沟通技术。好的图表能让一个陌生人在三十秒内看懂系统的主干,烂的图表则会让一个熟悉系统的人连自己想找的服务在哪都找不到。
1.2 diagram-design 到底解决什么问题
往大了说,图表设计解决的是“在同一个平面上,让多个人对同一个复杂系统达成共识”的问题。口头沟通是线性的,一秒只能说一个词;文字是序列的,读者得一行一行扫;而图表是空间的,人眼可以同时感知位置、颜色、形状、连接关系和尺寸差异。利用好这种空间并行感知,就能把一段需要讲十分钟的复杂关系压缩成一眼就能看懂的画面。
往具体了说,diagram-design 需要解决四类基本问题:
第一类是语义问题:矩形、圆角矩形、菱形、圆圈、圆柱、泳道,分别是什么含义?连线是带箭头还是不带?实线虚线有什么区别?这些语义必须在图内保持一致,最好还能与团队既有规范对齐。
第二类是层级问题:哪些元素是核心容器,哪些是容器内部的子项;哪些关系是主要的,哪些是次要的;一张图里应该有几个视觉焦点,如果没有焦点,读者就会被淹没在同等重要的信息里。
第三类是布局问题:节点怎么排布才能减少连线交叉?分组边界怎么画才能既清楚又不占地方?留白多少才能让图透气又不至于稀疏得浪费空间?
第四类是出版问题:这张图会出现在文档哪一页?是会投射到会议室大屏上,还是被人用手机放大看?不同场景对字号、线条粗细、颜色对比度的要求完全不一样。
这些问题没有一个能在画图工具里被自动解决,工具只是帮你把想法落到画布上而已。想清楚这些问题,才算真正进入 diagram-design。
1.3 这篇内容适合谁
如果你是准备画第一张架构图或者流程图的初学者,我建议你把注意力放在第 2 章和第 3 章,那是从“会操作工具”到“能画出合格图”的跨越。如果你已经在用画图工具画了不少图,但总觉得自己的图不够专业、总被同事吐槽“看不懂”,那可以重点看第 3 章的规范细节和第 4 章的排查思路。如果你是要在一个团队里推广统一图表规范的负责人,那第 5 章的进阶思路值得细读,那里讨论了怎么让规范和自动化工具结合,而不只是发一份没人看的《画图守则》。
2. 动手前先想清楚:diagram-design 的核心决策顺序
2.1 先定受众,再定图层级
很多人画图的第一步是打开工具,新建画布,然后开始拖框。这个顺序其实是反的。正确的第一步应该是问自己:这张图交付给谁?
我曾经同一个“用户登录流程”分别画过两版:给产品经理看的那版,用了泳道图,把用户、前端、后端、数据库四个角色拆成四条泳道,每个步骤按时间顺序在不同泳道间穿梭;给后端研发看的那版,直接用了时序图,把消息请求和响应画成带标记的箭头,重点是接口调用顺序和异常分支。两版图内容本质相同,但读者关心的问题完全不同——产品经理想知道“用户在什么环节会卡住”,研发想知道“哪个服务在哪一步会报错”。如果我硬要用一版时序图去同时满足两拨人,结果往往是两边都嫌他看不懂。
确定受众之后,紧接着要确定图的“核心主张”。一张图只能有一个核心信息,或者“系统由哪几个核心模块组成”,或者“这个流程的关键分支在哪”,或者“这条链路的瓶颈在什么位置”。把核心主张写在画布外面都不过分,画的时候反复对照:图中元素是否都在为一个核心主张服务?那些只是“顺手补上”的细节,该删就删。
图层级则可以简单划分为三层:背景层(大分组、系统边界、泳道)、主景层(核心节点和主要连线)、前景层(标注、注释、警示色)。把不同语义放到对应层级,是避免“一坨东西糊在一起”的根本办法。我见过很多新手图,所有元素都在同一个视觉平面上,边框、文字、颜色都一样重,背景层和主景层完全没有区分,结果整张图看起来像一堵贴满标签的墙,谁看了都头大。
2.2 选对图表类型,比画得漂亮重要得多
图表类型选错,后面所有规范都白搭,因为读者会用错误的阅读方式去理解你的图。这里我总结了一张非常主观但很实用的类型速查表:
| 你想表达的信息 | 首选图表类型 | 不要用 | 理由 |
|---|---|---|---|
| 一个请求在多个系统间的时间顺序 | 时序图 | 架构图 | 时序图能清楚表达“谁先谁后”,架构图表达不了时间维度 |
| 角色分工 + 流程阶段 | 泳道图 / 跨功能流程图 | 普通拓扑图 | 泳道把“谁做的”固定到空间里,一眼可知责任主体 |
| 系统由哪些模块组成、它们怎么连接 | 架构图 / 模块框图 | 流程图 | 流程图有步骤含义,架构图更强调容器和边界 |
| 类与类之间的继承/组合关系 | UML 类图 | ER 图 | 类图有专门的关系箭头语义,ER 图使用习惯不同 |
| 数据表之间的关系 | ER 图 | 类图 | ER 图表达主外键与基数更自然 |
| 集群节点之间的物理连接 | 网络拓扑图 | 业务流程图 | 拓扑关注链路与设备,不要混入业务步骤 |
选类型之外,选“抽象粒度”也很重要。同一套系统,画“部署视图”时可能只需要三个大框:前端集群、后端集群、数据库集群;画“应用视图”时就得拆出十几个微服务;画“代码视图”时甚至要把服务内的组件画出来。粒度不同,图的形态完全不同。动手前想好自己要的是哪一层粒度,别指望一张图覆盖从物理机房到代码方法的全部层级——那只会画出一张谁都无法阅读的蜘蛛网。
2.3 信息架构:分组、留白、连接线怎么走
确定类型之后,进入信息架构阶段。这步很像写文章前列大纲:先不急着把每个节点摆好,而是先用一个矩形框代表“一组东西”,理清组与组之间的关系。
分组的原则有三个:业务内聚性、生命周期一致性和访问频率相似性。比如“用户服务”和“认证服务”放在一个组里,因为它们处理的是同一批用户主数据;“订单服务”和“支付回调服务”放一起,因为它们的调用关系最紧密。分组的边界可以用大圆角矩形、浅色底色或泳道表示,注意不要让分组线抢了内部节点的视觉权重。
留白是很多人最容易忽略的。节点之间的距离不是越小越好,也不是越大越好。以我的经验,同一分组内相邻节点的间距建议保持在节点短边的 0.5 到 1 倍;不同分组之间的间距至少是分组内间距的 2 倍。这样读者能自然地感知到“哪些东西是一伙的”。如果画布不够,优先压缩节点内部的文字边距,而不是压缩分组间距。
连线走向也要在架构阶段想好。我统一偏好“主链路从左到右,回环链路从下往上绕”,这样读者顺着视线扫一遍就能抓住主流程。所有连线尽量走水平和垂直方向,不要出现任意角度斜线——斜线在线条密集时会制造大量交叉噪声。这也就是为什么在画布上做“通道预留”很重要:两个分组之间至少要留出一条横平竖直的走廊,方便连线展开。
3. 实操过程:一张系统架构图的完整设计流程
3.1 工具选型与画布设置
画图工具彼此差异很大,但核心能力就几项:是否支持图层、是否支持批量对齐、是否有可复用的组件库、是否支持版本回滚、是否能导出高分图。我个人的选择标准非常朴素——日常快速草图用在线白板类工具,正式交付文档用桌面级绘图工具,代码化图形用声明式脚本。这里不具体点名工具,因为工具迭代太快,但三个原则是一致的:能导出 SVG 或高分辨率位图;能通过组件样式批量修改颜色和字体;能定义共享样式库。
画布设置同样重要。比例要跟最终承载媒介匹配:如果图要放进 A4 纸打印的 Wiki 文档,画布比例建议用 4:3 或者 16:9,初始画布宽度设为 1200 到 1600 像素比较合适,字号按 12 到 14 磅设计。如果图要投到大厅幕布,字号至少 18 磅,连线粗细也要相应提高。画布的背景色我习惯用纯白或极浅灰,不用深色模式,因为深色底在打印和嵌入文档时经常出问题。
网格与对齐也是画布设置的一部分。我习惯打开网格线(网格步长设为 8 或 10 像素),节点尺寸尽量按网格整数倍设置,比如宽 180、高 56。这样后面做批量对齐时几乎不会出现“差两个像素怎么都对不起”的情况。很多图表看起来很糙,不是配色问题,而是大量节点位置不对齐、间距不一致导致的“微乱”。网格是改善微乱最廉价的手段。
3.2 元素规范:形状、颜色、字体、线型
一套可复用的 diagram-design 规范,本质上是对“形状、颜色、字体、线型”四类变量的严格约束。
先说形状。我给团队的默认规范是:圆角矩形代表服务或组件,矩形代表存储或集群,菱形代表判断,圆形代表外部系统或终端用户,圆柱代表数据库,横向粗线条代表消息队列或事件总线。这些并不一定是行业刚性标准,但必须做到“图内自洽”和“团队内统一”。最忌讳的是同一张图里,服务既用圆角矩形又用直角矩形,判断既用菱形又用六边形,读者得靠猜来判断图形含义。
颜色方面,不追求花哨,但要满足三个要求:语义色一致、对比度达标、灰度可区分。我会先定义 4 到 6 个核心语义色,比如主业务模块用蓝色系、支撑模块用绿色系、外部依赖用灰色系、告警与异常用橙红色系。颜色之间最好在灰度模式(去色)下也能拉开层次,因为很多文档会以黑白打印,或者部分读者是色弱人士。文字与底色对比度至少要保证白字在蓝色底上清晰可读,纯黄底配白字这种组合直接禁用。
字体我偏好无衬线字体,字号层级只设三档:图标题 20 到 24,节点主文字 13 到 14,辅助注释 10 到 11。避免在一张图里出现十种字号。节点内文字对齐统一左对齐,超长文字用省略号截断,不要自动换行产生三行四行的小段落,那是流程图大忌。
线型规范最容易乱:默认业务主链路用 2 像素实线;次要关联用 1 像素实线;数据流用 1.5 像素虚线;回调用 1 像素点划线。箭头形状统一为实心三角形,箭头大小不小于线宽的 3 倍,否则打印后箭头会糊成一团。虚线段的长度和间隔也要统一,最好用样式库定义,不要每根线手调。
3.3 布局与对齐的落地细节
布局策略我习惯总结成“先分块、再排内、后对齐”。
先分块:把画布按业务域划成若干大区域,每个区域对应一个分组。比如一个电商系统,我会把“用户中心”“商品中心”“交易中心”“支付平台”“外部依赖”先当作文档大纲一样列出来,按从左到右、从上到下的业务处理顺序摆放。这不是严格的线性流,但可以在空间上建立阅读顺序,读者自然会从左上角看起。
再排内:每个分组内部,将节点按依赖关系排列。对于同一层级的兄弟节点,尽量保证它们拥有相同的尺寸和间距;有主从关系的节点,主节点放在左侧或上方,从节点放在右侧或下方。节点内部的文字和图标不要贴边,留出至少 8 到 10 像素的内边距。如果节点内要带图标,图标统一放在文字左侧,图标尺寸和间距保持一致。
后对齐:选中同组节点后,统一执行“左对齐/上对齐/等间距分布”。这一步看似不起眼,却能让整张图的专业度上一个档次。我见过太多图,每个节点单独拖拽,结果细看之下没有两条边是平行的,没有两条间距是一样的。批量对齐功能基本所有工具都有,用一键操作替代手工微调,能省下大量时间。
关于层次感还有一个技巧:给当前组节点加一层极浅的同色系底色,并把边框粗细设为其他节点的 1.25 倍,作为视觉强调。同时把同组内非关键连线降为低对比度、细线,这样读者能在第一秒锁定核心结构,不会被全部连线淹没。
3.4 从草图到成图的五步推进
具体到一次实操,我的流程是五步,每步都有明确的产出物。
第一步:画“火柴盒草图”,只花十分钟。不要用电脑,就用纸笔,把所有需要用到的节点名字写出来,用圆圈圈住名字,用连线把有关系的圆圈连起来。这个阶段唯一目标是把信息抓全,不讲究美观。如果这步做不到列全节点,后面的图一定会反复改。
第二步:定“分组与通道”。把草图上的圆圈按业务域分组,用大括号或者色块框出组边界,检查组之间需要画几条连线,在组与组之间预留通道。同时剪掉那些“可有可无”的节点——比如一个只被调用一次、且不参与核心链路的工具类服务,可以收进下游分支,不要占主干位置。
第三步:上工具,搭主骨架。新建画布,设置网格,按分组把空的大区域定位好,先画出最大容器框,再在容器内排子节点。此阶段不做任何细致的颜色和字体设置,全部节点先用同一个默认样式。目的是先把拓扑结构和空间位置定下来。
第四步:连线与交叉整理。把所有关系线连上,然后集中处理交叉:调整相关分组的位置,让交叉最少化;对无法避免的交叉,采用“跨线”而不是“断线”的处理方式;在线段上添加文字注释时,确保注释文字与所标注线段颜色一致。
第五步:美化与校验。套用配色规范、线型规范、字号规范,统一箭头样式,调整留白和间距。最后把图缩小到实际使用尺寸(比如缩到 60%),离远看一遍,检查是否还能分清主次。如果缩小后糊成一团,说明视觉层级还不够,得继续加强分组底色、加粗主干线。
4. 常见问题与排查技巧实录
4.1 连线交叉怎么处理
交叉是最常见的图表问题,尤其在节点较多的架构图里。处理交叉有个很实用的策略:不要试图消灭所有交叉,而是把交叉集中到非核心视觉区域。
具体做法是:把交叉的连线分为“主要的”和“次要的”,优先保证主干连线完全正交且无交叉,允许部分次要连线在画面边角位置交叉。如果一个区域的交叉密集度过高,可以考虑增加一个重复节点——在另一处画同一个节点的替代框,并加上“同下”或“同左”的小标记,让连线就近结束,避免长线穿越大半个画布来制造交叉。
还有一招是“反转分支方向”。比如两个分组之间的连线,原本从上往下走会横穿第三个分组,这时可以把起点和终点分别调整到下侧和右侧,绕开中间分组。虽然连线路径变长了,但视觉干扰显著降低。总体原则是:宁可多绕一个弯,不要让线从别人“头顶”穿过。
4.2 图太密或者太空怎么办
图太密通常意味着粒度选粗了。当一个分组内超过 8 个节点且节点间连线超过 20 条,阅读效率会急剧下降。此时不要硬排,而是把该分组进一步拆成子图,在主图上保留一个“聚合节点”,子图内容附在附录或另一张图中,用相同的编号关联。
图太空则有两种可能:要么信息本来就少,要么留白分配不当。信息少时,可以适当增大节点尺寸,在节点内补充关键配置、负责人、状态标签等元信息,让图的内容密度合理。留白分配不当是指“局部紧、局部空”,这时不要无脑放大画布,而是重新审视分组边界,把空区域的分组边界缩进来,让整体画布保持紧凑。
我个人比较推荐“五秒测试法”:把画好的图出示给一个不了解背景的同事,只让他看五秒,然后问他“这张图讲了什么”。如果他答案里出现了最关键的两个模块名,说明密度合格;如果他说“好多框”“颜色很多”,说明需要继续做减法。
4.3 多端适配与导出清晰度问题
图表经常要同时放进网页文档、PDF、PPT 和打印件中。导出清晰度是我踩过最多的坑之一。早期用位图导出,觉得 200 DPI 足够,结果放到展厅大屏上全是马赛克边线。后来统一改成矢量导出(SVG 或 PDF),问题才彻底解决。如果你使用的工具只能导出位图,记得导出尺寸至少是实际展示尺寸的 2 倍,且关闭压缩。
另一个容易被忽略的是字号在缩放后的可读性。在画布上用 14 磅字号看着舒服,导出图片后嵌进文章页面可能会被缩到原尺寸的 70%,实际字重会变小。所以导出前,先把整图临时缩小 70%,看看最小字号是否还能认得清。如果不行,要么增大字号,要么截断无用内容。
浅色线条在浅色背景上的对比度问题也多发。尤其是浅灰色虚线的走向,在手机屏幕上一看就“消失”了。我把所有实线类线型的默认颜色设为深色(接近黑灰或深蓝),仅用线型区分语义,避免“颜色靠太近”导致的可读性灾难。
4.4 协作场景的版本管理
多人协作画同一张图时,最大的风险不是画得难看,而是各自保存一份本地文件,最后谁也不知道哪一版是权威。我们的做法是:所有正式图都放进集中式协同画板(云文档类工具),使用链接分享而不是文件传输。每张图必须在文件备注区写明“上次更新时间、当前唯一权威版本号、所属需求单号”。
对于经常变化的系统架构图,我甚至建议在图的左下角固定画一个“版本标签区”,记录版本号、日期和变更摘要。这样哪怕图片被截图发在聊天群里,别人也能知道这是哪个时代的版本,不至于拿着旧图讨论新问题。
如果团队规模较大,还应该设置“规范守门人”角色——不一定是专职,但每次新增图表进入知识库之前,由同一人快速检查是否沿用形状、颜色、线型规范。否则再好的规范也会因为每个人的审美偏好而沦为一纸空文。
5. 进阶思路:让 diagram 自己“说话”
5.1 动态图表与数据绑定
当图表里的信息会频繁变化时,静态图就显得力不从心。比如一个集群的实时状态图,如果用手工画拓扑,每加一台机器就要重新拖一个节点,运维根本维护不过来。这时候应该让图表“活”起来,跟数据源绑定。
常见的方案有两类:一类是数据可视化工具,通过查询接口获取节点状态,自动生成带颜色的拓扑节点,把“在线/离线/过载”直接用颜色表达;另一类是脚本化绘图方案,把图表当作代码来维护,节点列表来自配置文件,连线的生成通过遍历关系数组自动完成。两者的差别在于:前者适合非开发人员快速搭建面板,后者适合工程师把图表纳入 CI/CD 流程,文档和代码一起演进。
我个人的经验是,动态图表适合“高频变化”且“读者就是运维或研发”的场景。如果读者是高层或客户,动态刷新反而会让人怀疑数据真实性,不如定期导出的静态快照更能控制沟通焦点。所以不要让所有图都动态化,先问一句“变化频率是否高到必须自动化”。
5.2 用代码生成图表
代码化图表是 diagram-design 的另一个进阶方向。它最大的优点是可版本化、可 diff、可复用。当架构图描述的是基础设施代码时,图表里的节点和代码里的资源定义一一对应,从“画图”到“维护图”变成了“写代码自动出图”,彻底消除了“图与代码不同步”这个顽疾。
用代码画图的语调偏向工程,写起来很像搭积木:先定义节点样式,再定义分组,最后定义连线。对于复杂系统,还能通过脚本自动拉取云端资源列表,生成基础拓扑后再手工补充关系注释。需要提醒的是,代码化图表的上手成本比鼠标拖拽高,但如果团队规模超过十人、系统版本迭代频繁,这笔成本很快会被节省的返工时间抵消。
另一个好处是规范强制统一。在代码里定义了节点类型后,所有同类型节点天然使用完全一致的样式,不存在某个人手滑把颜色改了的情况。团队评审时,甚至可以只 review 生成的 diff,快速发现“哪个节点被移出分组”“哪条依赖被删掉”。
5.3 设计与工程的分工边界
说到这,必须说清楚 diagram-design 里“设计”和“工程”的边界。我见过一种团队状态:架构师画草图,工程师把草图落成图,最后设计同学再来调色。这个流程里,草图画得好不好直接取决于架构师能不能把层次想清楚,工具能力反而是最不稀缺的部分。
更健康的角色分配应该是:一个人负责“语义决策”——定分组、定主链路、定信息粒度;另一个人负责“样式执行”——把语义决策落到统一的形状、颜色、线型规范里。如果是单人完成整个 diagram-design,那也要在心里分两个阶段:先做语义,不碰颜色;再做样式,不改结构。把这两个阶段混在一起,是最容易把图越画越乱的原因。
边界明确以后,工具选型、规范制定、自动化脚本才能各司其职。否则你会遇到一种尴尬境地:设计做了精美好看的图,但结构上该合并的节点没合并;工程师写脚本自动生成了拓扑,但配色乱了套、连线交叉成堆。两边都不该背锅,问题是没人把 diagram-design 当做一个跨越设计和工程的工作。
我在实际项目里体会到最有用的一件事,就是把上述所有规范浓缩成一个十秒钟的口诀:先定受众与主张,再选类型和粒度;分组留白定通道,横平竖直少交叉;形状颜色有语义,线型粗细分主次;缩小五秒测可读,版本标签不要忘。每次画图画到一半没把握时,默默把这几个词念一遍,基本能把自己拉回正确的轨道。
这套流程不只适用于技术图,其实任何信息密度高、需要多人达成共识的图表场景,都会遇到相似的挣扎。如果看完这篇文章你觉得“画个图哪有这么多讲究”,恭喜你,说明你目前的图足够简单;但只要你开始处理那些节点超过二三十个、关系比较复杂、还要跨团队评审的图,就会明白今天聊的这些坑,几乎一个都绕不过去。下次再有人扔给你一句“随便画个图呗”,希望你能自信地回一句:给我一分钟想清楚,再给我几小时画明白。