
干技术的这些年我有个越来越深的体会写代码容易画图难。所谓画图指的不是 UI 设计稿也不是数据可视化报表而是项目里几乎每天都要碰的架构图、流程图、时序图、部署拓扑图。diagram-design 这个名字听起来像个绘图小工具但它背后其实是一整套被很多人忽略的工程方法论用设计思维组织信息、用统一规范约束图形、把复杂关系画成一眼能看懂的结构图。很多人觉得图嘛能看懂就行了但能看懂和设计过之间的差距恰恰是一次架构评审里别人能不能快速抓住重点的区别。这篇文章我想把 diagram-design 这套方法论拆开来讲图表的选型逻辑、视觉元素的设计规范、代码化绘图工具以及一次完整的实操走查。适合谁参考如果你是后端、前端、DevOps经常要给团队画架构图如果你是技术文档负责人需要约束一群人产图的风格又或者你是刚入行的新人想系统提升画图水平这篇文章都能给你一套可以直接落地的参考做法。文中所有的规则和步骤都是我日常画图踩过坑之后沉淀下来的不是教科书理论。1. 先搞清楚diagram-design 到底解决什么问题1.1 代码里写逻辑文档里画逻辑写程序的时候我们用代码表达逻辑。代码是线性、精确、可执行的机器能跑人也能读。但到了文档、方案评审、新人 onboarding 这些场景代码反而不合适了。人的视觉系统处理图形信息的速度远高于逐行读文字尤其当你要表达的是模块间的关系、一次请求的流转、一套系统的分层时一张图比一千行说明都有效。这里就引出一个核心问题图的本质是什么。我的理解是图是一个信息压缩器把多维的关系压进一个二维平面让读者用眼睛扫一遍就能抓出结构。diagram-design 的价值不是把图画得好看而是确保压缩的过程中不丢信息、不引入歧义、不增加认知负担。你画下的每一个方框、每一条箭头本质上都是对信息的一次编码编码规则越清晰读者的解码成本就越低。1.2 为什么能看懂和设计过差距巨大两张内容一模一样的架构图一张是随手把方框排开、连上箭头一张经过设计做了分组、对齐、留白、语义色。读者看第一张可能要花三分钟看第二张可能只要三十秒。差距不在绘画技能而在有没有设计约束。设计过的图通常有四个特征第一有明确的层次先看什么、后看什么扫一遍就有顺序第二有合理的分组相关的东西在视觉上靠在一起第三有统一的视觉语言形状、颜色、线型都代表固定的含义不会同一张图里一会儿方块、一会儿圆角、一会儿箭头乱指第四密度高但不累人信息再多也靠留白维持呼吸感。这些特征不是玄学背后是认知心理学里的格式塔原则。比如接近原则靠得近的元素会被看成一组所以你把相关模块放在一起读者天然就会认为它们属于同一个领域。还有对称、连续、闭环这些原则在图上也都直接转化为视觉秩序。所以 diagram-design 的第一课不是学工具而是建立图上每个元素都有语义的意识。你画的每一个边框、每一条线都是在给读者发信号。信号一致图就专业信号混乱图就廉价。2. 图表分类与选型逻辑先别动手先选对图2.1 按关系类型选图先确定你表达的是哪种关系很多人画图失败不是因为不会画是因为选错了图型。我见过有人想表达模块间的父子层级结果画成一张流程图有人想表达服务间的调用关系结果画成一张部署图。图型不对后面再怎么设计都是别扭的。我平时会把技术图先按要表达的关系类型分成六类。选图之前先问自己一句这张图的核心信息是一种步骤推进还是一种结构划分还是一种时间顺序上的交互答案不同图型就完全不同。图型表达的关系典型场景常见工具流程图随时间或条件推进的步骤业务处理、异常分流、审批流程通用绘图工具、代码绘图时序图时间顺序上的交互与消息API 调用链、跨服务协作PlantUML、专用时序工具架构图系统的静态结构与分层模块边界、部署拓扑绘图工具、架构专用工具层级图父子、上下位归属关系组织架构、目录结构树状结构工具关联图实体间的多对多关系数据模型、依赖关系实体关系工具状态图状态迁移与事件触发订单状态机、设备状态机状态机专用工具2.2 选型实战同一个需求图为什么不一样举个例子。给你一个需求用户下单后订单系统需要校验库存、扣减库存、通知物流。围绕这个需求你可以画三张完全不同的图。第一张画流程图表达的是流程按照什么顺序推进先校验、再扣减、再通知读者关注的是先后步骤第二张画时序图表达订单服务、库存服务、物流服务三个角色之间消息的时间顺序读者关注的是谁在什么时刻调用了谁第三张画架构图表达订单服务在整个系统里处于什么位置、和哪些外部系统对接读者关注的是模块边界和数据流向。选图的关键是你心里清楚希望读者获得哪种认知。什么时候做什么选流程图谁在什么时候调用谁选时序图系统是怎么被切分的选架构图。一张图解决一个问题是 diagram-design 的第一条纪律。我见过太多人想把流程、状态、部署、数据模型全都塞进一张图里结果谁也没看明白。克制永远比全面重要。3. 图上视觉元素的设计规范靠细节拉开差距3.1 节点形状、边框、阴影都有语义节点是图的基本单元。很多人做第一件错事就是全图只用一种矩形然后纯靠文字去区分节点类型。这个做法相当于把本可以靠视觉立即识别的信息硬生生变成了逐个文字阅读读者累信息密度也低。我给团队立的规矩是固定一套语义映射圆角矩形代表功能模块直角矩形代表外部系统或第三方服务平行四边形代表数据库或存储菱形代表判断分支。这套映射一旦定下来全团队复用谁画的图读起来都像出自一个人。边框粗细也有讲究核心模块用粗边框次要模块用细边框灰色虚线框代表规划中或未上线的部分。这样读者哪怕不读文字扫一眼也能感觉到主次差异。还有个建议技术图里尽量不要用阴影和立体效果。图是二维信息图不是三维渲染图。阴影会干扰视觉分层让边框的粗细、颜色的差异都变得不明显在部分渲染环境里还会造成图片体积膨胀。保持扁平让你的语义靠形状、颜色和位置来表达。3.2 连线箭头方向、线型与拐角的秩序线是图上被忽略得最严重、又最影响可读性的元素。我见过一张图全是斜线节点之间绕来绕去箭头还双向乱指读者根本没法快速追踪流向这张图基本就报废了。几条硬规则都是我实测下来最有效的。第一连线保持正交横平竖直不画斜线。如果工具支持设置拐角为直角立刻打开。斜线在视觉上暗示混乱而正交线暗示有序这个感知差异非常直接。第二箭头方向统一主流程从上到下或从左到右尽量不要出现向上或向左的主流线更不要双向箭头乱开。第三线型做语义区分实线代表常规调用虚线代表异步、弱依赖或者可选路径粗线代表核心链路和关键请求路径。第四所有连线不能穿过节点绕一点路可以穿过去不行一穿读者的视线就断了。3.3 颜色与字体克制是最高级的专业颜色是最容易被滥用的设计元素。一张图超过五种彩色读者的注意力就全部被色块抢走根本还在读图说话而不是吸收信息。我的调色策略是背景用灰色白色中性色节点最多三种语义色连线不超过两种颜色强调色只用于异常路径或核心链路。我这里给一套可以直接抄的语义色定义蓝色代表正常模块绿色代表已上线或稳定状态橙色代表需要关注或告警红色代表异常和高风险。这个语义全团队统一不要这次用蓝代表模块、下次用蓝代表外部系统。换了语义读者就得重新学习一次图的效率就下降一分。字体方面也是一样。一套中文字体加一套英文等宽字体就够用不要为了丰富混五六种字体进去。字号分三级图标题最大核心节点次之说明性文字最小每级之间要有肉眼可辨的倍数差不要靠一两个像素去区分。另外节点里的文字长度也要控制一般来说不超过四到六个字太长就拆到注释里。3.4 布局与分组把看起来能读提升到一眼看懂布局是 diagram-design 里最体现功力的一环。布局做得好读者从左上角进入顺着视线流看完右下角中途不需要回头布局做得不好读者在图上四处找线找到后还要确认自己没走错阅读体验极差。第一个技巧是分组。相关模块外面套一个大圆角框框顶部写组名也就是我常说的容器化。分组之后读者先看到几大块再进入每一块看细节认知层级瞬间拉开。这个技巧对超过十个节点的图几乎是强制性的。第二个技巧是对齐。同一层级的节点顶部要对齐左右间距要一致手工拖拽做不到就花时间用工具里的对齐功能。不对齐的图会产生一种草稿感哪怕内容是对的读者也会下意识觉得不可信。第三个技巧是留白。节点之间、分组之间的距离要明显大于节点内文字到边框的距离否则整张图就像一堵密不透风的墙。我画图时有个习惯草图完成先看三秒。如果三秒内我说不出这张图可以分几大块说明布局失败了必须重新分组。这个习惯帮我快速揪出布局问题比对着细节调半天高效得多。4. 用代码驱动图形从手画到工程化4.1 为什么我推荐代码驱动画图手绘工具适合临时头脑风暴不适合放仓库长期维护。原因有三个第一版本管理困难同事改了你都不知道改了什么图文件也没有 diff 可说第二多人协作风格难以统一每个人拖拽出来的结果都不一样第三没有自动化的可能代码改了文档还是旧图维护全靠自觉。代码驱动绘图解决的就是这三个问题。图只是一份文本文件改动天然可以 diff评审的时候能看到改了哪个节点、加了哪条线风格可以通过共享样式约束团队用同一份主题配置还可以接入 CI在文档构建时自动渲染图片。diagram-design 要进入工程化阶段代码绘图基本是必选项这不是时尚而是可维护性要求。4.2 适合工程文档的几种代码绘图方案先说 Graphviz这是老牌布局引擎用 DOT 语言描述节点和边。它擅长树形结构、依赖关系、流程图布局算法很强连线放置基本不用操心。缺点是布局不可精确控制想手工微调某条边的位置时会比较费劲。下面这个例子描述了一个简单的部署关系digraph deploy { rankdirTB; node [shapebox, stylerounded,filled, fillcolor#EEF2FF]; edge [color#64748B, arrowheadnormal]; gateway [labelAPI 网关]; order [label订单服务]; stock [label库存服务]; db [label订单数据库, shapecylinder]; gateway - order; order - stock; order - db; }你只需要描述节点和边的关系布局算法是 Graphviz 自己的责任。这种只描述关系不描述坐标的思路正是代码绘图的核心优势。再说 PlantUML。它最擅长时序图和活动图语法接近自然语言评审的时候直接在 PR 里读代码就能理解图的内容这是它最大的价值。比如下面这段时序图读起来和讲话差不多startuml actor 用户 participant 订单服务 as O participant 库存服务 as S 用户 - O: 提交订单 O - S: 扣减库存 S -- O: 扣减成功 O - 用户: 下单成功 enduml第三类是基于 JSON 或 JavaScript 的绘图库。这类方案适合把图嵌进前端页面做交互展示可以点击、折叠、联动数据很适合数据可视化和动态分析场景。但缺点是依赖前端渲染链路通常不能直接放进 Markdown 文档离线阅读对普通技术文档来说有点重。对大部分技术团队来说Graphviz 和 PlantUML 已经覆盖了绝大多数需求。4.3 代码绘图的可维护性代码绘图的优势只有配上工程规范才能真正发挥。一个常见的坑是图代码放进仓库了但后面没人维护代码改了好几版图还在原地踏步三个月后这张图就变成了负资产新人照着理解系统方向全错。我的建议有三条。第一图代码跟随对应模块的代码存放不要收进一个独立的总图目录这样谁改了模块代码就会在自己的目录里看到图文件顺手更新的概率高很多。第二图文件头部写清楚信息这张图对应哪个版本、上次更新日期、维护者是谁把维护责任落到人。第三尽量让图和文档在同一个构建流水线里出产物文档发布时自动渲染图片避免手工导图导致的过期。这三条不一定能做到完美但每做到一条图的寿命就能延长一大截。5. 实操过程从需求到成图的一次完整走查5.1 需求与信息收集真正要画的是什么我给自己定了一套流程每次画图都走一遍已经有几年了。第一步不是打开工具而是先收集信息。拿订单提交流程举例先列出所有参与方用户、订单服务、库存服务、支付服务、物流系统再列出所有关键动作下单、校验库存、扣库存、发起支付、通知物流最后列出分支条件库存不足怎么办、支付失败怎么办、超时怎么处理。三类信息都列出来图的骨架也就有了。这一步最容易犯的错是知道的都往上放。我理解画图的时候总想展示自己对系统了解全面但信息收集阶段允许多设计阶段必须做减法。先确定这张图当前版本必须表达的最小集合其他内容放到后续版本的待定区不要试图在一张图里装下整个系统。5.2 草图与信息分层信息骨架确定后我在草稿纸上做信息分层。第一层是主链路只有一条主线从左上角往右下角走这是读者一定要跟着走完的路第二层是分支和异常路径放在主线下方用不同颜色标注第三层是外部系统和辅助说明放在两侧用容器框框起来。画草图的时候我会刻意用容器化思维同一参与方的所有节点放进一个容器容器之间再画交互。比如订单服务相关节点放一个容器库存服务相关节点放另一个容器容器之间只有几条粗连线。这个习惯能避免最典型的布局混乱——子细节和主结构搅在一起整个图变成一张分不清主次的网状结构。5.3 用代码落地与迭代草图满意之后我会用 Graphviz 落地第一版。这里有个关键操作习惯不要一次写完所有内容。先只写骨干节点和连线把主链路跑通渲染出来看看布局觉得方向不对就调整 rankdir方向设置或者增加 cluster分组容器骨架稳了再往里加细节节点再加异常分支。每加一轮渲染一次确认没有破坏整体结构再继续下一步。这个分阶段迭代的方式能帮你省下大量时间。如果一次性写完二十个节点和三十条线再渲染大概率得到一张布局混乱的图然后你花两小时手工调结构最后还是一团乱麻。画图和写代码一样小步快跑永远比憋大招稳妥。我在这个环节最常在一次到位上栽跟头后来强制自己每轮只改一个维度才把问题压住。5.4 导出与嵌入文档统一风格图在本地验证通过就进入文档体系。我通常输出 SVG 而不是 PNG。SVG 是矢量格式放大不糊在 HTML 文档里还可以加链接、支持交互PNG 适合聊天工具里快速分享正式技术文档还是 SVG 更专业。如果平台不支持 SVG 上传那至少把源文件保留好下次改图不要从 PNG 反推。嵌入文档之后我还做一次全局风格检查。同一份文档里有多张图的话背景色、节点形状、箭头样式、色板必须一致。最理想的做法是把样式定义抽到共享配置里不同图复用同一份 style 定义这样改一处全部图同步更新。风格统一是 diagram-design 的终局目标也是判断一个技术团队文档成熟度的重要指标。你去看那些文档体系做得好的开源项目图的风格一定是一致的这不是巧合。6. 常见问题与排查技巧实录6.1 连线乱飞先回到底层重新分层谁都有过这种经历图改着改着节点越来越多连线开始乱飞想挪一个节点结果牵一发而动全身。我的对策是不要去修补乱图回到草图层面重新分层。连线交叉严重百分之九十的原因是层次过多或分组不清晰。把骨架重新画一遍把外部系统和内部模块分开层大部分交叉线会自己消失。还有个排查技巧数一数每个节点的连线条数。如果某一个节点连出六条以上的线说明它承担了太多职责要么把它拆成几个节点要么在它前面引入一个中间层。图里的单一职责原则和代码里一样重要一个节点连太多线读者根本分不清哪条是主链路哪条是次要依赖。6.2 信息过载给图做减法图里塞了太多文字每个节点都是一大段描述这种情况经常出现在新人画的架构图里。解决办法是文字分层节点里只写名称详细说明放到图下方的注释区或者用脚注关联到具体模块。如果一张图超过了二十个节点就考虑拆成两张子图母图画结构子图画细节各司其职。我给自己定的红线是一张图让一个完全不了解背景的新读者看十五秒如果他说不出大致结构和主链路就算过载必须做减法。减到什么程度减到只保留表达最小核心信息为止。那些以后可能有用的节点暂时拿掉等到真正需要的时候再放回去。6.3 风格不统一把规范固化成模板同一个项目里有人用蓝色方框有人用绿色圆角有人画箭头用直头有人用弯头多张图摆在一起视觉上完全像是不同公司的人画的。根治方法不是开会喊口号而是把风格规范固化成代码模板。颜色色值、形状映射、线型规则全部写进项目文档Graphviz 里用共享样式文件PlantUML 里用 include 公共主题。容易被忽视的是箭头风格这个小细节。箭头用直头还是 V 形头团队必须统一。这种细节读者未必能说出来哪里不舒服但整篇文档读下来这种不统一感会在潜意识里降低内容的可信度。别小看视觉一致性它是在给文档的整体专业度加分。6.4 图和代码不一致用工程手段治理这是我最痛恨也最普遍的问题。图刚画完是准确的后面代码改了图没人更新三个月后这张图就成了负资产。新人照着它理解系统方向全错。除了前面说的代码和图就近存放我还建议在文档里标注这张图的生成时间和对应的代码提交哈希。另一个更彻底的做法是把图纳入代码评审范围PR 里有代码改动却没有同步更新图评审人应该主动问一句这张图是不是也改了画图能力不是天生的它跟写代码一样可以被刻意练习。我自己的体会是练习的关键在于每次画完都复盘一次这张图哪里让读者困惑了连线是不是乱颜色是不是吵一遍遍复盘设计约束就会慢慢内化成直觉以后画图不用再翻规范落笔就是有序的。最后再分享一个小技巧每次画完图把它拿给一个完全不了解背景的同事看十秒然后问他这张图讲了什么。如果他能说出个大概说明图合格了如果他说不出来别解释别补充背景直接重新设计。这个测试成本极低但比你自己盯着图看半小时更能反映真实的可读性。我现在每张正式对外发布的图都要过一遍这个测试过不了的图坚决不发出去。