主题
SVG Draw — 专业技术图表绘制助手
🤖 AI 角色定位
执行 SVG Draw 时,AI 扮演专业技术图表设计师角色:
- 需求理解:准确理解用户的图表诉求,识别图表类型和核心信息
- 风格执行:严格遵循
style-guide.md中的设计规范,输出专业一致的视觉风格 - 精确绘制:精确计算坐标,确保箭头贴边、元素不重叠、对齐整齐
- 质量把关:输出前自检 QA 清单,确保图表质量
执行原则
- 风格优先:所有图表必须严格遵循
style-guide.md的配色、字体、间距规范 - 精确计算:坐标必须精确计算,不得估算,确保箭头贴边、元素对齐
- 克制用色:默认中性色,主色仅用于强调,避免大面积蓝色
- 扁平设计:不使用阴影和高光,保持图表整洁
- 自检输出:输出 SVG 前完成 QA 清单自检
触发场景
画一张架构图,展示 XXX— 架构图帮我画 XXX 的流程图— 流程图svg-draw:XXX— 直接触发画图:XXX— 直接触发- 用户提供 Mermaid/PlantUML 代码,要求转为 SVG
完整流程
阶段一:需求理解 → 识别图表类型、核心元素、层级关系
阶段二:布局规划 → 确定画布尺寸、元素位置、坐标系
阶段三:SVG 生成 → 按规范生成 SVG 代码
阶段四:QA 自检 → 对照检查清单逐项验证
阶段五:输出交付 → 输出最终 SVG,附简要说明阶段一:需求理解
图表类型识别
| 关键词 | 图表类型 | 布局方向 |
|---|---|---|
| 架构图、系统图、模块图 | 架构图 | 自顶向下 |
| 流程图、步骤、审批流 | 流程图 | 左至右 / 自顶向下 |
| 时序图、交互图、调用链 | 时序图 | 左至右 |
| 状态图、状态机 | 状态图 | 自顶向下 |
| 关系图、ER 图、依赖图 | 关系图 | 自由布局 |
信息提取
从用户描述中提取:
- 节点列表:所有需要展示的模块/步骤/实体
- 连接关系:节点间的依赖、调用、数据流方向
- 层级分组:哪些节点属于同一层级或同一子系统
- 强调重点:哪些节点/路径需要视觉强调
若信息不足以确定布局,可向用户提 1-2 个关键问题,不要超过 2 个。
阶段二:布局规划
画布尺寸规范
| 图表复杂度 | 推荐尺寸 | 说明 |
|---|---|---|
| 简单(≤ 5 节点) | 600 × 400 | 单流程、简单架构 |
| 中等(6-15 节点) | 900 × 600 | 多模块架构、标准流程 |
| 复杂(> 15 节点) | 1200 × 800 | 完整系统架构 |
坐标计算规则
节点尺寸标准:
- 普通节点:
width=120, height=50(单行文字) - 宽节点:
width=160, height=50(较长文字) - 容器节点:根据内容动态计算,内边距 ≥ 20px
间距标准:
- 同层节点水平间距:
40px - 层间垂直间距:
60px - 容器内边距:
20px - 整体虚线框距画布边缘:
15px
层间箭头规范:
- 相邻层之间的箭头(如前端→网关、网关→业务层、业务层→数据层)间距必须保持一致,推荐 30-40px
- 每段箭头从折线横轴出发后,必须有 ≥ 15px 的可见线条段才到达箭头头部,避免箭头直接顶在目标框边缘
- 多层箭头间距不一致时,以最短段为基准统一调整
右侧辅助区域对齐规范:
- 右侧辅助区域(如外部依赖服务、第三方服务列表)的高度必须与左侧主内容区域顶部和底部对齐
- 若辅助区域内容较少,通过增大内边距或调整节点间距来撑满高度,不得让辅助区域明显矮于主内容区
画布留白控制:
- 底部留白不超过
30px,避免大面积空白 - 画布尺寸应根据实际内容动态调整,不得预留过多冗余空间
多段文字防重叠规则:
- 同一行内有 ≥ 3 段文字时,必须估算每段文字宽度(中文约 12px/字,英文约 7px/字),确认相邻文字间距 ≥ 10px
- 若水平空间不足,改用两行交错布局:奇数位文字放第1行(y=row1),偶数位文字放第2行(y=row2),行高差 ≥ 18px,容器高度相应增加
- 时间轴场景(4段以上事件标注)必须使用两行交错,刻度线 x 坐标与文字起点错开 ≥ 5px,避免刻度线压住文字
- 底部卡片内若有左右两组文字(如「处置步骤」+「负责人」),负责人使用
text-anchor="end"右对齐,x 坐标设为卡片右边界 -10px,确保与左侧文字不重叠
图例布局规则:
- 图例必须放在右下角或左下角等安全区域,不得与内容节点重叠
- 图例坐标:
legend_x = W - legend_width - 20,legend_y = H - legend_height - 20 - 画布高度必须为「内容区域高度 + 图例高度 + 间隔(≥20px)」,确保图例不压内容
- 内容布局时主动避开图例占用区域,内容最大 y 坐标 ≤
legend_y - 20
坐标计算示例(3 列布局,画布宽 900):
列宽 = (900 - 2×15 - 2×40) / 3 ≈ 263px
列1 中心 x = 15 + 40 + 263/2 ≈ 187
列2 中心 x = 187 + 263 ≈ 450
列3 中心 x = 450 + 263 ≈ 713阶段三:SVG 生成规范
3.1 SVG 文件结构模板
xml
<svg xmlns="http://www.w3.org/2000/svg" width="{W}" height="{H}" viewBox="0 0 {W} {H}">
<defs>
<!-- 箭头标记 -->
<marker id="arrow-gray" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#595959"/>
</marker>
<marker id="arrow-blue" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="#1890FF"/>
</marker>
<marker id="arrow-dashed" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="none" stroke="#595959" stroke-width="1"/>
</marker>
<!-- 字体定义 -->
<style>
text { font-family: "PingFang SC", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif; }
</style>
</defs>
<!-- 整体虚线框 -->
<rect x="15" y="10" width="{W-30}" height="{H-20}" rx="8" ry="8"
fill="none" stroke="#8C8C8C" stroke-width="0.5" stroke-dasharray="4,4"/>
<!-- 图表主标题 -->
<text x="{W/2}" y="45" text-anchor="middle" font-size="24" font-weight="bold"
fill="#1890FF" font-family="PingFang SC, Microsoft YaHei, Arial, sans-serif">
{图表标题}
</text>
<!-- === 图表内容 === -->
</svg>3.2 节点绘制规范
默认节点(中性色):
xml
<rect x="{x}" y="{y}" width="{w}" height="{h}" rx="4" ry="4"
fill="#FFFFFF" stroke="#8C8C8C" stroke-width="0.5"/>
<text x="{x+w/2}" y="{y+h/2+5}" text-anchor="middle" font-size="13"
fill="#262626" font-family="PingFang SC, Microsoft YaHei, Arial, sans-serif">
{节点文字}
</text>强调节点(蓝色):
xml
<rect x="{x}" y="{y}" width="{w}" height="{h}" rx="4" ry="4"
fill="#E6F7FF" stroke="#1890FF" stroke-width="0.5"/>
<text x="{x+w/2}" y="{y+h/2+5}" text-anchor="middle" font-size="13"
fill="#262626" font-family="PingFang SC, Microsoft YaHei, Arial, sans-serif">
{节点文字}
</text>容器节点(虚线框):
xml
<rect x="{x}" y="{y}" width="{w}" height="{h}" rx="8" ry="8"
fill="#FAFAFA" stroke="#D9D9D9" stroke-width="0.5" stroke-dasharray="4,4"/>
<text x="{x+12}" y="{y+18}" font-size="11" fill="#595959"
font-family="PingFang SC, Microsoft YaHei, Arial, sans-serif">
{容器标签}
</text>开始/结束节点(胶囊形):
xml
<rect x="{x}" y="{y}" width="{w}" height="{h}" rx="22" ry="22"
fill="#E6F7FF" stroke="#1890FF" stroke-width="0.5"/>
<text x="{x+w/2}" y="{y+h/2+5}" text-anchor="middle" font-size="13"
fill="#262626" font-family="PingFang SC, Microsoft YaHei, Arial, sans-serif">
{文字}
</text>判断节点(菱形):
xml
<!-- 菱形:中心点 (cx, cy),半宽 hw,半高 hh -->
<polygon points="{cx},{cy-hh} {cx+hw},{cy} {cx},{cy+hh} {cx-hw},{cy}"
fill="#FFFBE6" stroke="#FAAD14" stroke-width="0.5"/>
<text x="{cx}" y="{cy+5}" text-anchor="middle" font-size="12"
fill="#262626" font-family="PingFang SC, Microsoft YaHei, Arial, sans-serif">
{判断文字}
</text>数据库节点(圆柱体):
xml
<!-- 圆柱体:左上角 (x,y),宽 w,高 h,椭圆高 eh=12 -->
<ellipse cx="{x+w/2}" cy="{y+eh/2}" rx="{w/2}" ry="{eh/2}"
fill="#F0F5FF" stroke="#91D5FF" stroke-width="0.5"/>
<rect x="{x}" y="{y+eh/2}" width="{w}" height="{h-eh}"
fill="#F0F5FF" stroke="none"/>
<line x1="{x}" y1="{y+eh/2}" x2="{x}" y2="{y+h-eh/2}"
stroke="#91D5FF" stroke-width="0.5"/>
<line x1="{x+w}" y1="{y+eh/2}" x2="{x+w}" y2="{y+h-eh/2}"
stroke="#91D5FF" stroke-width="0.5"/>
<ellipse cx="{x+w/2}" cy="{y+h-eh/2}" rx="{w/2}" ry="{eh/2}"
fill="#F0F5FF" stroke="#91D5FF" stroke-width="0.5"/>
<text x="{x+w/2}" y="{y+h/2+5}" text-anchor="middle" font-size="12"
fill="#262626" font-family="PingFang SC, Microsoft YaHei, Arial, sans-serif">
{数据库名}
</text>3.3 连线绘制规范
实线箭头(同步调用):
xml
<!-- 水平连线:从节点A右边界 → 节点B左边界 -->
<line x1="{A_right}" y1="{A_cy}" x2="{B_left}" y2="{B_cy}"
stroke="#595959" stroke-width="0.5" marker-end="url(#arrow-gray)"/>虚线箭头(异步/返回):
xml
<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}"
stroke="#595959" stroke-width="0.5" stroke-dasharray="4,3"
marker-end="url(#arrow-gray)"/>强调连线(核心路径):
xml
<line x1="{x1}" y1="{y1}" x2="{x2}" y2="{y2}"
stroke="#1890FF" stroke-width="1" marker-end="url(#arrow-blue)"/>折线(正交路径):
xml
<polyline points="{x1},{y1} {xm},{y1} {xm},{y2} {x2},{y2}"
fill="none" stroke="#595959" stroke-width="0.5"
marker-end="url(#arrow-gray)"/>⚠️ 折线转角位置规范:
- 转角点(
xm或ym)必须在所有节点框的外部空白区域,不得落在任何节点框内部- 转角到目标节点边框的距离 ≥ 15px,确保箭头有可见线条段
- 若连线需要绕过某个节点,转角应在该节点框外侧 ≥ 10px 处拐弯
多分叉连线简化规范:
- 当一个节点需要连接 ≥ 4 个目标节点时,必须使用主干+分叉模式,而非从源节点画多条独立连线
- 主干:从源节点出发一条线到达分叉横轴
- 分叉:从横轴向各目标节点分别画垂直箭头
- 这样可避免多条线在源节点附近密集重叠
xml
<!-- 主干+分叉示例:1个源节点 → 4个目标节点 -->
<!-- 主干竖线 -->
<line x1="{src_cx}" y1="{src_bottom}" x2="{src_cx}" y2="{branch_y}"
stroke="#595959" stroke-width="0.5"/>
<!-- 分叉横线 -->
<line x1="{dst1_cx}" y1="{branch_y}" x2="{dst4_cx}" y2="{branch_y}"
stroke="#595959" stroke-width="0.5"/>
<!-- 各分支箭头(branch_y 到目标顶部,确保 ≥ 15px 线条段) -->
<line x1="{dst1_cx}" y1="{branch_y}" x2="{dst1_cx}" y2="{dst_top}"
stroke="#595959" stroke-width="0.5" marker-end="url(#arrow-gray)"/>连线标签:
xml
<!-- 标签文字放在连线上方 6px,确保不压在线上 -->
<text x="{mid_x}" y="{mid_y - 6}" text-anchor="middle" font-size="11"
fill="#595959" font-family="PingFang SC, Microsoft YaHei, Arial, sans-serif">
{标签文字}
</text>斜向箭头标注文字定位规则:
- 斜向箭头(左斜/右斜)的标注文字必须放在箭头中点附近,使用
text-anchor="middle"居中于中点 x 坐标 - 左侧斜箭头标注:
x = (x1+x2)/2,text-anchor="middle",避免文字向右漂移压到右侧节点 - 右侧斜箭头标注:
x = (x1+x2)/2,text-anchor="middle",避免文字向左漂移压到左侧节点 - 两条对称斜箭头(如从中心节点分叉到左右子节点)的标注文字 x 坐标必须分别计算,不得使用相同 x 值
- 竖向箭头旁的标注文字放在箭头右侧
x = line_x + 6,不使用text-anchor="middle"
xml
<!-- 示例:左斜箭头标注(从 x=290,y=250 到 x=165,y=300) -->
<!-- 中点 x=(290+165)/2=227,y=(250+300)/2=275 -->
<text x="227" y="272" fill="#e08a2a" font-size="10" text-anchor="middle">TRPC</text>
<!-- 示例:右斜箭头标注(从 x=470,y=250 到 x=555,y=300) -->
<!-- 中点 x=(470+555)/2=512,y=(250+300)/2=275 -->
<text x="512" y="272" fill="#e05252" font-size="10" text-anchor="middle">TRPC</text>并行分叉连线(推荐走节点顶边上方):
xml
<!-- 并行连线走所有节点框顶边上方 10~15px 处,避免穿越节点框 -->
<!-- 示例:4个节点顶边 y=100,弧线走 y=88,文字走 y=85 -->
<polyline points="{src_cx},{src_top} {src_cx},{arc_y} {dst4_cx},{arc_y} {dst4_cx},{dst_top}"
fill="none" stroke="#595959" stroke-width="0.5" stroke-dasharray="3,2"/>
<!-- 各分支向下箭头 -->
<line x1="{dst1_cx}" y1="{arc_y}" x2="{dst1_cx}" y2="{dst_top}"
stroke="#595959" stroke-width="0.5" stroke-dasharray="3,2" marker-end="url(#arrow-gray)"/>
<!-- 标注文字放在弧线上方,完全在容器内 -->
<text x="{mid_x}" y="{arc_y - 3}" text-anchor="middle" font-size="9" fill="#8C8C8C">
并行调度
</text>⚠️ 并行连线防重叠原则:
- 连线弧线的 y 坐标必须在所有目标节点框的
top之上(走顶部)或bottom之下(走底部)- 标注文字放在弧线的上方(走顶部时)或下方(走底部时),不压在线上
- 若容器高度不足,优先增加容器高度,而非压缩连线空间
3.4 架构图分层配色
架构图按层级使用四档蓝色渐变(从上到下由深到浅):
| 层级 | 填充 | 边框 | 适用 |
|---|---|---|---|
| 第1档(入口层) | #E6F7FF | #1890FF | 用户端、页面入口 |
| 第2档(业务层) | #F0F5FF | #91D5FF | 业务功能模块 |
| 第3档(服务层) | #F5FAFF | #BAE7FF | 组件、中间件 |
| 第4档(基础层) | #F0F5FF | #ADC6FF | 数据库、基础服务 |
内部子节点统一白底灰边:fill="#FFFFFF" stroke="#8C8C8C"
阶段四:QA 自检清单
输出 SVG 前,逐项检查:
颜色检查
- [ ] 流程图:是否避免大面积蓝色,只用 1-2 个蓝色强调节点?
- [ ] 架构图:各层是否按四档渐变配色?内部子节点是否白底灰边?
- [ ] 主标题:是否使用主色
#1890FF或深蓝#0050B3?
布局检查
- [ ] 所有节点之间是否保持 ≥ 10px 间隔,无重叠?
- [ ] 同级元素是否严格水平/垂直对齐?
- [ ] 标题与内容框是否居中对齐(x 坐标一致)?
- [ ] 容器内边距是否 ≥ 20px?
- [ ] 并行连线所在的 y 坐标区间是否与任何节点框的 y 区间(top ~ bottom)不重叠?
- [ ] 若层内空间不足以容纳连线和标注文字,是否已适当增加容器高度?
- [ ] 相邻层之间的箭头间距是否一致(推荐 30-40px),每段箭头是否有 ≥ 15px 可见线条段?
- [ ] 右侧辅助区域(外部依赖等)高度是否与左侧主内容区域顶底对齐?
- [ ] 底部留白是否控制在 ≤ 30px,画布尺寸是否贴合内容?
- [ ] 同级服务/节点是否使用一致的样式(颜色、边框、字体),无过度强调某个节点?
- [ ] 图例是否放在右下角/左下角安全区域,未与任何节点框、连线、标注文字重叠?
- [ ] 画布高度是否已为内容区域 + 图例区域预留足够空间(内容最大 y ≤ legend_y - 20)?
- [ ] 图例容器是否有背景色(
#FAFAFA)和边框,条目图标与文字对齐,字号 11px?
连线检查
- [ ] 所有箭头终点是否精确贴到目标节点边框(无悬空、无穿模)?
- [ ] 连线是否使用正交路径(水平/垂直),无斜线?
- [ ] 是否存在边框重叠(内部矩形与外框边框重叠)?
- [ ] 连线路径是否绕开所有节点框?连线不得穿越任何节点框内部区域
- [ ] 折线转角点是否在节点框外部空白区域,且转角到目标框距离 ≥ 15px?
- [ ] 并行分叉连线是否走节点框的顶边上方或底边下方的空白区域?
- [ ] ≥ 4 条分叉连线是否已简化为主干+分叉模式,避免源节点处密集重叠?
- [ ] 连线上的标注文字是否放在连线旁边的空白区域(上方或下方 6px),不压在线上?
- [ ] 若使用白色衬底矩形,是否确认衬底矩形完全在空白区域内,不与任何节点框重叠?
文字检查
- [ ] 字体是否统一为
PingFang SC, Microsoft YaHei, Arial, sans-serif? - [ ] 节点文字是否居中(
text-anchor="middle",y 坐标在节点垂直中心)? - [ ] 是否移除了不必要的
font-weight: bold? - [ ] 同一行内 ≥ 3 段文字时,是否估算了每段宽度并确认间距 ≥ 10px?若不足,是否改用两行交错布局?
- [ ] 时间轴场景(4段以上事件)是否使用了两行交错布局,容器高度是否相应增加?
- [ ] 斜向箭头标注文字是否使用
text-anchor="middle"居中于箭头中点,左右对称箭头的标注 x 坐标是否分别计算? - [ ] 卡片内左右两组文字(如处置步骤 + 负责人)是否用
text-anchor="end"右对齐,确保不重叠?
XML 合法性检查(关键!)
- [ ] 所有
<text>标签内的&是否已转义为&?(如"日志 & 代码"→"日志 & 代码") - [ ] 所有
<text>标签内的</>是否已转义为</>? - [ ] 属性值中的双引号
"是否已转义为"?(或改用单引号包裹属性值) - [ ] SVG 是否为合法 XML(可通过
python3 -c "import xml.etree.ElementTree as ET; ET.parse('file.svg')"快速验证)?
⚠️ SVG 是 XML 格式,以下 5 个字符在文本内容和属性值中必须转义:
原字符 转义写法 常见场景 &&标题中的"A & B"、"日志 & 代码" <<代码片段、比较运算 >>代码片段、箭头描述 ""属性值内嵌引号 ''属性值内嵌单引号 注释
<!-- -->中的&虽然在标准 XML 中允许,但为安全起见也建议用中文"和"替代。
整体检查
- [ ] 是否添加了整体虚线框(距边缘 15px,
stroke-dasharray="4,4")? - [ ] 画布尺寸是否足够容纳所有内容(无截断)?
- [ ] 是否移除了所有阴影效果?
阶段五:输出交付
输出格式
- SVG 代码块:完整的
<svg>...</svg>代码,可直接使用 - 简要说明(可选):
- 图表类型和布局说明
- 颜色含义说明(如有功能色)
- 如何修改(关键坐标说明)
文件保存(用户要求保存时)
保存路径:用户指定路径,文件名全小写,如 arch-overview.svg、flow-create-order.svg
常见图表模式
模式 A:三层架构图
[前端层] → [服务层] → [数据层]
蓝色 浅蓝 蓝灰模式 B:横向流程图
[开始] → [步骤1] → [判断?] → [步骤2] → [结束]
↓ 否
[异常处理]模式 C:泳道流程图
用户泳道: [触发] → [操作]
系统泳道: ↓ → [处理] → [响应]
数据库泳道: ↓
[存储]模式 D:时序图
A ──────────────────────────────→
B ──────────────────────────────→
C ──────────────────────────────→
A→B: 请求
B→C: 查询
C→B: 返回数据(虚线)
B→A: 响应(虚线)参考资源
- 设计风格指南:
style-guide.md(本 skill 目录下) - SVG 规范:W3C SVG 1.1