deepseek 总结的html绘图规范
版本:v2(汇总至第 40 轮迭代)
参考原型:https://martinbj2008.github.io/html/fib_animation.html
适用场景:Linux 内核数据结构关系图(数组 / 链表 / 树 / 注册表)的静态 SVG 绘制
1. 参考原型:martinbj 的 FIB 画页
打开原页面,可以提炼出以下视觉约定(本项目沿用了其中大部分):
| 元素 | martinbj 做法 | 本项目沿用 / 调整 |
|---|---|---|
| 页面容器 | 白色圆角卡片 + 浅灰背景 | 沿用 |
| 顶部信息 | 大标题 + 一行灰色说明 | 沿用(改为中文 title + commit 引用) |
| 节点 | 圆角矩形,标题栏 + 内容区 | 沿用 |
| 节点配色 | 不同协议不同色 | 沿用 |
| 节点间关系 | 曲线 + 箭头 | 沿用(改为黑色) |
| 内容字段 | 字段 : 值 键值对 |
沿用(callbacks 例外,见后文) |
| 底部 | 配套代码区 | 按需保留 |
关键取舍:martinbj 是动画页(节点移动/重排),本项目只画最终状态,不做任何 animate 元素。
2. 总体设计原则
| # | 原则 | 说明 |
|---|---|---|
| P1 | 静态优先 | 不做动画,只画最终状态 |
| P2 | 分层递进 | 顶部声明 → 数组/链表 → 箭头 → 节点展开 → 底部代码(可选) |
| P3 | 一图一焦点 | 主图只表达”注册关系”,代码/结构体定义放两侧或底部辅助 |
| P4 | 对齐严谨 | 箭头端点、框宽、列宽必须像素级对齐 |
| P5 | 配色有语义 | 同层元素同一套配色规则;不同协议用色相区分 |
| P6 | 极简冗余 | 不写”(指针)”、”(详情)”这类废话 |
| P7 | 可缩放无滚动 | SVG 用 viewBox + CSS width:100%,页面不自带滚动条 |
3. 页面布局
1 | |
4. 视觉规范
4.1. 字体
| 元素 | 字体 | 字号 | 字重 | 颜色 |
|---|---|---|---|---|
| 页面 Title | Arial | 20px | bold | #1565C0 |
| 页面 Subtitle | Arial | 12px | normal | #666 |
| 顶层声明 | monospace | 14px | normal(见「顶层声明的粗体」) | #000000 |
| 数组格内容 | monospace | 9px | bold | 按协议配色 |
| 节点名(标题栏) | monospace | 12px | bold | 按协议配色 |
分组标签(如 callbacks) |
monospace | 11px | bold | #1565C0 |
| 明细字段名 | monospace | 11px | normal | #555 |
| 冒号 | monospace | 11px | normal | #888 |
| 明细字段值 | monospace | 11px | bold | 按函数配色 |
| 代码区 | monospace | 12px | normal | #333 / #555 |
4.2. 配色
数组条(统一黑框,无背景色)
- 外框:
#3331.5px - 空槽分隔:虚线
#B0BEC5,stroke-dasharray="2,2" - 有指针的格子分隔:实线
#3331.2px - 格子文字:按协议色(见下)
协议主题色(仅用于文字 / 节点框)
| 协议 | 主色 | 标题背景 | 标题文字 |
|---|---|---|---|
| IPIP (4) | #7B1FA2 |
#F3E5F5 |
#4A148C |
| TCP (6) | #43A047 |
#E8F5E9 |
#2E7D32 |
| UDP (17) | #FF8F00 |
#FFF8E1 |
#E65100 |
| GRE (47) | #1565C0 |
#E3F2FD |
#0D47A1 |
函数色(所有协议框统一,不随协议变)
| 函数 | 背景 | 文字 |
|---|---|---|
gso_segment |
#FFF59D(黄) |
#5D4037(深棕) |
gro_receive |
#1B5E20(深绿) |
#FFFFFF(白) |
gro_complete |
#1B5E20(深绿) |
#FFFFFF(白) |
4.3. 边框
| 元素 | 描边 |
|---|---|
| 数组条外框 | #333 1.5px |
| 节点框 | 协议主色 1.5px |
| 节点标题分隔线 | 协议主色 1.5px |
| 明细虚线框 | #90A4AE 1px,stroke-dasharray="4,3" |
4.4. 箭头与连线
- 曲线:
<path>贝塞尔(C命令),起点在数组格底部中心,终点在节点框顶中心 - 箭头 marker:
viewBox="0 0 10 10"refX="0"(尾部对齐曲线终点,见「箭头对齐」)refY="5"markerWidth="6" markerHeight="6"orient="auto"fill="#000000"(统一黑色)
- 颜色:连线与箭头统一黑色
#000000,不随协议变色
5. 技术实现要点
5.1. 响应式(无滚动条)
1 | |
1 | |
5.2. 文字宽度精确控制
问题:浏览器字体渲染的字符宽度和手动估算不一致,导致背景框和文字不贴合。
方案:用 textLength 强制锁定宽度:
1 | |
105.6=16 字符 × 6.6px/字符(11px monospace 平均字宽)lengthAdjust="spacingAndGlyphs"会拉伸字形以适应宽度
5.3. 分组标签的冒号
规则:callbacks、ops、handlers 这类”字段分组标签”后面不加冒号。
1 | |
理由:标签是”分组标题”而非键值对;下面三行已经是 字段 : 值 形式,冒号已足够表达关系。
5.4. 顶层声明的粗体
规则:声明行整体正常字重,只对关键标识符加粗。
1 | |
效果:inet_offloads 明显加粗,其余正常。
5.5. 边框压住背景
错误的绘制顺序(背景会盖住边框):
- 主框 rect
- 标题栏 rect(有背景色)
- 内容
正确的绘制顺序:
- 主框 rect(只有 fill,无 stroke)
- 标题栏 rect(只有 fill,无 stroke)
- 内容
- 顶层边框 rect(只有 stroke,无 fill) ← 压在最上层
- 标题分隔线
5.6. 箭头对齐
问题:箭头尖端与框顶之间容易留有缝隙。
精确公式:
1 | |
示例(框顶 y=130):
1 | |
5.7. 数组条格子布局
- 每格固定宽度(本项目用 38px)
- 第 N 格的左边界 =
起始 x + N × 格宽 - 第 N 格的中心 =
起始 x + N × 格宽 + 格宽 / 2 - 有指针的格子:实线边框 + 协议色文字
- 空槽格子:虚线分隔 + 灰色
...标记 - 末格:写数组长度(如
255)
6. 常见坑与解决方案
| # | 坑 | 解决方案 |
|---|---|---|
| 1 | 页面出现横向滚动条 | 去掉 overflow: auto,SVG 用 viewBox + width:100% |
| 2 | 背景色块和文字不贴合 | 用 textLength 锁定宽度,rect 用同数值 |
| 3 | 框太宽 | 宽度 = 最长文字宽 + 2 字符 |
| 4 | 节点框宽度不一致 | 同类节点用同一宽度值 |
| 5 | 箭头和框有空隙 | refX=0 + 终点提前到 框顶 - 10.8 |
| 6 | 边框被背景色盖住 | 最后再画一层 stroke-only 的边框 |
| 7 | 数组格位置对不上 | 每格固定 38px,下标 × 38 就是格左边界 |
| 8 | 顶部声明文字太占位 | 去掉外框,只留一行文字,紧贴数组条 |
| 9 | 大量空槽占地方 | 用一个格子写 ... 代表连续空槽 |
| 10 | 尾部长度无标识 | 末格写数组长度(如 255) |
| 11 | 分组标签后带冒号 | 删除(见「分组标签的冒号」) |
| 12 | 箭头/连线颜色太花 | 统一黑色 #000000 |
| 13 | 函数背景色跨协议不统一 | 按函数类型固定配色(见「配色」) |
7. 绘图 Checklist
7.1. 结构层
- 明确数据结构的本质(数组 / 链表 / 树 / 注册表)
- 明确”根对象”和”子对象”的关系
- 确定每个节点的字段(只保留必要的)
- 确定”排序 / 索引”规则(如 protocol 号)
7.2. 视觉层
- 主色定义(几个协议几个色)
- 字体规范(字号、字重、字体族)
- 边框规范(宽度、颜色、虚实)
- 背景色规范(只在高亮元素用,不用大面积)
- 箭头规范(长度、粗细、颜色、对齐)
7.3. 技术层
- SVG 用
viewBox,不写固定 width / height - CSS 用
width:100%+height:auto - 关键文字用
textLength锁定宽度 - 边框最后画(stroke-only,压上层)
- 曲线 + marker,
refX=0 - 数组每格等宽,位置 = 索引 × 格宽
- 箭头尖端与框顶无缝(终点 = 框顶 − 10.8)
7.4. 内容层
- 无用信息全部删除(如默认值
flags = 0) - 分组标签后不加冒号
- 顶层声明只加粗关键标识符
- 尾部用
...+ 长度数字 - 代码区可选,不喧宾夺主
- 一句话总结放 Subtitle
8. 修改历史归档(可作为需求模板)
按迭代顺序,记录本项目所有修改要求:
8.1. 结构性确认
- 静态图,不做动画
-
inet_offloads[]是数组,不是链表(与offload_base链表区分) - 参考 commit:
de27d001d1877(2012 引入) - 参考内核版本:6.6+
8.2. 布局
- 数组条横向排列,不是纵向
- 每个元素占一格
- 只保留一行(不要下标行 + 值行两行)
- 连续空槽用一个格子放
...表示 - 末尾最后一格写
255
8.3. 尺寸
- 数组格宽度压缩到 20%(最终 38px/格)
- 结构体框宽度按函数名长度自动调整
- 同层节点框等宽
- 框间距一致(33px)
- 框高 150px,标题栏 28px
8.4. 内容取舍
- 去掉
flags : 0行 - 去掉底部
struct net_offload定义框 - 去掉
inet_offloads[] 数组标题行 - 去掉
net/ipv4/protocol.c行 - 去掉
MAX_INET_PROTOS = 256说明 - 去掉”(指针)”等废话标注
-
callbacks后面不加冒号
8.5. 文字与配色
-
callbacks字号与函数名一致(11px) - 函数名缩进 2 字符
- 声明行:整体正常字重,只
inet_offloads加粗 - 声明行与数组条紧贴
- 函数背景色:
gso_segment黄,gro_*深绿(跨协议统一) - 背景色与文字等宽(textLength)
- 边框比最长文字往右多 2 字符
8.6. 数组条风格
- 外框统一黑色
- 有指针的格子:实线黑色
- 空槽格子:虚线灰色
- 不要彩色背景
- 不要彩色边框
- 保留字体颜色(协议色)
8.7. 连线
- 曲线终点加箭头
- 箭头尾部对齐曲线终点(
refX=0) - 箭头尖端接触框顶(不留缝)
- 框整体下移给箭头留空间
- 箭头与连线统一黑色
8.8. 内容扩充
- 增加 IPIP:4 / GRE:47
- 四个注册点:IPIP / TCP / UDP / GRE
- IPIP:4 前面只有 0~3 四个空槽
- 各 protocol 按真实下标就位
9. 快速启动 Prompt 模板
复制以下内容作为新任务的输入:
1 | |
deepseek 总结的html绘图规范
https://martinbj2008.github.io/2026/09/29/html-pic-md/