跳到主内容
快讯直播
AI智模界
教程

用 Reladraw 手写架构图:定位、布局与导出

Reladraw 是一类"位置由你说了算"的图表工具:你用一段文本描述节点放在哪个坐标、连到谁、长什么样,它负责渲染。和那些"拖一下、对齐一下、第二天打开发现全乱了"的画图软件相比,它的好处是图变成了可以进 Git、可以 diff、可以复制的文本。

这篇教程带你从零写出一张四层架构图(客户端 → 网关 → 服务 → 数据库),位置全部由坐标控制,最后导出成可以贴进文档的 SVG。文中的字段名、子命令名属于通用写法,不同版本的 Reladraw 可能略有差异,具体语法以官方文档当前版本为准,方法本身是通用的。

这篇能做出什么

完成后你会得到:

1. 一份纯文本的图定义文件,大约 40 行,写清楚每个节点放在画布的第几个格子;

2. 一条命令导出 SVG / PNG,改一个数字图就变,不需要重新拖拽;

3. 一套"网格坐标法",让你不用试错也能算出位置;

4. 一份踩坑清单,包含坐标原点、容器相对坐标、中文文字溢出等高频问题。

先看最终效果对应的结构:左边一列是入口,中间两列是服务,右边一列是存储,横向三条连线。位置全部由 x、y 两个数字决定。

前置条件清单

  • Reladraw 的运行环境(桌面客户端、网页版或命令行工具,看你装的是哪个,以官方文档为准);
  • 任意文本编辑器,能看 YAML 缩进就行;
  • 一张纸上先列好节点清单:有哪些模块、谁连谁、分成几组;
  • 如果走命令行导出路线,需要本机有对应的运行时环境(比如 Node.js 一类的运行时),具体依赖以官方文档为准;
  • 一颗不着急的心:第一次算坐标会慢,第二次开始就是复制粘贴。

第 1 步:先定坐标系,别急着写字

绝对定位类工具的坐标系几乎都是这样的:原点在左上角,x 向右增大,y 向下增大,单位是像素。这一点必须先确认,因为很多人的直觉是数学坐标系(y 向上),画出来整个图会上下颠倒。

先决定三件事:

  • 画布多大:给个 1200 x 720,比 A4 横版略宽,贴文档刚好;
  • 列宽多少:取 280,够放 6~8 个中文字符加内边距;
  • 行高多少:取 120,节点高度 64,上下各留 28 的间隙。

有了这三个数,坐标就不是"试出来"的,而是"算出来"的:

```text

x = 80 + 列号 * 280 列号从 0 开始

y = 80 + 行号 * 120 行号从 0 开始

```

于是四列的 x 分别是 80、360、640、920;四行的 y 分别是 80、200、320、440。

第 2 步:写出第一个最小可运行的图

下面是一份 YAML 风格的图定义。这类 DSL 常见两种写法:YAML 风格(缩进敏感、适合程序生成)和括号风格(适合手写),下面用前者举例。

```yaml

canvas:

width: 1200

height: 720

background: "#ffffff"

nodes:

  • id: client

label: 浏览器 / App

x: 80

y: 320

w: 160

h: 64

  • id: gateway

label: API 网关

x: 360

y: 320

w: 160

h: 64

  • id: order

label: 订单服务

x: 640

y: 200

w: 160

h: 64

  • id: user

label: 用户服务

x: 640

y: 440

w: 160

h: 64

  • id: db

label: 主库

x: 920

y: 320

w: 180

h: 64

edges:

  • from: client

to: gateway

label: HTTPS

  • from: gateway

to: order

  • from: gateway

to: user

  • from: order

to: db

  • from: user

to: db

```

把它保存成 arch.yaml,用 Reladraw 打开或渲染。这时候你应该看到一条从左往右的主干,中间在网关处分叉成上下两条,再汇到右边的数据库。

注意 y: 320 那一行:行号其实是 2(80 + 2×120 = 320),所以网关和数据库在同一水平线上,订单服务在它上方,用户服务在下方。这就是"网格法"的价值——你脑子里想的是"网关在第 3 行",手上打出来的是数字。

第 3 步:用分组框把边界画出来

架构图好看不好看,很大程度取决于有没有分组。加一层容器,把服务圈在一起:

```yaml

groups:

  • id: g_front

label: 接入层

x: 40

y: 280

w: 220

h: 144

  • id: g_service

label: 业务服务

x: 600

y: 160

w: 240

h: 384

  • id: g_data

label: 数据层

x: 880

y: 280

w: 260

h: 144

```

分组框的画法通常是"先画框、再画里面的节点",因为框通常要在填充和描边上都更淡一点,视觉上才会退到后面去。如果工具支持 z 或 layer 字段,把分组框的层级调到节点之下。

这里有一个关键问题:分组内部的节点,坐标是相对框还是相对画布? 两种设计都有人做,行为完全不同。相对坐标的话,节点 x 要从分组框的左上角重新算;绝对坐标的话,上面那份 nodes 一个数字都不用改。第一次用务必只放一个节点测一下,再批量写。

第 4 步:控制连线从哪里出发

默认情况下,连线会自动选最近的两个边作为出入口。图简单的时候没问题,节点一多就会出现连线贴着文字走、或者两条线重叠。

