尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

告别粗糙架构图:纯HTML+SVG实现出版级图解方案

告别粗糙架构图:纯HTML+SVG实现出版级图解方案 如果你画过架构图大概率经历过这种尴尬方案讲得头头是道图一放出来评审现场直接就尬住了。框线对不齐、字体发虚、配色像调色盘打翻逻辑再严谨也很难让人相信你“考虑周全”。我从前端转到基建、又在一线带过几年团队对这种“图不给力”的痛太有体会了。最近在GitHub上刷到一个叫 diagram-design 的源码项目一句话就把我勾住了告别粗糙架构图纯HTMLSVG实现设计师也认可的出版级图解。这项目不是又一个拖拽画图工具而是一套把SVG绘图这件事做到工程化、规范化的完善方案。我把它拉下来仔细读了一遍跑了demo还拿团队真实的系统架构图试了水确实能打。接下来的篇幅我会从设计思路、源码机制、实操落地和避坑经验四个维度拆一拆这个项目并把其中最值得迁移的部分单独抽出来讲透。不管你是前端、后端还是经常要画方案图的普通开发这篇文章都能让你少走不少弯路。1. diagram-design到底是什么、解决什么问题1.1 被架构图丑哭的评审现场先说个真实场景。之前我带一个中台项目技术方案写了三周核心链路设计得自认为很完善。到了评审会打开图的那一瞬间我就看到几个业务方在偷偷皱眉——倒不是方案有问题是图真的太糙了。流程框大小不一箭头歪歪扭扭配色是draw.io默认的“蜜汁撞色”字体在小屏幕上糊成一团。结果前十分钟全在解释“这个框代表什么”“这条线为什么是虚线”真正该讨论的架构决策反而没时间聊。这种痛我估计很多人都经历过。工具本身没有错draw.io、Visio、ProcessOn都能画图问题在于默认美术水平和我们大脑里“专业”的期望差得太远。而专业设计师做的图看似只是“好看”其实是字体、间距、对齐、配色、留白这些细节在统一发力。diagram-design这个项目最打动我的点就是它把这些“审美细节”全部变成了可复用的代码参数。它不逼你手动调而是从底层帮你把美术规范定死让普通人也能画出一眼看去就很专业的图。1.2 项目定位不是画布工具是图解渲染方案如果你以为diagram-design是又一个在线画图工具那就理解偏了。它本质上是一套基于HTML和SVG的图解渲染方案你通过结构化的数据或标签去描述“图里面有什么”它负责把它画成一张高完成度的矢量图。在这个方案里有几个核心概念画布、节点、连线、主题。画布定义坐标系和尺寸节点是图里的“框图”和“文字块”连线表达节点之间的关系主题则统一控制颜色、圆角、阴影、字体等视觉参数。这种设计带来的最大优势是图不再是一张不可编辑的位图而是纯文本描述出来的结构化产物。只要描述图的数据没有变谁来渲染、用什么主题渲染出来的都是同一张规范图。这解决了团队协作时“每个人画的图风格都不一样”的世纪难题。对开发团队来说它还可以直接嵌入网页、注入自动化文档流水线甚至做成动态可视化图表。这是传统画图工具做不到的。1.3 快速跑起来从拉取源码到渲染第一张图我实际跑了一遍流程很顺。先把仓库克隆到本地然后在项目根目录起一个静态服务就行。git clone diagram-design仓库地址 cd diagram-design python3 -m http.server 8000浏览器打开http://localhost:8000就能看到项目自带的demo页面。页面里有现成的架构图、流程图、拓扑图示例你可以直接在浏览器里查看源码找到SVG对应的节点定义。比如demo里一个最简单的节点长这样svg viewBox0 0 1200 800 xmlnshttp://www.w3.org/2000/svg rect x100 y100 width200 height80 rx8 fill#fff stroke#4F6AF6 stroke-width1.5/ text x200 y138 text-anchormiddle font-size14 fill#333核心服务/text /svg这段代码画了一个宽200、高80的圆角矩形里面居中写了一行字。看起来简单但它已经具备了出版级图解的雏形圆角克制、描边细致、文字对齐精确。后面我会把如何从这个小节点扩展到完整架构图一步步讲清楚。2. 为什么选择纯HTMLSVG这条路2.1 先聊聊其他方案的坑很多人画架构图的第一反应是打开画图工具或者用Canvas类库。这两种思路都有天花板。传统画图工具最大的问题是“不可编程”图画完就定了后期改动、批量生成、版本对比都很难做。Canvas方案虽然可以编程但它是位图渲染模型画出来的东西是像素文字不能选中、无法检索放大到一定程度还会发虚。我在项目里也踩过Canvas的坑。早前做监控大屏用Canvas画拓扑图40个节点还流畅到200个节点加动画后帧率掉得厉害。而且业务方反馈“图里的字不能复制”没有很好的办法只能改方案。后来换SVG文字天然就是文本节点鼠标一拖就能选中这个体验上的差距是位图方案弥补不了的。还有一类方案是直接用HTMLCSS拼布局用div模拟图块、用border画线。这种做法做做简单示意图还行一旦涉及复杂连接线、曲线、锚点CSS就会非常吃力几乎没有可行性。2.2 SVG的本质优势图形本身就是DOM节点SVG最重要的特点是所有图形元素都是DOM节点。这意味着你可以用CSS控制它的样式用JavaScript操作它的结构用浏览器开发者工具直接审查它的属性。调试流程和调试普通网页完全一致对前端来说几乎没有学习门槛。另一个很实际的优势是矢量缩放。无论图在手机小屏还是4K大屏上展示SVG都能保持边缘锐利。出版场景下SVG可以直接转成PDF或者高分辨率PNG打印300DPI依然清晰。这一点普通位图做不到Canvas也做不到。SVG还天然支持一些前端生态的附属能力动画、事件绑定、无障碍标签、ARIA标注。比如你可以给一个节点加上aria-label让读屏软件读出“支付服务”这个名字这对团队内部文档的可访问性是很大的加分项。2.3 工程化与协作价值是你没想到的大多数人选画图方案时只会考虑“能不能画出来”很少考虑“这个图能不能进代码仓库、能不能被评审”。diagram-design最聪明的地方就是把图变成了纯文本的SVG代码。代码就意味着可以进Git可以diff。团队里任何一个人改了架构图提交记录里都能看清改了什么——是加了一个服务框还是换了一条连线的颜色。这个特性在文档评审、架构治理场景下价值极高。以前看图只能靠肉眼对比两版图片现在可以直接看代码变更精度完全不一样。主题变量也让“设计师认可”这件事变得可实现。设计师定好一套色彩、圆角、阴影规范开发者把规范落成CSS变量或者主题配置文件所有人画出来的图都是同一套视觉语言。不再出现“这个人偏好蓝色、那个人喜欢绿色”的混乱局面。3. 源码级拆解diagram-design的核心实现机制3.1 画布坐标系与viewBox设计看源码首先会注意到整个画布根节点上的viewBox属性。viewBox定义了SVG内部的虚拟坐标系比如viewBox0 0 1200 800表示图内部空间是1200像素宽、800像素高。浏览器会根据容器大小自动缩放这个坐标系所以图在任何屏幕上都不会拉伸变形。这里值得学习的一个设计是diagram-design在画图时并不会让使用者直接面向屏幕像素操作而是面向“逻辑坐标”。比如你想在画布中间放一个节点只需要根据画布的逻辑尺寸计算坐标不用关心最终渲染设备的分辨率。这样做的好处是把“布局”和“呈现”解耦了图在什么设备上看效果都保持一致。我在复刻这个设计时踩过一个坑忘记设置viewBox直接用了width和height。结果在小屏设备上SVG溢出大屏上边缘又留白太多。后来把viewBox固定为设计稿尺寸再把width设成100%问题立刻解决。3.2 节点与容器圆角、阴影、边框背后的“审美参数”diagram-design里节点的视觉呈现非常讲究。以矩形节点为例核心参数就几个rx圆角半径、fill填充色、stroke描边色、stroke-width描边宽度。但不同的组合方式出来的气质完全不一样。源码里节点默认采用白色填充、浅灰描边、中等圆角的组合这个组合最接近现代设计规范中的卡片风格。圆角半径一般取8到12像素太小显得生硬太大又丧失严肃感。阴影则是通过SVG的filter实现的默认模糊半径不会太大阴影颜色是半透明的黑色而不是纯黑这样阴影会显得柔和不“脏”。我并排对比过rx4和rx12的节点效果结论是如果是技术架构图8像素是比较安全的中间值如果是面向管理层的汇报图可以加大到12视觉上更亲和。源码里把这些参数做成主题变量后切换风格只是改两个变量的事完全不需要重画。3.3 连线的三种画法与布局算法图的高级感一半取决于节点另一半取决于连线。diagram-design源码里将连线分成三种形态直线连接、折线连接、曲线连接。直线适合表达强关联折线适合表达流程走向曲线用来表达复杂的网状关系时最优雅。曲线连线的实现并不神秘核心就是贝塞尔曲线路径。举个例子如果要从起始点(x1, y1)连接到结束点(x2, y2)一条横向弧线可以写成path dM x1 y1 C x1offset y1, x2-offset y2, x2 y2 stroke#888 fillnone/offset控制了曲线在起点和终点附近的弯曲程度。源码中会根据两个节点的相对位置和连线方向来动态计算offset如果节点是左右排列offset用水平方向如果是上下排列offset用垂直方向。这个逻辑看似简单却是整个图看起来“顺不顺眼”的关键。更值得借鉴的是连接点的锚定规则。diagram-design没有让连线从节点矩形的正中心穿过而是让线从矩形边缘的“锚点”出发。这样避免线和文字重叠整个图会显得非常干净。我第一次画连线时没有锚点概念线直接横穿文字效果惨不忍睹后来照着源码改成边缘锚点图面瞬间清爽很多。3.4 出版级排版系统从网格到字体的完整控制这部分我非常推荐所有画图的人认真看。diagram-design之所以能接近“出版级”排版细节功不可没。首先是网格对齐。源码里所有节点坐标、尺寸都遵循一个基本网格单位我看到的demo中是8像素部分场景会用4像素微调。只要所有元素都落在网格线上随便怎么看画面都是整齐的。很多草率的图画出来歪歪扭扭本质就是元素坐标没有落在同一个网格系统上。其次是字体栈和字号梯度。源码里中文字体栈大概是类似PingFang SC, Microsoft YaHei, sans-serif的组合西文部分是常见的系统无衬线字体。字号梯度上默认层级是主标题18到20、节点标题14到16、说明文字12。字重上标题用600正文用400这种克制的对比让信息主次分明。最后是行高和留白。SVG里的text不会自动换行diagram-design在源码里提供了文本换行的处理逻辑把长文本按最大宽度拆分成多行行高默认是字号乘1.5。行与行之间、节点与节点之间的留白也都有最小阈值保证画面不压抑、不拥挤。这些参数单独看都不起眼全部叠加起来就成了“专业感”的来源。4. 实操复现手写一张出版级系统架构图4.1 搭建HTML骨架与SVG画布我们不看复杂的项目代码先自己动手复现一张简单的系统架构图。新建一个HTML文件加入基础骨架和SVG画布。画布逻辑尺寸设为1200宽、800高这样有足够空间表达至少3层架构。!DOCTYPE html html langzh-CN head meta charsetUTF-8 titlediagram-design实践出版级架构图/title style body { background: #f5f6f8; display: flex; justify-content: center; padding: 40px 0; } .diagram { width: 1200px; background: #fff; border-radius: 12px; padding: 24px; box-shadow: 0 4px 20px rgba(0,0,0,0.06); } svg { width: 100%; height: auto; display: block; } /style /head body div classdiagram svg viewBox0 0 1200 800 xmlnshttp://www.w3.org/2000/svg !-- 图内容写在这里 -- /svg /div /body /html画布外面套一个白色卡片容器这是很多设计站点常用的展示手法可以让图在预览时就显得高级。svg的width: 100%配合viewBox确保缩放在任何宽度下不变形。4.2 用CSS变量统一主题diagram-design源码里把视觉参数抽成了主题变量这个思路在纯HTMLSVG里同样适用。我们可以在style里定义一组CSS变量然后在SVG元素上用var()引用。:root { --primary: #4F6AF6; --primary-light: #EEF2FF; --text-main: #1F2329; --text-sub: #5F6B7A; --border: #D0D7E2; --bg-node: #FFFFFF; --radius: 8px; --shadow-color: rgba(31, 35, 41, 0.10); --line-color: #A3ADBB; --line-width: 1.5; --font-main: PingFang SC, Microsoft YaHei, -apple-system, sans-serif; }主题变量带来一个立竿见影的好处后续所有节点都引用这些变量如果要换一套配色只需要改变量定义。比如公司要出深色版架构图把--bg-node和--text-main改掉就全部同步了。这也是diagram-design源码里“主题”模块的核心思想。4.3 写节点、连线和分组区域接下来我给一张典型的三层架构图画几个节点。前端网关层、业务服务层、数据存储层各画一个区块再加两条连线表示调用关系。先看单个节点的写法。一个标准的服务节点由矩形背景、左侧图标区、文字标题和副标题组成。为了保持代码简洁我用g把几个图形元素打包成一个逻辑单元g transformtranslate(80, 80) rect width240 height96 rx8 fillvar(--bg-node) strokevar(--border) stroke-width1.5/ rect x0 y0 width6 height96 rx3 fillvar(--primary)/ text x28 y42 font-size16 font-weight600 fillvar(--text-main) font-familyvar(--font-main)API网关/text text x28 y66 font-size12 fillvar(--text-sub) font-familyvar(--font-main)统一流量入口鉴权与路由/text /g左边竖着的一条彩色矩形是diagram-design里很常见的一种设计用一个小的强调色块给节点增加视觉重心避免节点看起来像“光秃秃的盒子”。这种做法简单但专业感提升非常明显。再画另外两个服务结构类似只是坐标不同。然后画一条从API网关指向业务服务的曲线连线用贝塞尔曲线让路径平滑path dM 320 128 C 420 128, 420 128, 520 128 strokevar(--line-color) stroke-width1.5 fillnone/ circle cx520 cy128 r4 fillvar(--primary)/路径在水平方向平滑过渡终点加一个小圆点作为箭头端口的视觉提示。这里如果你想要真正的箭头可以在末尾加一个polygon三角形或者使用SVG的marker-end属性。diagram-design源码里两种方式都有简单场景用marker更省事追求精细控制就自己画箭头。4.4 导出与发布让矢量图落到报告和网页里图画完之后下一步是怎么用。由于整个架构图就是SVG嵌入网页再简单不过——直接把SVG代码粘进去即可。它和网页完美融合文字还能被搜索引擎收录、被用户选中复制。如果要放到Word文档或者PPT里我一般会先把SVG转成PNG。方法有三种第一种是用浏览器打开HTML文件右键SVG区域选择“图片另存为”得到的就是矢量兼容格式第二种是用开发工具截图将浏览器窗口设成2倍缩放device scale factor2再截得到的PNG更清晰第三种是写一个批量转换脚本用sharp或puppeteer在Node环境里把SVG渲染成任意分辨率的PNG。有一点必须提醒如果你的报告要打印或者有高分辨率LED屏幕展示需求尽量用SVG源文件或者PDF格式不要用PNG。PNG放大到原图两倍以上边缘发虚的问题就出来了这违背了“出版级”的初衷。5. 我踩过的坑常见问题与排查技巧实录5.1 文字发虚、边缘模糊的问题第一次用SVG画架构图时我把图嵌进网页结果在部分Windows电脑上文字发虚和macOS上的效果差一大截。排查下来发现了两个原因。第一是字体渲染差异。Windows上如果没有安装中文字体栈里的字体会回退到一种默认字体小字号下渲染不够锐利。解决方法是完善字体栈把“Microsoft YaHei”放在中文字体前面必要时嵌入Web字体。第二是SVG被CSS做得过小然后被浏览器强行放大这时文字边缘会模糊。解决方法是确保SVG的实际渲染尺寸不低于设计尺寸或者用viewBox配合响应式容器时留出足够安全边距。5.2 viewBox 和实际长宽比不一致导致变形这个坑特别隐蔽。我在给一个客户做架构图时viewBox设置成0 0 1200 900但是外层容器的CSS宽度是1200、高度却是800结果整个图被垂直压扁。原因在于SVG默认会拉伸去适配容器宽高比。解决方案有三个一是让容器宽高比和viewBox一致二是给svg设置preserveAspectRatioxMidYMid meet这样它会保持纵横比并在容器里居中多出的区域留白三是用preserveAspectRatioxMidYMid slice让图铺满容器但会裁剪两侧。做架构图推荐第一种或第二种视觉上更可控。5.3 节点数量增多后页面明显卡顿SVG的DOM节点是“有代价的”一个大型架构图动辄几百个节点和连线每个节点还有阴影filter页面帧率会明显下降。我测试过一次包含400个节点的图在普通笔记本上滚动时已经能感到迟滞。优化策略一般有几个方向合并路径和图形使用CSS的will-change减少filter的使用因为阴影滤镜计算开销很大能用伪影层模拟就不用filter将大图拆成多个SVG按需渲染如果是动态数据对频繁更新的元素分组避免全量diff。diagram-design源码里对静态图做了一版优化把所有静态节点合并成单个g配合静态渲染缓存实际性能提升很可观。5.4 常见问题速查表问题根因快速处理方案文字模糊字体缺失或SVG被缩放完善字体栈保持渲染尺寸接近设计尺寸图被拉伸变形viewBox与容器比例不一致设置preserveAspectRatio或统一宽高比节点阴影不显示/渲染异常filter在部分浏览器兼容性差异使用基础filter避免过多复杂滤镜节点数量多页面卡顿DOM节点多、filter开销大合并静态分组减少阴影filter分批渲染高DPI导出模糊直接截图分辨率不够用2x缩放截图或用脚本渲染PNGSVG在不同浏览器颜色有差异颜色空间与渲染引擎差异确认图片嵌入方式必要时用统一的sRGB这张表是我在实际使用项目过程中总结出来的也结合了团队成员反馈的真实案例。每一条背后都对应过一个具体的线上事故按时排查能省下不少时间。6. 评测总结与一点扩展思路如果你只把这个项目当成“画图工具”它可能不如Polka、Excalidraw这些来得快。但如果你需要一套稳定、可编程、能进代码评审、能统一团队视觉规范的图解方案它几乎是目前最值得参考的开源答案。设计上的克制感、代码里的工程化细节、对“审美参数”的封装让它不只是好看而已。就我个人经验来说这类基于SVG的方案特别适合三个场景一是技术架构文档的自动化生成二是团队内部的知识库配图规范化三是产品汇报中需要高完成度可视化的场景。你可以把它当成一个基础规范再往上叠加自动布局算法、数据驱动渲染、实时协作能力想象空间很大。还有一个可以立刻上手的思路把你目前最常用的架构图重新用HTMLSVG画一遍。不需要一上来就追求复杂先把几个核心节点和连线的主题统一好用CSS变量把配色和字体定下来再逐步添加细节。画完对比一下你会明显感觉到“专业感”这件事其实是用规范堆出来的。
返回列表