返回博客

用 HTML + SVG 手写架构图:告别 Mermaid 的 38 种排版实战

2026/9/73 分钟阅读
用 HTML + SVG 手写架构图:告别 Mermaid 的 38 种排版实战

用 HTML + SVG 手写架构图:告别 Mermaid 的 38 种排版实战

Mermaid 那种依赖库自动渲染的方式,在画复杂的业务架构图时常常让我抓狂——布局错乱、样式难以微调。我最终放弃了它,转而使用纯 HTML + SVG 的组合来绘制所有图表。通过预定义的 38 种原子化组件,我们完全可以实现对架构图的像素级控制,不仅兼容性好,而且能无缝集成到任何 React 或 Vue 项目中。

SVG 架构组件的核心逻辑

在开始写代码之前,我得先理清一个概念:架构图本质上就是一组“图元”的连接。我用一个 SVG 画布配合 React 组件来管理这些节点。核心在于,不要把整个流程图写在一个巨大的 <svg> 里,而是把每个节点(如服务、数据库、API)封装成独立的 SVG 组件。这样我就能复用代码,同时保持架构的清晰。比如,我定义了一个通用的 <BaseNode> 组件,它负责处理节点的描边、填充和文字居中,其他复杂节点都是它的子集。

用 HTML + SVG 手写架构图:告别 Mermaid 的 38 种排版实战 - 插图 1

38 种基础图元的覆盖策略

很多人觉得要手写 38 种节点很麻烦,其实大部分是重复劳动。我把它们分成了几类:基础形状(矩形、圆角矩形、圆形)、数据流节点(数据库、缓存、对象存储)、计算节点(服务器、容器、微服务)以及网关类(负载均衡、API 网关)。我一般不追求 38 种全部完美,而是先覆盖最常用的 15 种,剩下的通过参数组合实现。例如,一个圆柱体数据库,我可以通过变换 SVG 的 ellipsepath 组合快速搞定,而不需要重新写一套算法。

从零搭建一个 SVG 节点组件

下面这段代码是我在实际项目中用的基础节点模板,你可以直接抄过去改。它利用了 SVG 的 <g> 标签进行层级管理,并通过 CSS 变量来控制主题颜色,这样我修改整体配色时只需要动一处配置。

const ArchitectureNode = ({ x, y, width, height, label, type }) => {
  const isDatabase = type === 'db';
  return (
    <g transform={`translate(${x}, ${y})`}>
      <rect 
        width={width} 
        height={height} 
        rx={isDatabase ? 0 : 4} 
        fill="#f0f4f8" 
        stroke="#2c3e50" 
      />
      {isDatabase && (
        <ellipse cx={width/2} cy={height-5} rx={width/2 - 5} ry={10} fill="#f0f4f8" stroke="#2c3e50" />
      )}
      <text 
        x={width / 2} 
        y={height / 2} 
        textAnchor="middle" 
        dominantBaseline="middle"
        fontSize="14" 
        fill="#333"
      >
        {label}
      </text>
    </g>
  );
};

连线与布局的避坑指南

SVG 最大的难点从来不是画框,而是画线。我踩过最大的坑就是手动计算连线路径,最后发现用 SVG 的 <path> 配合贝塞尔曲线(Cubic Bezier)才能做出好看的直角转弯。我的做法是,不依赖任何自动布局库,而是手动定义节点间的坐标映射。对于 38 种图元的连线,我约定了统一的锚点规则:矩形节点只在上下左右四个方向的中心点出连线,这样我在写 <path d="..." /> 时就可以用简单的直线或折线算法,避免了曲线重叠的尴尬。

为什么我不再推荐 Mermaid

老实说,Mermaid 对于快速原型开发很有用,但当我需要交付一份精美的技术文档时,它那种“黑盒”渲染让我非常不舒服。HTML + SVG 的方案虽然前期配置稍微多一点,但一旦我建立了那 38 种图元的组件库,后续画图速度反而更快。而且,SVG 本身是矢量图,不管我怎么放大缩小,线条永远清晰,这在打印 PDF 架构白皮书时尤为重要。如果你也受够了调整 Mermaid 配置里的每一个间距,不妨试试这种更底层的实现方式。

下一步:如何扩展你的图元库

如果你想深入,可以尝试将 SVG 节点导出为 PNG 或 PDF,方便插入到 Word 文档中。同时,建议引入 TypeScript 对节点属性进行严格定义,这能大幅减少你画错连线时的调试时间。

原文出处

本文首发于 用 HTML + SVG 手写架构图:告别 Mermaid 的 38 种排版实战https://lyxq.com.cn/zh/blog/html-svg-diagram-architecture-guide

转载或引用请注明出处,商业使用请联系作者获得授权。