"画过图的人都懂,真正难的不是把图'画出来',而是把图画到别人一看就懂、三个月后再看还能改、团队里谁接手都不骂娘。diagram-design 这个目录我之前见过太多次——多数情况下里面躺着一堆风格迥异、箭头乱飞、颜色随缘的示意图,有的连图例都没有,有的已经和代码对不上。它不是个小问题,而是文档质量的分水岭:图一旦失控,整个项目的沟通效率会肉眼可见地往下掉。这篇文章想聊的就是我如何从'画图'走到'设计图'这一套方法。核心涵盖读者分析、信息分层、代码化绘制、视觉规范和团队协作,适合正在整理项目文档、想建立图表规范的开发者,也适合那些明明技术很强、但一画图就翻车的同学。内容全部来自真实项目里的反复折腾,不是教科书,是我踩坑之后沉淀下来的可直接照做的经验。1. 为什么大部分技术示意图都不及格:Diagram设计的本质是信息压缩入行头两年,我一度以为画图靠审美。直到有一次给新来的同事讲系统架构,我打开一张精心配色的架构图,对方盯着看了半分钟,问了一句:'所以这个框是服务还是数据库?'那一刻我才意识到,图的问题不是好不好看,而是信息传达是否有效。1.1 常见的四类"废图":信息过载、箭头乱飞、图例缺失、版本漂移信息过载是最常见的。一张图里塞了二十个节点、十几条连线、五个不同的颜色、三种线型,画的人觉得自己把整个系统都讲清楚了,看的人其实什么都记不住。人类短时记忆能处理的信息组块非常有限,一张图超过七个关键元素,理解成本就开始成倍增加。箭头乱飞是第二类。很多图的连线不是从下往上穿,就是从左往右绕,节点之间的线条交叉得像一团毛线。我见过一张时序图,光箭头就有十一种语义,没有图例说明,作者自己也说不清虚线、点线、双线分别代表什么。图例缺失是第三类。颜色用红色标了异常路径,黄色标了降级方案,但图边上没有任何说明。读者只能靠猜,猜错了就把责任算在画图的人头上。版本漂移最隐蔽也最伤。架构改了三轮,图只更新了一版,于是文档里的图和线上真实系统越来越不像,最终变成一堆精致的无用装饰。1.2 图不是画的,是设计的:设计与绘画的区别我后来想明白一个道理——技术图不是绘画,是工程图纸。绘画追求表达,工程图纸追求精确。一张合格的技术示意图,应该让读者在十秒内回答三个问题:这张图讲的是什么范围的事?里面有哪些关键对象?它们之间是什么关系?达到这个标准靠的不是天赋,而是一套可重复的决策流程。Diagram设计本质上是在做信息压缩:把复杂的系统、流程、数据结构,降维成一张读者能快速扫描的二维平面图。压缩得好不好,取决于画图的人有没有想清楚哪些信息保留、哪些信息丢弃、哪些信息放在第一层、哪些放第二层。刚开始做规范的时候,我给自己定了一个原则:画图之前不许打开画图工具。先写清楚这张图要回答什么问题,再动手。这个习惯沿用到现在,帮我避掉了大量返工。2. 动手前先定三件事:读者、信息层级、图的内容边界很多图是在'手痒'状态下画出来的。想到一个模块就加一个框,觉得流程缺一环就补一条线,最终图越滚越大,效果越来越差。要改变这种局面,必须在动笔之前做完三个决策。2.1 第一件事:确认读者会拿图做什么图的读者决定了图的画法,这个道理很多人忽略。给架构评审委员会看的图,突出的是模块边界和依赖方向;给新员工看的图,突出的是核心流程和数据走向;给运维同学看的图,突出的是服务实例和部署关系。用途不同,图的构图完全不同。我在某跨平台系统的文档整理中做过一次对比:同一套系统,我先后画过四个版本的架构图,分别服务技术选型评审、模块开发分工、线上故障排查、新人入职培训。四个版本画出来的节点选择、连线口径、标注粒度几乎没有重叠。这说明图不是系统的照片,而是系统的'切片'——针对某个视角的信息抽取。判断读者需求有个土办法:问自己一句,'如果对方只能看图、不能问我,他最怕漏掉什么信息?'这个问题的答案,就是图的中心主题。2.2 第二件事:拆信息层级把要表达的内容拆成三层:主层、支撑层、跳转层。主层是这张图必须表达的核心关系,支撑层是帮助理解主层的上下文信息,跳转层是细节,但不放进当前图,而是通过图号或外部链接引导读者去别处查。举个例子,我在画支付链路时序图时,主层就是发起支付、风控校验、锁定账户、返回结果这条主线。支撑层是超时时间、重试次数这几个参数标注。跳转层是每个环节内部的异常分支——那些内容我绝不画进同一张图,而是单独拆成异常流程子图。这个分层的逻辑和代码重构很像:一个函数承担太多职责就拆函数,一张图画了太多主题就拆图。2.3 第三件事:决定什么是"不画"这可能是整个diagram-design里最重要的一步。我见过太多人栽在看什么都重要、什么都舍不得丢。画图必须做取舍,而且要主动舍弃那些'有关系但不关键'的边边角角。我常用的判断标准是:如果删掉某个节点,阅读理解会不会受影响?如果删掉不影响,就删掉;如果读者需要点击或者翻页才能搞懂,那不是主层信息,应该放到跳转层。删完之后再看一眼,通常还能再删掉一批。有个可量化的参考值:一张技术示意图的节点数量建议控制在5到12个之间。少于5个可能不需要图,多于12个就应该考虑拆分。这不是硬性规定,但当图超过这个规模时,我基本都会重新考虑信息分层。3. 代码化绘图:为什么我建议把图当作代码来管理Diagram设计里最值得投入的一件事,就是把图变成代码。过去我用拖拽工具画图,画完导出图片往文档里一贴,以为大功告成。直到某次架构调整要改二十多张图,我才发现每张图都要手动点开、移动框体、调整线条,改完一张忘一张,还要反复确认有没有漏改。3.1 从手绘/拖拽工具转到代码化方案的理由代码化绘图的核心收益是三点:可版本管理、可自动化渲染、可统一风格。图源文件可以和代码一起提交到仓库,每次改动都有diff记录,评审的时候可以精确指出'第三张图第5个节点改了名字',而不是发一张图片让团队猜改了哪里。风格统一在团队协作中尤其重要。手绘和拖拽工具里,每个人的审美都会带进来——有人喜欢圆角框,有人喜欢直角框,有人阴影开满,有人容不下一点多余线条。代码化之后,样式集中定义,渲染结果完全一致,个人偏好被约束在可控范围内。持续集成也是代码化带来的额外好处。文档流水线里加一步渲染任务,源文件变了,渲染产物自动更新,图永远跟着文档走,从源头上消灭了版本漂移。3.2 主流代码化方案对比:怎么选才不后悔我用过不少方案,这里列几个有代表性的,按适用场景说透一点。文本图方案,比如用字符拼图,适合放在源码注释、命令行帮助文档里,零依赖、任何地方都能看,缺点是表达能力有限,稍微复杂一点就难以维护。图描述语言方案,这类工具发展得比较成熟,语法简单,上手快,颜色和连线的可编程空间足够。我现在的主力方案就是这一种——不是因为它功能最全,而是因为它在简单和强大之间平衡得最好,社区生态和导出格式都比较稳。类描述语言方案,对严谨建模友好,适合表达类关系、状态机这类强结构内容。但它的语法有学习成本,日常画个流程图写它有点重,灵活性也不如同类通用方案。手绘风格方案,适合画产品原型、头脑风暴、非正式讨论,写起来舒服,视觉上亲和力强,但不适合当作正式技术文档的统一标准,因为画出来的样式受手写轨迹影响,换个环境渲染结果就可能不一样。我之前在某图像处理Demo的文档里做过一次完整对比,最终留在日常工具箱里的是:正式文档用类描述语言方案的变体,快速草图用手绘风格方案,源码内的说明用文本图方案。没有哪个方案是万能的,关键是按场景分工。3.3 一个最小可用的工程化目录结构如果团队想从一开始就按代码化的方式管理图,下面这个目录结构可以直接照搬,它是我在多个项目里验证过的布局。docs/ diagrams/ src/ # 图源文件 system-overview.mmd payment-sequence.mmd retry-states.mmd out/ # 渲染产物 system-overview.svg payment-sequence.svg retry-states.svg scripts/ # 批处理脚本 render-all.sh README.md源文件和渲染产物分开存放,出图脚本集中放,这样有几层好处。第一,渲染产物可以随时重新生成,不需要手动维护;第二,不同图之间的公共样式可以抽成共享文件,改一次,全部生效。第三,脚本可以批量渲染,新同事入职之后不需要了解画图工具内部逻辑。我在实际项目中会把全量渲染脚本做成一个简单的Shell脚本,遍历src目录下的源文件,逐个调用渲染命令,输出到out目录。持续集成只需要在文档发布前执行这个脚本。4. 把图做"干净"的六个细节:布局、对齐、色彩、字体、图例、边界工具选好之后,真正拉开差距的是视觉细节。下面这六个方面是我在整理diagram-design规范时反复打磨出来的,也是最容易被忽略的地方。4.1 布局与对齐:让信息流的方向可预测人的视线习惯从左上到右下,所以画图要顺着这个方向安排信息流。主流程从左到右,或者从上到下,不要做蛇形曲线。分支流程放在主流程的同一侧,不要一会儿左边一会儿右边。对齐的选择要显式且一致。能对齐的边界尽量对齐,能等距的间距尽量等距。我见过很多图画得'还行但总感觉乱',问题就出在间距不一致。框体之间的距离忽大忽小,整张图的节奏感就没了。初始排版可以用工具自动布局,但最后一定要手工检查一遍关键节点,自动布局常常会在语义相邻的节点之间留下多余空白。4.2 色彩数量控制与语义化配色颜色是语义工具,不是装饰。我的规范是单张图最多三种主色,允许一到两种强调色。出现第四种主色之前,先怀疑是不是图塞了太多主题。常用的语义约定如下:颜色语义使用场景中性灰/深灰常规节点服务、模块、步骤蓝色核心主链路主流程节点、关键路径绿色正常/成功成功分支、健康状态红色异常/失败错误分支、告警路径橙色降级/警告限流、降级、重试路径色盲安全性也要考虑,建议不要只靠颜色区分关键信息,可以搭配线型、图标、文字标注。我在规范里要求任何颜色语义都必须在图例中标明,不标颜色的图不允许对外发布。4.3 字体与可读性:正文优先,装饰靠边字体选择上,标题、正文、注释的层级要拉开。框内节点名常用中号正文,分组标签用小号,重要说明用加粗或高亮。统一的字体栈要维护在公共样式文件里,不要每张图都手动改。强调一点:在允许的格式,如SVG和PNG上,优先选择无衬线字体,中文环境优先系统自带的高可读性字体,不要为了'好看'选择非主流字体库。嵌入式环境里如果找不到可用字体,渲染出来的字形会随机替换,那才是真正的灾难。4.4 图例、编号与跨图引用:让图可被索引规范化之后,每张图都应该有一个稳定编号,比如'图2-1:系统总体架构'。正文引用时用编号而不是'下图',这样文档排版变化、图片顺序调整之后,引用关系不会断。跨图引用是很多人忽视的细节。如果主图里某个模块在另一张图里有详细展开,就在这个模块旁边标注'详见子图2-3'。这样读者就知道细节不在当前图,不用盯着主图发呆。图例的位置固定在图的右下角或左下角,内容包含所有用到的线型、颜色、符号。哪怕只有三种颜色,也要放图例。我见过太多图没有图例,靠读者猜,猜错的代价比少画一条线大得多。5. 一套可以直接抄的diagram-design工作流方法讲了一堆,落到日常执行,需要一套能坚持的工作流。下面是我目前在用的,整体思路是'先写文字,再画图'。5.1 先写图说明,再画图这个看起来反直觉,但非常管用。每画一张图之前,我要求自己在图的上方或注释里先写三行话:这张图的目的是什么,主要读者是谁,图里包含哪些关键对象和关系。写完这三行再画,图的边界自动就清楚了。举个例子,我在画某跨平台系统的部署拓扑图之前,先写了这样一段:目的:展示三个环境下的实例分布和网络接入方式。 读者:运维同事、排查线上问题的开发。 关键对象:接入层、应用实例、存储集群、消息队列。写完之后,我发现自己根本不需要画DNS解析细节,也不需要画客户端内部逻辑。少画了一半的内容,图反而清楚了许多。5.2 每次改图的检查清单我把改图之前要做的事整理成了一份检查清单,现在团队里用着挺好。这次改动的动机是什么?如果是需求变更,写明对应的需求编号。图里的节点和连线是否与当前代码一致?不一致的地方就是这次改动的重点。新增节点是否超过了单张图的信息量上限?超了就拆图。颜色、线型是否沿用了公共样式定义?不要新造颜色。图例是否同步更新?新增的语义是否已经写进图例?跨图引用编号有没有变化?变化了要同步改正文引用。这份清单不用打印出来挂在墙上,在代码评审里加上一条'图变更需附检查记录'就能贯彻。5.3 团队协作中的命名规范源文件的命名要具备自解释性,比如用户登录流程就写login-flow,不要叫final_v2。一个项目里所有图源文件按主题前缀分组,比如架构图用arch-开头,时序图用seq-开头,状态图用state-开头。渲染产物和源文件共用同名前缀,后缀区分格式。目录划分建议参考前面提到的工程化布局,视图层和逻辑层分开。命名规范在团队里的作用是降低新人上手成本,让每个同学打开仓库就知道什么文件放哪里。6. 我在实际项目中踩过的坑:从混乱到规范的一次重构理论说多了,聊点真实场面。有一回我接手一个大型项目的文档整理,那里的diagram-design目录让我印象极深——不是因为它规范,而是因为它乱得具有代表性。6.1 重构前的状态:六套图、五种风格、零注释那个目录里一共有几十张图,分属六套子文档,画风五花八门。有的是拖拽工具导出的彩色方块,有的是文本图,有的是手绘风格的草图,唯一统一的是没有一张图带图例。架构改过三轮,旧图没有归档,新图直接覆盖,结果就是文档里同时存在已经下线了的模块和还没上线的占位符。我把所有图归拢之后做了件事:按我前面说的流程,给每张图补上'目的、读者、关键对象'三行注释,再决定这张图是保留、合并、还是直接废弃。最终真正留下的图不到原来的三分之一,但每一张都能说清楚服务谁。6.2 重构中遇到的问题:工具绑定、中文渲染、复杂图拆分重构过程中遇到三个典型问题,值得单独说。工具绑定很麻烦,旧图用的是闭源格式,编辑必须装对应客户端,渲染结果换个环境就变形。我最终把所有需要保留的旧图全部重画成代码化源文件,这也顺便解决了后续协作的准入问题。中文渲染踩过不少坑。默认字体在某些环境下对中文支持不佳,出现乱码或者字形错位,解决方式是显式在公共样式里指定中文字体栈。另一个细节是中文文本在框内换行时,要把分词逻辑处理对,不然一行长文本会把整个节点撑变形。复杂图拆分是一次认知升级。原来有一张系统全景图,包含几十个服务和数据流,怎么摆都乱。按模块拆成主图和四张子图之后,主图只保留各模块之间的依赖,子图专门负责模块内部细节,阅读体验立刻就不一样了。跨图引用的编号也在这个阶段补全,之后所有正文都改用'图编号'引用。6.3 重构后的效果与经验沉淀重构完成后,新同事理解系统架构的时间从之前的两三天缩短到半天以内,排查流程图指向模糊的问题也基本绝迹了。更重要的是,后续架构演进时改图不再是一个心理负担,源文件改一行、渲染全出,所有图自动保持同步。从那次重构之后,我养成了一个习惯:每画一张图,都把它当成要交给下一个维护者的代码来写。写注释、起好名字、保持边界清晰、控制复杂度、统一风格、纳入版本管理,这些标准搬到图上也完全成立。如果你现在手头就有个乱糟糟的diagram-design目录,不妨从今天开始按这个方法重理一遍。先别急着重画,先回答三件事:图给谁看、表达什么关系、哪些细节不画。把这三件事和老图对齐,你会发现大部分图根本不需要保留,留下来的只需要很小的改动就能焕然一新。之后每次新图都照这个流程走,文档的图表质量会稳定在一个不会让你尴尬的水准线上。
"画过图的人都懂,真正难的不是把图'画出来',而是把图画到别人一看就懂、三个月后再看还能改、团队里谁接手都不骂娘。diagram-design 这个目录我之前见过太多次——多数情况下里面躺着一堆风格迥异、箭头乱飞、颜色随缘的示意图,有的连图例都没有,有的已经和代码对不上。它不是个小问题,而是文档质量的分水岭:图一旦失控,整个项目的沟通效率会肉眼可见地往下掉。这篇文章想聊的就是我如何从'画图'走到'设计图'这一套方法。核心涵盖读者分析、信息分层、代码化绘制、视觉规范和团队协作,适合正在整理项目文档、想建立图表规范的开发者,也适合那些明明技术很强、但一画图就翻车的同学。内容全部来自真实项目里的反复折腾,不是教科书,是我踩坑之后沉淀下来的可直接照做的经验。1. 为什么大部分技术示意图都不及格:Diagram设计的本质是信息压缩入行头两年,我一度以为画图靠审美。直到有一次给新来的同事讲系统架构,我打开一张精心配色的架构图,对方盯着看了半分钟,问了一句:'所以这个框是服务还是数据库?'那一刻我才意识到,图的问题不是好不好看,而是信息传达是否有效。1.1 常见的四类"废图":信息过载、箭头乱飞、图例缺失、版本漂移信息过载是最常见的。一张图里塞了二十个节点、十几条连线、五个不同的颜色、三种线型,画的人觉得自己把整个系统都讲清楚了,看的人其实什么都记不住。人类短时记忆能处理的信息组块非常有限,一张图超过七个关键元素,理解成本就开始成倍增加。箭头乱飞是第二类。很多图的连线不是从下往上穿,就是从左往右绕,节点之间的线条交叉得像一团毛线。我见过一张时序图,光箭头就有十一种语义,没有图例说明,作者自己也说不清虚线、点线、双线分别代表什么。图例缺失是第三类。颜色用红色标了异常路径,黄色标了降级方案,但图边上没有任何说明。读者只能靠猜,猜错了就把责任算在画图的人头上。版本漂移最隐蔽也最伤。架构改了三轮,图只更新了一版,于是文档里的图和线上真实系统越来越不像,最终变成一堆精致的无用装饰。1.2 图不是画的,是设计的:设计与绘画的区别我后来想明白一个道理——技术图不是绘画,是工程图纸。绘画追求表达,工程图纸追求精确。一张合格的技术示意图,应该让读者在十秒内回答三个问题:这张图讲的是什么范围的事?里面有哪些关键对象?它们之间是什么关系?达到这个标准靠的不是天赋,而是一套可重复的决策流程。Diagram设计本质上是在做信息压缩:把复杂的系统、流程、数据结构,降维成一张读者能快速扫描的二维平面图。压缩得好不好,取决于画图的人有没有想清楚哪些信息保留、哪些信息丢弃、哪些信息放在第一层、哪些放第二层。刚开始做规范的时候,我给自己定了一个原则:画图之前不许打开画图工具。先写清楚这张图要回答什么问题,再动手。这个习惯沿用到现在,帮我避掉了大量返工。2. 动手前先定三件事:读者、信息层级、图的内容边界很多图是在'手痒'状态下画出来的。想到一个模块就加一个框,觉得流程缺一环就补一条线,最终图越滚越大,效果越来越差。要改变这种局面,必须在动笔之前做完三个决策。2.1 第一件事:确认读者会拿图做什么图的读者决定了图的画法,这个道理很多人忽略。给架构评审委员会看的图,突出的是模块边界和依赖方向;给新员工看的图,突出的是核心流程和数据走向;给运维同学看的图,突出的是服务实例和部署关系。用途不同,图的构图完全不同。我在某跨平台系统的文档整理中做过一次对比:同一套系统,我先后画过四个版本的架构图,分别服务技术选型评审、模块开发分工、线上故障排查、新人入职培训。四个版本画出来的节点选择、连线口径、标注粒度几乎没有重叠。这说明图不是系统的照片,而是系统的'切片'——针对某个视角的信息抽取。判断读者需求有个土办法:问自己一句,'如果对方只能看图、不能问我,他最怕漏掉什么信息?'这个问题的答案,就是图的中心主题。2.2 第二件事:拆信息层级把要表达的内容拆成三层:主层、支撑层、跳转层。主层是这张图必须表达的核心关系,支撑层是帮助理解主层的上下文信息,跳转层是细节,但不放进当前图,而是通过图号或外部链接引导读者去别处查。举个例子,我在画支付链路时序图时,主层就是发起支付、风控校验、锁定账户、返回结果这条主线。支撑层是超时时间、重试次数这几个参数标注。跳转层是每个环节内部的异常分支——那些内容我绝不画进同一张图,而是单独拆成异常流程子图。这个分层的逻辑和代码重构很像:一个函数承担太多职责就拆函数,一张图画了太多主题就拆图。2.3 第三件事:决定什么是"不画"这可能是整个diagram-design里最重要的一步。我见过太多人栽在看什么都重要、什么都舍不得丢。画图必须做取舍,而且要主动舍弃那些'有关系但不关键'的边边角角。我常用的判断标准是:如果删掉某个节点,阅读理解会不会受影响?如果删掉不影响,就删掉;如果读者需要点击或者翻页才能搞懂,那不是主层信息,应该放到跳转层。删完之后再看一眼,通常还能再删掉一批。有个可量化的参考值:一张技术示意图的节点数量建议控制在5到12个之间。少于5个可能不需要图,多于12个就应该考虑拆分。这不是硬性规定,但当图超过这个规模时,我基本都会重新考虑信息分层。3. 代码化绘图:为什么我建议把图当作代码来管理Diagram设计里最值得投入的一件事,就是把图变成代码。过去我用拖拽工具画图,画完导出图片往文档里一贴,以为大功告成。直到某次架构调整要改二十多张图,我才发现每张图都要手动点开、移动框体、调整线条,改完一张忘一张,还要反复确认有没有漏改。3.1 从手绘/拖拽工具转到代码化方案的理由代码化绘图的核心收益是三点:可版本管理、可自动化渲染、可统一风格。图源文件可以和代码一起提交到仓库,每次改动都有diff记录,评审的时候可以精确指出'第三张图第5个节点改了名字',而不是发一张图片让团队猜改了哪里。风格统一在团队协作中尤其重要。手绘和拖拽工具里,每个人的审美都会带进来——有人喜欢圆角框,有人喜欢直角框,有人阴影开满,有人容不下一点多余线条。代码化之后,样式集中定义,渲染结果完全一致,个人偏好被约束在可控范围内。持续集成也是代码化带来的额外好处。文档流水线里加一步渲染任务,源文件变了,渲染产物自动更新,图永远跟着文档走,从源头上消灭了版本漂移。3.2 主流代码化方案对比:怎么选才不后悔我用过不少方案,这里列几个有代表性的,按适用场景说透一点。文本图方案,比如用字符拼图,适合放在源码注释、命令行帮助文档里,零依赖、任何地方都能看,缺点是表达能力有限,稍微复杂一点就难以维护。图描述语言方案,这类工具发展得比较成熟,语法简单,上手快,颜色和连线的可编程空间足够。我现在的主力方案就是这一种——不是因为它功能最全,而是因为它在简单和强大之间平衡得最好,社区生态和导出格式都比较稳。类描述语言方案,对严谨建模友好,适合表达类关系、状态机这类强结构内容。但它的语法有学习成本,日常画个流程图写它有点重,灵活性也不如同类通用方案。手绘风格方案,适合画产品原型、头脑风暴、非正式讨论,写起来舒服,视觉上亲和力强,但不适合当作正式技术文档的统一标准,因为画出来的样式受手写轨迹影响,换个环境渲染结果就可能不一样。我之前在某图像处理Demo的文档里做过一次完整对比,最终留在日常工具箱里的是:正式文档用类描述语言方案的变体,快速草图用手绘风格方案,源码内的说明用文本图方案。没有哪个方案是万能的,关键是按场景分工。3.3 一个最小可用的工程化目录结构如果团队想从一开始就按代码化的方式管理图,下面这个目录结构可以直接照搬,它是我在多个项目里验证过的布局。docs/ diagrams/ src/ # 图源文件 system-overview.mmd payment-sequence.mmd retry-states.mmd out/ # 渲染产物 system-overview.svg payment-sequence.svg retry-states.svg scripts/ # 批处理脚本 render-all.sh README.md源文件和渲染产物分开存放,出图脚本集中放,这样有几层好处。第一,渲染产物可以随时重新生成,不需要手动维护;第二,不同图之间的公共样式可以抽成共享文件,改一次,全部生效。第三,脚本可以批量渲染,新同事入职之后不需要了解画图工具内部逻辑。我在实际项目中会把全量渲染脚本做成一个简单的Shell脚本,遍历src目录下的源文件,逐个调用渲染命令,输出到out目录。持续集成只需要在文档发布前执行这个脚本。4. 把图做"干净"的六个细节:布局、对齐、色彩、字体、图例、边界工具选好之后,真正拉开差距的是视觉细节。下面这六个方面是我在整理diagram-design规范时反复打磨出来的,也是最容易被忽略的地方。4.1 布局与对齐:让信息流的方向可预测人的视线习惯从左上到右下,所以画图要顺着这个方向安排信息流。主流程从左到右,或者从上到下,不要做蛇形曲线。分支流程放在主流程的同一侧,不要一会儿左边一会儿右边。对齐的选择要显式且一致。能对齐的边界尽量对齐,能等距的间距尽量等距。我见过很多图画得'还行但总感觉乱',问题就出在间距不一致。框体之间的距离忽大忽小,整张图的节奏感就没了。初始排版可以用工具自动布局,但最后一定要手工检查一遍关键节点,自动布局常常会在语义相邻的节点之间留下多余空白。4.2 色彩数量控制与语义化配色颜色是语义工具,不是装饰。我的规范是单张图最多三种主色,允许一到两种强调色。出现第四种主色之前,先怀疑是不是图塞了太多主题。常用的语义约定如下:颜色语义使用场景中性灰/深灰常规节点服务、模块、步骤蓝色核心主链路主流程节点、关键路径绿色正常/成功成功分支、健康状态红色异常/失败错误分支、告警路径橙色降级/警告限流、降级、重试路径色盲安全性也要考虑,建议不要只靠颜色区分关键信息,可以搭配线型、图标、文字标注。我在规范里要求任何颜色语义都必须在图例中标明,不标颜色的图不允许对外发布。4.3 字体与可读性:正文优先,装饰靠边字体选择上,标题、正文、注释的层级要拉开。框内节点名常用中号正文,分组标签用小号,重要说明用加粗或高亮。统一的字体栈要维护在公共样式文件里,不要每张图都手动改。强调一点:在允许的格式,如SVG和PNG上,优先选择无衬线字体,中文环境优先系统自带的高可读性字体,不要为了'好看'选择非主流字体库。嵌入式环境里如果找不到可用字体,渲染出来的字形会随机替换,那才是真正的灾难。4.4 图例、编号与跨图引用:让图可被索引规范化之后,每张图都应该有一个稳定编号,比如'图2-1:系统总体架构'。正文引用时用编号而不是'下图',这样文档排版变化、图片顺序调整之后,引用关系不会断。跨图引用是很多人忽视的细节。如果主图里某个模块在另一张图里有详细展开,就在这个模块旁边标注'详见子图2-3'。这样读者就知道细节不在当前图,不用盯着主图发呆。图例的位置固定在图的右下角或左下角,内容包含所有用到的线型、颜色、符号。哪怕只有三种颜色,也要放图例。我见过太多图没有图例,靠读者猜,猜错的代价比少画一条线大得多。5. 一套可以直接抄的diagram-design工作流方法讲了一堆,落到日常执行,需要一套能坚持的工作流。下面是我目前在用的,整体思路是'先写文字,再画图'。5.1 先写图说明,再画图这个看起来反直觉,但非常管用。每画一张图之前,我要求自己在图的上方或注释里先写三行话:这张图的目的是什么,主要读者是谁,图里包含哪些关键对象和关系。写完这三行再画,图的边界自动就清楚了。举个例子,我在画某跨平台系统的部署拓扑图之前,先写了这样一段:目的:展示三个环境下的实例分布和网络接入方式。 读者:运维同事、排查线上问题的开发。 关键对象:接入层、应用实例、存储集群、消息队列。写完之后,我发现自己根本不需要画DNS解析细节,也不需要画客户端内部逻辑。少画了一半的内容,图反而清楚了许多。5.2 每次改图的检查清单我把改图之前要做的事整理成了一份检查清单,现在团队里用着挺好。这次改动的动机是什么?如果是需求变更,写明对应的需求编号。图里的节点和连线是否与当前代码一致?不一致的地方就是这次改动的重点。新增节点是否超过了单张图的信息量上限?超了就拆图。颜色、线型是否沿用了公共样式定义?不要新造颜色。图例是否同步更新?新增的语义是否已经写进图例?跨图引用编号有没有变化?变化了要同步改正文引用。这份清单不用打印出来挂在墙上,在代码评审里加上一条'图变更需附检查记录'就能贯彻。5.3 团队协作中的命名规范源文件的命名要具备自解释性,比如用户登录流程就写login-flow,不要叫final_v2。一个项目里所有图源文件按主题前缀分组,比如架构图用arch-开头,时序图用seq-开头,状态图用state-开头。渲染产物和源文件共用同名前缀,后缀区分格式。目录划分建议参考前面提到的工程化布局,视图层和逻辑层分开。命名规范在团队里的作用是降低新人上手成本,让每个同学打开仓库就知道什么文件放哪里。6. 我在实际项目中踩过的坑:从混乱到规范的一次重构理论说多了,聊点真实场面。有一回我接手一个大型项目的文档整理,那里的diagram-design目录让我印象极深——不是因为它规范,而是因为它乱得具有代表性。6.1 重构前的状态:六套图、五种风格、零注释那个目录里一共有几十张图,分属六套子文档,画风五花八门。有的是拖拽工具导出的彩色方块,有的是文本图,有的是手绘风格的草图,唯一统一的是没有一张图带图例。架构改过三轮,旧图没有归档,新图直接覆盖,结果就是文档里同时存在已经下线了的模块和还没上线的占位符。我把所有图归拢之后做了件事:按我前面说的流程,给每张图补上'目的、读者、关键对象'三行注释,再决定这张图是保留、合并、还是直接废弃。最终真正留下的图不到原来的三分之一,但每一张都能说清楚服务谁。6.2 重构中遇到的问题:工具绑定、中文渲染、复杂图拆分重构过程中遇到三个典型问题,值得单独说。工具绑定很麻烦,旧图用的是闭源格式,编辑必须装对应客户端,渲染结果换个环境就变形。我最终把所有需要保留的旧图全部重画成代码化源文件,这也顺便解决了后续协作的准入问题。中文渲染踩过不少坑。默认字体在某些环境下对中文支持不佳,出现乱码或者字形错位,解决方式是显式在公共样式里指定中文字体栈。另一个细节是中文文本在框内换行时,要把分词逻辑处理对,不然一行长文本会把整个节点撑变形。复杂图拆分是一次认知升级。原来有一张系统全景图,包含几十个服务和数据流,怎么摆都乱。按模块拆成主图和四张子图之后,主图只保留各模块之间的依赖,子图专门负责模块内部细节,阅读体验立刻就不一样了。跨图引用的编号也在这个阶段补全,之后所有正文都改用'图编号'引用。6.3 重构后的效果与经验沉淀重构完成后,新同事理解系统架构的时间从之前的两三天缩短到半天以内,排查流程图指向模糊的问题也基本绝迹了。更重要的是,后续架构演进时改图不再是一个心理负担,源文件改一行、渲染全出,所有图自动保持同步。从那次重构之后,我养成了一个习惯:每画一张图,都把它当成要交给下一个维护者的代码来写。写注释、起好名字、保持边界清晰、控制复杂度、统一风格、纳入版本管理,这些标准搬到图上也完全成立。如果你现在手头就有个乱糟糟的diagram-design目录,不妨从今天开始按这个方法重理一遍。先别急着重画,先回答三件事:图给谁看、表达什么关系、哪些细节不画。把这三件事和老图对齐,你会发现大部分图根本不需要保留,留下来的只需要很小的改动就能焕然一新。之后每次新图都照这个流程走,文档的图表质量会稳定在一个不会让你尴尬的水准线上。