处理办法通常是给边加锚点或端口:

```yaml

edges:

  • from: gateway

to: order

fromAnchor: right

toAnchor: left

route: orthogonal

label: gRPC

labelPosition: 0.5

```

几个概念:

  • fromAnchor / toAnchor:指定从节点的哪条边出去(top / right / bottom / left);
  • route: orthogonal:走直角折线,架构图里比斜线好读;需要曲线时换成对应的值;
  • label:边上的文字,比如协议名、数据流向;
  • labelPosition:0 到 1 之间的数字,控制标签落在连线的哪个位置,避免压到节点。

如果两条线还是重叠,可以给其中一条加一个 waypoints(中间控制点)列表,手动把线掰开:

```yaml

edges:

  • from: user

to: db

waypoints:

  • x: 840

y: 480

  • x: 1010

y: 480

```

这本质上还是在"自己定位置",只不过定的是连线的位置。

第 5 步:样式、字体和深浅色

样式一般分三层:全局主题、分组级、节点级。能放全局的就别放节点级,否则改一次颜色要改 20 个地方。

```yaml

theme:

fontFamily: "Source Han Sans, Noto Sans CJK SC, sans-serif"

fontSize: 14

node:

fill: "#f7f9fc"

stroke: "#c8d3e0"

radius: 8

edge:

stroke: "#6b7a90"

width: 1.5

nodes:

  • id: db

label: 主库

x: 920

y: 320

w: 180

h: 64

style:

fill: "#eef6ff"

stroke: "#7aa7d6"

```

关于字体,有一点必须提前做:如果图上会出现中文,字体列表里一定要写中文字体,或者把字体文件嵌进导出结果。否则在别人的电脑上打开 SVG,中文可能变成方框。

第 6 步:导出与进版本库

导出通常有命令行和图形界面两条路。命令行的形态大致是这样:

```bash

渲染成 SVG(子命令与参数名以官方文档为准)

reladraw export arch.yaml --format svg --out arch.svg

渲染成高清 PNG,倍率按需调整

reladraw export arch.yaml --format png --scale 2 --out arch.png

```

SVG 和 PNG 各有用途:SVG 放大不糊、适合贴网页和文档,但字体依赖环境;PNG 到处都能看,但不方便再编辑。稳妥的做法是两份都出,SVG 进仓库当源文件,PNG 用来发消息。

如果工具支持渲染到标准输出(--out - 或者省略输出路径),就能接进 CI:

```bash

提交前自动检查图能不能渲染出来

reladraw export arch.yaml --format svg --out /dev/null

```

这一步能拦住"改了 YAML 缩进、图直接渲染失败"的低级事故。

常见坑与排错

图整个上下颠倒或跑出画布。 九成是坐标系方向理解反了。先放一个节点在 (0, 0),看它出现在左上角还是左下角。

节点位置比预期偏了半个身位。 有些实现里 x / y 指的是节点左上角,有些指的是中心点。判断方法:把同一个坐标给两个不同尺寸的节点,看它们的左上角是否重合。

分组加进去之后节点全跑偏。 容器内坐标是相对还是绝对的问题,见第 3 步。测一个节点就能确定。

中文标签溢出边框。 手动定位置的代价就是得自己留够宽度。经验值:中文按每字约 14~16 px 估(跟随字号变化),英文字符按一半估,再左右各留 16 px 内边距。拿不准就把 w 加大 20 px,宁可松一点。

连线和文字叠在一起。 用 labelPosition 挪标签,或者换 fromAnchor / toAnchor 让线走另一条边。

YAML 缩进报错。 缩进只能用空格,同一层级必须对齐。别在文件里混用 Tab。报错信息通常会给出行号,从那一行的上一行开始看。

id 重复。 两个节点用了同一个 id,连线会连到意料之外的地方。命名上建议加前缀区分模块,比如 svc_order、db_order。

导出后中文变方框。 目标环境没装对应字体。解决办法是把字体内嵌进导出文件,或者导出时把文字转成路径。具体开关以官方文档为准。

改了 YAML 但画面没变。 有些客户端有缓存或需要手动刷新。先确认保存了,再确认工具读的是不是同一个文件路径。

下一步建议

把坐标抽成常量。 如果 DSL 支持变量或引用,把列宽、行高、起始边距定义成一组数字,后面所有坐标都用表达式算。改一次间距,全图跟着变,这是"手写图"能长期维护的关键。

把大图拆成多个文件。 前端一张、后端一张、数据一张,用 include 或 import 合成。单文件超过 200 行之后,找节点会变成体力活。

给自己留一份坐标草图。 在 YAML 顶上写注释,标明列 0/1/2/3 的 x 值分别是多少。三个月后回来改图,你会感谢现在的自己。

用同一套方法画别的图。 RAG 管线、Agent 编排、部署拓扑、审批流程,只要是"有明确分层和流向"的图,都可以用同一套网格法加绝对定位来写。DSL 画图真正省时间的场景,不是画一次,而是画完还要改十次。

把图交给 CI 检查。 渲染失败就报错,顺带把导出的 SVG 存档,文档里引用最新版本,图再也不会和代码脱节。

AI 生成本文由 AI 基于公开信息自动生成,仅供参考。