关于 figure
figure 是用于在文档站点中选择和绘制说明性图形的技能。它指导作者挑选合适的图表形式,并规定 SVG 标记、主题配色和连接线约定,使图形符合站点的视觉规范。
主要功能
- 01选择图形形式的指引
- 02各类图表布局参考
- 03基于主题的 SVG 色彩令牌
- 04标签、节点和连接线规则
- 05Mermaid 与图表的适用场景说明
适用场景
- 01说明系统机制的运作方式
- 02为文档段落选择合适的图形
- 03制作适用于不同色彩模式的图形
- 04让图表遵循站点约定
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ markomitranic/ jotdown --skill figure安装后在 Claude Code 中输入/figure确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/forms/bar.mddependency.mdfishbone.mdflowchart.mdjourney.mdlayers.mdline.mdloop.mdnested.mdpyramid.mdquadrant.mdradar.mdsankey.mdscatter.mdsequence.mdstate.mdstory-map.mdswimlane.mdtimeline.mdtree.mdtreemap.mdvenn.mdwardley.mdwaterfall.mdwhat-talks-to-what.mdscripts/render.ts详细介绍
图示
此代码库中的文档页面用手绘图示来说明机制。默认形式是内嵌 SVG,直接放在 .mdx 中,并且只使用 --jd-fig-* CSS 变量绘制,因此无需额外处理,就能适用于两种颜色模式。本文末尾附近介绍了一种 HTML 图示,作为备用方案。
本文是索引:介绍如何选择图示形式,以及每种图示都必须遵循的规则。每种形式的布局语法都在 references/forms/ 中,每种形式各有一个文件;选定形式后再加载对应文件,而不是一次性全部加载。绘图技巧来自随 Claude Code 提供的技能,在绘制第一行 SVG 之前通过 Skill 工具加载。
调色板包含 13 个令牌,均根据项目主题精心设计:
| 令牌 | 用途 |
|---|---|
--jd-fig-ink | 标签,取自 foreground |
--jd-fig-muted | 次级标签和弱化文本,取自弱化前景色 |
--jd-fig-line | 方框轮廓和连接线 |
--jd-fig-line-soft | 细线、分隔线、最淡的轮廓 |
--jd-fig-surface | 方框填充色 |
--jd-fig-accent、--jd-fig-accent-soft | 图示重点涉及的一两个元素,取自 primary |
--jd-fig-p-ink、--jd-fig-p-bg | 第一种色调,取自 chart-1 |
--jd-fig-d-ink、--jd-fig-d-bg | 第二种色调,取自 chart-2 |
--jd-fig-i-ink、--jd-fig-i-bg | 第三种色调,取自 chart-3 |
图示、图表还是编辑插画
此技能用于绘制图示:以标准形式和网站的图示调色板呈现机制的组成部分及其连接方式。除此之外,还有另外两种技能:
- 用真实数据绘制的条形图、折线图、面积图、饼图或雷达图,应使用
<Chart />块。请使用chart技能。 - 每个页面开头的配图,就像杂志文章开篇时的插画,是编辑插画。请使用
editorial-illustration技能;它会以自身风格绘制到单独的 SVG 文件中,而不是页面内,并且不遵循以下规则。图示应放在章节中,用于解释内容。
应加载哪个内置技能
根据下文确定的形式,加载一个技能,而不是全部加载:
| 形式 | 加载 | 涵盖内容 |
|---|---|---|
| 任何机制:方框和箭头、流程、层级结构、时间线 | artifact-diagramming | 图示何时值得绘制、如何呈现真实机制、如何标注箭头 |
| 任何图表 | dataviz | 选择图表类型、控制标记数量、坐标轴和标签规则、配色公式 |
| 使用真实排版的 HTML 图示 | frontend-design(一个并非始终安装的插件) | 不显得像套用模板的字体、间距和布局选择 |
跳过 artifact-design、artifact-capabilities 和 design,它们针对的是完整的 Artifact 页面。你能使用的其他任何视觉技能都可以加载。它们的机制面向独立页面,因此请忽略其中关于 data-theme、currentColor、CDN 和页面布局的说明。只有绘图建议适用;标记和颜色由本文决定。
先选择形式
阅读图示所在段落,并判断它讨论的内容类型。然后在表格中查找对应内容。在查看任何表格行之前,先做一个更简单的判断:如果一句话或一个三列表格能同样快速地说明问题,就直接写出来。
表格中的一行只是候选项,并非最终结论。放置矩形之前,请打开对应文件并阅读开头的适用条件;如果某种形式不符合自身条件,那它就是错误的选择,无论表格中的描述看起来多么合适。机制表格的最后一行是一个真正可选的去处,并非无奈之选;归入这一项并不表示分类失败。多种形式共用一个文件,因此应打开参考列中指定的文件。
Mermaid 或图
在这里绘图的另一种方式是使用 ```mermaid 围栏,而且仓库规则已经设定好:对于由人维护的确定性参考图,使用 Mermaid;对于配在正文旁的插图,使用图。四种形式几乎总是属于第一类,因为它们的内容是之后会有人编辑的数据集:甘特图、看板、ER 图或数据库架构图、类图。它们的行指向围栏,不需要对应的表单文件。其他情况则要判断适合哪一种。用于说明 API 规范的时序图应使用围栏;用于解释缓存为何存在的三方时序图则应使用图。
机制
| 正文内容 | 形式 | 参考 |
|---|---|---|
| 系统的组成部分,以及哪些部分彼此相连 | 谁与谁通信 | forms/what-talks-to-what.md |
| 软件的运行位置:主机、区域、副本、版本 | 部署 | forms/what-talks-to-what.md |
| 端到端的数据平台:来源、核心、使用者 | 平台集成 | forms/what-talks-to-what.md |
| 遗留系统全貌,即迁移前的状态 | 当前状态 | forms/what-talks-to-what.md |
| 带有分支的决策,即“我是否应该……” | 流程图 | forms/flowchart.md |
| 按时间顺序排列的参与者间消息、请求跟踪 | 时序图 | forms/sequence.md |
| 状态,以及事物如何在状态间转换 | 状态机 | forms/state.md |
| 按时间排列的事件:发布、里程碑、事故 | 时间线 | forms/timeline.md |
| 团队或角色之间交接的流程 | 泳道图 | forms/swimlane.md |
| 同上,并注明每个步骤的输入和产出 | 流程图 | forms/swimlane.md |
| 分层的抽象级别、技术栈、级联结构 | 层级堆栈 | forms/layers.md |
| 按质量级别划分的单个数据集存储层 | 奖章架构 | forms/layers.md |
| 按包含关系划定的范围、信任区域、影响范围 | 嵌套图 | forms/nested.md |
| 从父项到子项:分类体系、文件树 | 树形图 | forms/tree.md |
| 所有权归属、路由、升级处理 | 组织结构图 | forms/tree.md |
| 依赖关系,以及共享依赖或循环依赖 | 依赖关系图 | forms/dependency.md |
| 首尾相接的循环,且由一个中心节点保存状态 | 循环图 | forms/loop.md |
| 实体、字段、基数,或实际表和外键 | ER 图、架构图 | 一个 ```mermaid 围栏,erDiagram |
| 类、继承、组合、操作 | UML 类图 | 一个 ```mermaid 围栏,classDiagram |
| 提交、分支和合并 | Git 图 | 一个 ```mermaid 围栏,gitGraph |
| 不属于上述名称的机制 | 绘制正文所描述的内容 | 无对应文件,见下方规则 |
比较和位置
| 正文内容 | 形式 | 参考 |
|---|---|---|
| 两个坐标轴、优先级排序、2x2 矩阵 | 象限图 | forms/quadrant.md |
| 两个或三个概念的交集 | 维恩图 | forms/venn.md |
| 排名层级,或转换过程中的流失情况 | 金字塔图或漏斗图 | forms/pyramid.md |
| 价值链与各环节的商品化程度 | Wardley 地图 | forms/wardley.md |
| 按角色、按组件划分的权限 | 访问矩阵 | markdown 表格 |
工作和人员
| 正文内容 | 形式 | 参考 |
|---|---|---|
| 人员在各阶段的任务及其感受 | 用户旅程图 | forms/journey.md |
| 按发布版本切分的叙事主线 | 故事地图 | forms/story-map.md |
| 按类别归纳的某种结果成因 | 鱼骨图 | forms/fishbone.md |
| 按阶段划分的任务及其开始和结束日期 | 甘特图 | 一个 ```mermaid 围栏,gantt |
| 按状态划分的进行中工作、WIP 限额、阻塞项 | 看板 | 一个 ```mermaid 围栏,kanban |
数字
加载 dataviz 来绘制图表本身。段落中三句都在讲数字的话,
就应该用以下形式之一。普通的条形图、折线图、面积图、饼图或雷达图是
chart 技能中的 <Chart /> 块;只有当这里需要该块不支持的形式,或它无法承载的注释时,才自行绘制。
| 文本内容 | 形式 | 参考 |
|---|---|---|
| 变化的数值、各类别的数量或排名 | 条形图 | forms/bar.md |
| 每项恰好有两个数值,且差值是重点 | 哑铃图 | forms/bar.md |
| 通过带符号的步骤,从起始总量过渡到结束总量 | 瀑布图 | forms/waterfall.md |
| 随时间变化的趋势 | 折线图 | forms/line.md |
| 每项在两个时间点之间的变化 | 斜率图 | forms/line.md |
| 多个快照之间的排名变化 | 排名变化图 | forms/line.md |
| 每个系列各自的分布 | 山峦图 | forms/line.md |
| 两个变量:相关性、聚类、离群值 | 散点图 | forms/scatter.md |
| 三个变量:x、y 和一个量级 | 气泡图 | forms/scatter.md |
| 一个变量,每项对应一个点 | 蜂群图 | forms/scatter.md |
| 数量在不同阶段之间拆分并合并 | 桑基图 | forms/sankey.md |
| 整体中的一部分,且相对大小是重点 | 矩形树图 | forms/treemap.md |
| 按三到五项标准为多个事物评分 | 雷达图 | forms/radar.md |
| 一个系列跨多个类别,且类别的循环顺序很重要 | 极坐标图 | forms/radar.md |
标记
<figure className="jd-fig">
<div className="jd-fig-frame">
<svg viewBox="0 0 960 240" role="img" aria-label="One sentence describing what the figure shows">
...
</svg>
</div>
<figcaption>The takeaway.</figcaption>
</figure>
框架的 jd-fig 类负责边框、宽度、窄屏缩放,以及 <text> 的等宽字体,因此图形本身无需处理这些内容。
SVG 图形的标题不会显示在页面上。屏幕阅读器和搜索引擎会读取它;读者展开图形时,标题会显示在绘图下方。因此,图形周围的文本负责阐明重点,而标题则为只看图形的读者复述重点。HTML 图形无法展开,标题会始终显示。
规则
- 所有颜色都必须使用
var(--jd-fig-*),填充和描边都不例外。每个令牌都源自项目主题:中性色来自外壳,强调色来自primary,p、d 和 i 色调来自chart-1到chart-3。图形不得自行指定颜色。 - 这是 JSX。 属性使用驼峰命名:
fontSize、strokeWidth、strokeDasharray、textAnchor、markerEnd、letterSpacing。将&转义为&。注释写作{/* ... */}。 - 标签仍然会按 Markdown 解析。
<text>中的_category_.json会在 SVG 内渲染为<em>;浏览器会将其移出,React 会发现树与自己发送的不一致,于是丢弃页面并在客户端重新绘制。标签中的强调格式要进行转义(\_category\_、\*),或者直接去掉格式。单词前的冒号(11:04:07)也会导致同样的问题;不过框架会将这种情况恢复为文本。 - 标记 ID 在整个页面范围内唯一。 页面上的所有图形共用一个 DOM,因此每个图形中的
<marker>ID 都要加上图形专属前缀(lk-arrow、lk-arrow-accent),且不要在多个图形中重复使用arrow。 - 4px 网格。 每个 x、y、宽度、高度、半径和间距都必须是 4 的倍数。坐标以 1、2、3、5、6、7 或 9 结尾就是错误。描边宽度和字号不受此限制。
viewBox宽度为 960。 高度按绘图内容设置,不要留空。- 字号层级。 节点标签用 12(名称用
fontWeight="600"),注释和箭头标签用 10,副标签用 9.5,并设置opacity="0.75"。全大写的眉题和区段标题使用fontSize="10" letterSpacing="1.5"。不要使用writing-mode设置垂直文字;应将单词拆成多行排列。 - 强调色最多突出一项,最多两项。
--jd-fig-accent用来标示图形的重点:新增的跳转、读者应注意的状态,或正在讨论的路径。如果有四项都需要它,说明你还没决定图形的重点。其他内容使用墨色、柔和色和图层色调。
节点角色
角色由形状和描边体现。除非角色另有说明,填充保持低调。
| 角色 | 填充 | 描边 |
|---|---|---|
| 图示重点描述的一个或两个节点 | accent-soft | accent,strokeWidth="1.5" |
| 一个步骤、一项服务、一个组件 | surface | line;如果图示有分层,则使用该层的墨色(p-ink、d-ink、i-ink) |
| 一个存储、静止状态、文件、记录 | 分层时使用该层的背景色(p-bg、d-bg、i-bg),未分层时使用 line-soft | 与组件相同 |
| 不受我们控制的对象:供应商、浏览器、第三方 | surface | line-soft,标签使用 muted |
| 可选、异步、不总是存在的对象 | surface | line,strokeDasharray="4 3" |
| 区域、边界、分组 | 无 | line-soft,rx="8",眉题标签置于左上角内侧 |
节点使用 <rect rx="4">。
区域
区域用于归类共享同一层级、所有者、环境或信任边界的节点。任何形式的图示都可以使用区域,且通常会使用多个区域。
- 使用无填充、描边为
line-soft的<rect rx="8">,并在绘制其他所有内容之前绘制,这样箭头和标签就会显示在其上方。如果边界表示网络边界或信任边界,而非分组(如 VPC、安全组、环境),则使用虚线(strokeDasharray="4 4")。 - 在区域左上角内侧放置眉题标签,使用
fontSize="10" letterSpacing="1.5"和muted,标签与下方第一个节点之间留出 16px 的间距。 - 区域最多三个。超过三个就会显得像泳道,此时应改用泳道。
- 区域不是节点,也不拥有任何箭头。连接其中的节点,并由区域标签说明这些节点的共同点。
连接线
先绘制区域,再绘制箭头,然后绘制箭头标签,接着绘制节点,最后绘制节点文本。 在箭头之后绘制的方框会遮住箭头超出的部分;在节点之前绘制的标签必须放在画布的空白处,否则会被节点遮住。
每种描边颜色只定义一个标记,每个图中的标记 ID 添加对应前缀:
<marker id="lk-arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M0,0 L10,5 L0,10 z" fill="var(--jd-fig-line)" />
</marker>
| 线条 | 含义 |
|---|---|
实线 line,strokeWidth="1.5",实心箭头 | 主要流程、调用、数据流动 |
实线 accent,strokeWidth="1.5",accent 箭头 | 图中重点路径 |
虚线 muted,strokeDasharray="4 3",strokeWidth="1",实心箭头 | 返回流、次要流程、可选内容 |
虚线 muted,空心箭头(fill="none",标记中的路径带描边) | 异步、事件、单向通知 |
普通 line,无箭头 | 无方向的关系、细线 |
除文件中列明的例外(数据曲线、桑基图带、环形结构的圆环和辐条、鱼骨图的骨架、Wardley 链接)外,所有图形形式都遵循以下六条规则:
- 采用圆角直角连接线。 只有当两个点的 x 或 y 坐标相同时,才使用直线
<line>。其他情况都使用带半径为 8 的四分之一圆角的折线。从 (200,120) 到 (400,200),先向右再向下,在 x 300 处转弯:
虚线路径也采用相同的走线方式;虚线表示线条的含义,而非走线方式。<path d="M 200,120 H 292 Q 300,120 300,128 V 192 Q 300,200 308,200 H 400" fill="none" stroke="var(--jd-fig-line)" strokeWidth="1.5" markerEnd="url(#lk-arrow)" /> - 标签与描边之间留出 6 到 10px 的间距,绝不压在线上。 标签居中放在线段上方(水平线)或旁边(垂直线),最多三个词。不要使用遮挡矩形:标签应放在画布空白处;如果找不到合适的位置,说明图形超出了预算。
- 连接线之间不得共用路径。 平行线段从头到尾保持 12px 的间距。两条线必须交叉时,较不重要的一条用小弧线跨越,且只能有一条跨越。如果需要堆叠连接线,说明两个节点距离太近。
- 共用方框边缘的连接线要使用各自的连接点,第 k 个连接点在长度为 L 的边上位于
L · k / (N + 1)处,彼此间距不得小于 12px。 - 连接线不得从非起点或终点的方框后方穿过。 应重新规划走线。唯一例外是方框恰好位于唯一的直线路径上,例如页脚栏:此时线条必须使用虚线,标签放在可见端,箭头不得落在被穿过的方框上。
- 标签不得放在稍后绘制的方框会遮住的位置。 放在所属节点内部的徽标没有问题;放在区域上的标签也没有问题,因为区域会先绘制。
图表
- 绘图区位于
viewBox="0 0 960 480"内,x 坐标范围为 80 到 920,y 坐标范围为 40 到 420,为左侧的坐标轴数值和下方的类别名称留出空间。 - 使用 4 到 6 条
line-soft网格线,strokeWidth="0.8";坐标轴线使用line;坐标轴数值使用fontSize="10"和muted,并在 x 72 处右对齐;类别名称使用fontSize="12" fontWeight="600"。 - 仅一个焦点标记使用 accent。其他标记均使用
line-soft填充和muted描边。 - 标记上的数值使用
fontSize="10"。只有在相同编码重复出现时才添加图例;此时在绘图区下方放置图例条,并在上方加一条细线。 - 数量轴从零开始。图注说明标记所编码的内容,正文说明数字的来源。
HTML 图示
优先使用 SVG。只有当 SVG 不适合某类特定图示时,才考虑使用 HTML:例如需要真实的文本换行、长列表,或装饰成图示的对比表。交互内容不适合放在页面上,因为页面无法运行代码。
HTML 图示使用相同的 jd-fig / jd-fig-frame 包装器,并通过图示内部的 <style> 标签设置样式。MDX 会将 { ... } 解析为 JSX 表达式,因此 CSS 必须是模板字符串子项,否则构建会失败:
<figure className="jd-fig fig-checkout">
<style>{`
.fig-checkout .step { background: var(--jd-fig-surface); border: 1px solid var(--jd-fig-line); }
.fig-checkout .step.active { background: var(--jd-fig-d-bg); color: var(--jd-fig-d-ink); }
`}</style>
<div className="jd-fig-frame">
...
</div>
<figcaption>...</figcaption>
</figure>
- 将每个选择器嵌套在图示上唯一的
fig-*类下。像.step这样的裸类名在页面挂载期间是全局的,会重新设置主题元素的样式。 - 颜色仍然只能来自
--jd-fig-*令牌。和仓库中的其他地方一样,不要使用内联style属性。 - 这是页面中唯一允许使用局部
<style>标签的地方。绝不要将图示样式提升为新的正文块类;文章正文应使用纯 Markdown。
品味
图示应配合特定的正文内容,展示正文正在解释的事物,就像优秀的教育者在白板上作图一样。可以在图示形式上发挥创意,但不要在比喻上发挥创意:要说明段落所说的内容,以及正在发生的变化。
- 章节中的段落、代码和图示交织在一起。图示应指向周围段落中的概念。
- 每个图示只表达一个想法。通常需要图例的图示应拆成两个。
- 画出实际机制。方框代表真实组件,箭头代表真实调用或数据,并且每条箭头都要标注其传递的内容。
- 最好的做法通常是删减。两个总是同时出现的节点应合并为一个节点。布局已能清楚表达的关系不需要连线。节点超过九个时,很可能应该拆成两个图示。
- 图示中的文字少于 20 个词。细节应放在正文中;图示的作用是让人一眼看懂。
绘制前先说明计划
在回复中、SVG 的第一行之前,先用一两句话说明你选择的形式、图示的主题(需要强调的内容),以及受预算限制而无法纳入的内容。如果有人要阅读图示,他们可以用一句话的代价调整方向,而不用等到图示完成后再付出修改代价。
这样做的原因是:此时发现形式不合适,修改成本很低;等二十分钟后坐标都已排好,沉没成本会让人倾向于保留它,修改成本就很高了。只有当请求已经明确指定形式和内容时,才跳过这一步。
渲染并查看
不能仅凭 SVG 源码判断效果。渲染页面上的图示,查看图像,修正问题后再次渲染:
export AGENT_BROWSER_SESSION="$(agent-browser session id --scope worktree --prefix task)"
bun .agents/skills/figure/scripts/render.ts docs/index.mdx
它会使用项目主题渲染页面上的每个 jd-fig,分别生成深色和浅色版本,并打印 PNG 文件的路径。在页面后加上数字即可只渲染对应的图示。请在仓库根目录运行;需安装 agent-browser。使用 bun 或 node 均可运行。
完成前检查
- 图示是否包含其形式文件要求的所有内容?
- 绘制前是否说明了形式和主张?最终绘制的内容是否仍与之相符?
- 是否可以删掉某个节点、箭头或标签,而不影响图示的理解?
- 强调色是否最多用于两个元素?这些元素是否正是图示的主题?
- 每种颜色是否都使用令牌?每个属性是否都使用驼峰命名法?每个 marker 的 id 是否都有前缀?
- 每个坐标是否都落在 4px 网格上?每个连接线是否都是折线或直线?每个标签是否都避开了线条和方框?
- 是否已在两种模式下渲染并查看图像?
aria-label是否用一句话说明图示展示的内容,而没有描述图形形状?