Excalidraw 图表创建器
生成 .excalidraw JSON 文件,用于可视化论证,而非仅仅展示信息。
设置: 如果用户要求你设置此技能(渲染器、依赖等),请参阅 README.md 中的说明。
自定义
所有颜色和品牌特定样式都存在于一个文件中: references/color-palette.md。在生成任何图表之前阅读它,并将其作为所有颜色选择的唯一真实来源——包括形状填充、描边、文本颜色、证据工件背景等。
要使此技能生成符合你自己品牌风格的图表,请编辑 color-palette.md。此文件中的其他所有内容都是通用的设计方法论和 Excalidraw 最佳实践。
核心理念
图表应该进行论证,而非仅仅展示。
图表不是格式化的文本。它是一种视觉论证,展示文字 alone 无法表达的关系、因果关系和流程。形状本身就应该成为意义。
同构测试:如果移除所有文本,结构本身是否能传达概念?如果不能,请重新设计。
教育测试:有人能从这张图表中学到具体的东西吗,还是它只是在标注框?一张好的图表能够教学——它展示实际的格式、真实的事件名称、具体的例子。
深度评估(首先执行)
在设计之前,确定这张图表需要什么样的详细程度:
简单/概念性图表
在以下情况使用抽象形状:
- 解释心智模型或哲学
- 受众不需要技术细节
- 概念本身就是抽象(例如,"关注点分离")
全面/技术性图表
在以下情况使用具体例子:
- 为真实系统、协议或架构绘制图表
- 图表将用于教学或解释(例如,YouTube 视频)
- 受众需要理解事物的实际外观
- 展示多种技术如何集成
对于技术图表,你必须包含证据工件(见下文)。
研究要求(针对技术图表)
在绘制任何技术内容之前,研究实际的规范。
如果你正在为协议、API 或框架绘制图表:
- 查找实际的 JSON/数据格式
- 找到真实的事件名称、方法名称或 API 端点
- 理解各个部分实际如何连接
- 使用真实的术语,而非通用的占位符
坏的示例:"协议" → "前端" 好的示例:"AG-UI 流式传输事件(RUN_STARTED, STATE_DELTA, A2UI_UPDATE)" → "CopilotKit 通过 createA2UIMessageRenderer() 渲染"
研究使图表准确且具有教育意义。
证据工件
证据工件是具体的例子,证明你的图表是准确的,并帮助观众学习。在技术图表中包含它们。
证据工件类型(选择与你的图表相关的):
| 工件类型 | 何时使用 | 如何渲染 |
|---|---|---|
| 代码片段 | API、集成、实现细节 | 深色矩形 + 语法着色文本(参见调色板中的证据工件颜色) |
| 数据/JSON 示例 | 数据格式、模式、载荷 | 深色矩形 + 彩色文本(参见调色板) |
| 事件/步骤序列 | 协议、工作流、生命周期 | 时间线模式(线 + 点 + 标签) |
| UI 模型 | 展示实际输出/结果 | 嵌套矩形模拟真实 UI |
| 真实输入内容 | 展示进入系统的数据 | 带有可见示例内容的矩形 |
| API/方法名称 | 真实的函数调用、端点 | 使用文档中的实际名称,而非占位符 |
示例:对于关于流式协议的图表,你可以展示:
- 规范中的实际事件名称(而非只是"事件 1"、"事件 2")
- 展示如何连接的代码片段
- 流式数据的实际样子
示例:对于关于数据转换管道的图表:
- 展示示例输入数据(实际格式,而非"输入")
- 展示示例输出数据(实际格式,而非"输出")
- 如有相关,展示中间状态
关键原则:展示事物的实际样子,而非只是它们的名称。
多缩放层级架构
全面的图表同时在多个缩放层级上操作。把它想象成一张既显示国家边界又显示街道名称的地图。
层级 1:摘要流程
简化的概述,一眼展示完整的管道或流程。通常放置在图表的顶部或底部。
示例:输入 → 处理 → 输出 或 客户端 → 服务器 → 数据库
层级 2:区域边界
标记的区域将相关组件分组。这些创建视觉"房间",帮助观众理解什么属于一起。
示例:按职责分组(后端 / 前端)、按阶段分组(设置 / 执行 / 清理)或按团队分组(用户 / 系统 / 外部)
层级 3:区域内的细节
每个区域内的证据工件、代码片段和具体例子。这是教育价值所在。
示例:在"后端"区域内,你可以展示实际的 API 响应格式,而非只是一个标有"API 响应"的框
对于全面的图表, aim 包含所有三个层级。 摘要提供上下文,区域进行组织,细节进行教学。
坏与好的对比
| 坏的(展示) | 好的(论证) |
|---|---|
| 5 个带标签的等大小框 | 每个概念都有一个镜像其行为形状 |
| 卡片网格布局 | 视觉结构与概念结构匹配 |
| 装饰文本的图标 | 形状本身就是意义 |
| 所有东西都一样的容器 | 每个概念都有不同的视觉词汇 |
| 所有东西都在框里 | 自由浮动的文本与选择性容器 |
简单与全面(知道你需要哪种)
| 简单图表 | 全面图表 |
|---|---|
| 通用标签:"输入" → "处理" → "输出" | 具体:展示输入/输出实际的样子 |
| 命名框:"API"、"数据库"、"客户端" | 命名框 + 实际请求/响应的示例 |
| "事件"或"消息"标签 | 带有规范中真实事件/消息名称的时间线 |
| "UI"或"仪表板"矩形 | 显示实际 UI 元素和内容的模型 |
| ~30 秒解释 | ~2-3 分钟教学内容 |
| 观众学习结构 | 观众学习结构和细节 |
简单图表适用于抽象概念、快速概述或当受众已经知道细节时。全面图表适用于技术架构、教程、教育内容或当你希望图表本身进行教学时。
容器与自由浮动文本
不是每个文本片段都需要周围的形状。 默认使用自由浮动文本。仅在它们有目的时才添加容器。
| 使用容器当... | 使用自由浮动文本当... |
|---|---|
| 它是一个区域的焦点 | 它是一个标签或描述 |
| 它需要与其他元素进行视觉分组 | 它是支持细节或元数据 |
| 箭头需要连接到它 | 它描述附近的东西 |
| 形状本身携带意义(决策菱形等) | 排版本身创造了足够的层次结构 |
| 它代表系统中不同的"事物" | 它是区域标题、副标题或注释 |
排版作为层次结构:使用字体大小、粗细和颜色创建视觉层次,无需框。一个 28px 的标题不需要周围的矩形。
容器测试:对于每个带框的元素,问"这作为自由浮动文本能工作吗?"如果是,移除容器。
设计流程(在生成 JSON 之前执行)
步骤 0:评估所需深度
首先,确定这需要:
- 简单/概念性:抽象形状、标签、关系(心智模型、哲学)
- 全面/技术性:具体例子、代码片段、真实数据(系统、架构、教程)
如果是全面的:首先进行研究。查找实际规范、格式、事件名称、API。
步骤 1:深入理解
阅读内容。对于每个概念,问:
- 这个概念做什么?(不是它是什么)
- 概念之间存在什么关系?
- 核心转换或流程是什么?
- 有人需要看到什么才能理解这个?(而非只是阅读)
步骤 2:将概念映射到模式
对于每个概念,找到镜像其行为的视觉模式:
| 如果概念... | 使用此模式 |
|---|---|
| 产生多个输出 | 扇出(从中心辐射的箭头) |
| 将输入合并为一个 | 汇聚(漏斗、箭头合并) |
| 有层次/嵌套 | 树(线 + 自由浮动文本) |
| 是一系列步骤 | 时间线(线 + 点 + 自由浮动标签) |
| 循环或持续改进 | 螺旋/循环(返回起点的箭头) |
| 是抽象状态或上下文 | 云(重叠的椭圆) |
| 将输入转换为输出 | 流水线(之前 → 处理 → 之后) |
| 比较两件事 | 并排(平行对比) |
| 分为阶段 | 间隙/中断(区域之间的视觉分离) |
步骤 3:确保多样性
对于多概念图表:每个主要概念必须使用不同的视觉模式。不要统一卡片或网格。
步骤 4:草拟流程
在 JSON 之前,在心理上追踪眼睛如何穿过图表。应该有一个清晰的视觉故事。
步骤 5:生成 JSON
现在才创建 Excalidraw 元素。参见下文如何处理大型图表。
步骤 6:渲染与验证(强制)
生成 JSON 后,你必须运行渲染-查看-修复循环,直到图表看起来正确。这不是可选的——参见下面的渲染与验证部分了解完整流程。
大型/全面图表策略
对于全面或技术图表,你必须一次构建一个部分的 JSON。 不要试图在一次传递中生成整个文件。这是一个硬性约束——Claude Code 每次响应的输出限制约为 32,000 个 token,一个全面的图表很容易在一次传递中超过这个限制。即使没有,一次生成所有内容也会导致质量更差。分部分构建在各方面都更好。
分部分工作流程
阶段 1:构建每个部分
- 创建基础文件,包含 JSON 包装器(
type、version、appState、files)和第一部分元素。 - 每次编辑添加一个部分。 每个部分都有自己的专用传递——慢慢来。仔细考虑布局、间距,以及这个部分如何与已有的内容连接。
- 使用描述性字符串 ID(例如
"trigger_rect"、"arrow_fan_left"),使跨部分引用可读。 - 按部分命名空间种子(例如,第 1 部分使用 100xxx,第 2 部分使用 200xxx)以避免冲突。
- 更新跨部分绑定。当新部分的元素需要绑定到之前部分的元素时(例如,连接部分的箭头),同时编辑早期元素的
boundElements数组。
阶段 2:审查整体
在所有部分就位后,通读完整的 JSON 并检查:
- 跨部分箭头是否正确绑定在两端?
- 整体间距是否平衡,还是有些部分拥挤而其他部分空白太多?
- ID 和绑定是否都引用实际存在的元素?
在渲染前修复任何对齐或绑定问题。
阶段 3:渲染与验证
现在运行来自渲染与验证部分的渲染-查看-修复循环。这是你将在 JSON 中不明显的地方发现视觉问题——重叠、裁剪、不平衡的构图。
区域边界
根据图表计划中的自然视觉分组规划你的部分。一个典型的大型图表可能分为:
- 第 1 部分:入口点 / 触发器
- 第 2 部分:第一个决策或路由
- 第 3 部分:主要内容(主区域——可能是最大的单个部分)
- 第 4-N 部分:剩余阶段、输出等
每个部分应该独立可理解:它的元素、内部箭头,以及任何与相邻部分的交叉引用。
不该做什么
- 不要在一个响应中生成整个图表。 你会达到输出 token 限制并产生截断的、损坏的 JSON。即使图表足够小可以容纳,分成部分也会产生更好的结果。
- 不要使用编码代理生成 JSON。代理不会有足够的关于技能规则的上下文,协调开销抵消了任何好处。
- 不要编写 Python 生成器脚本。模板和坐标数学似乎有帮助,但引入了一层间接,使调试更难。具有描述性 ID 的手工 JSON 更易维护。
视觉模式库
扇出(一对多)
中心元素带有辐射到多个目标的箭头。用于:源、PRD、根本原因、中心枢纽。
○
↗
□ → ○
↘
○
汇聚(多对一)
多个输入通过箭头合并到单个输出。用于:聚合、漏斗、综合。
○ ↘
○ → □
○ ↗
树(层次结构)
父子分支,用连接线和自由浮动文本(不需要框)。用于:文件系统、组织架构图、分类。
label
├── label
│ ├── label
│ └── label
└── label
使用 line 元素作为树干和分支,自由浮动文本作为标签。
螺旋/循环(连续循环)
带箭头返回起点的顺序元素。用于:反馈循环、迭代过程、演进。
□ → □
↑ ↓
□ ← □
云(抽象状态)
大小各异的重叠椭圆。用于:上下文、内存、对话、心理状态。
流水线(转换)
输入 → 处理框 → 输出,有清晰的前后对比。用于:转换、处理、转换。
○○○ → [PROCESS] → □□□
chaos order
并排(比较)
两个带视觉对比的平行结构。用于:前后对比、选项、权衡。
间隙/中断(分离)
区域之间的视觉空白或障碍。用于:阶段变化、上下文重置、边界。
线条作为结构
使用线条(类型:line,不是箭头)作为主要结构元素,而非框:
- 时间线:垂直或水平线,间隔有小点(10-20px 椭圆),每个点旁边有自由浮动标签
- 树结构:垂直树干线 + 水平分支线,带自由浮动文本标签(不需要框)
- 分隔线:分隔区域的细虚线
- 流程主干:元素关联的中心线,而非连接框
时间线: 树:
●─── Label 1 │
│ ├── item
●─── Label 2 │ ├── sub
│ │ └── sub
●─── Label 3 └── item
线条 + 自由浮动文本通常比框 + 包含文本创建更干净的结果。
形状含义
根据形状代表什么来选择形状——或根本不使用形状:
| 概念类型 | 形状 | 原因 |
|---|---|---|
| 标签、描述、细节 | 无(自由浮动文本) | 排版创建层次结构 |
| 区域标题、注释 | 无(自由浮动文本) | 字体大小/粗细足够 |
| 时间线上的标记 | 小 ellipse(10-20px) |
视觉锚点,非容器 |
| 开始、触发、输入 | ellipse |
柔和,原点般 |
| 结束、输出、结果 | ellipse |
完成、目的地 |
| 决策、条件 | diamond |
经典决策符号 |
| 过程、动作、步骤 | rectangle |
包含的动作 |
| 抽象状态、上下文 | 重叠 ellipse |
模糊、云状 |
| 层次节点 | 线 + 文本(无框) | 通过线条构建结构 |
规则:默认无容器。仅当它们携带意义时才添加形状。目标 <30% 的文本元素在容器内。
颜色作为含义
颜色编码信息,而非装饰。每个颜色选择都应该来自 references/color-palette.md —— 语义形状颜色、文本层次颜色和证据工件颜色都在那里定义。
关键原则:
- 每个语义目的(开始、结束、决策、AI、错误等)都有特定的填充/描边对
- 自由浮动文本使用颜色进行层次(标题、副标题、细节——每个在不同层级)
- 证据工件(代码片段、JSON 示例)使用它们自己的深色背景 + 彩色文本方案
- 始终将较深的描边与较浅的填充配对以获得对比
不要发明新颜色。 如果一个概念不符合现有语义类别,使用 Primary/Neutral 或 Secondary。
现代美学
对于干净、专业的图表:
粗糙度
roughness: 0—— 干净、清晰的边缘。用于现代/技术图表。roughness: 1—— 手绘、有机感。用于头脑风暴/非正式图表。
默认使用 0 用于大多数专业用例。
描边宽度
strokeWidth: 1—— 细、优雅。适用于线条、分隔线、微妙的连接。strokeWidth: 2—— 标准。适用于形状和主要箭头。strokeWidth: 3—— 粗。谨慎用于强调(主线、关键连接)。
不透明度
所有元素始终使用 opacity: 100。 使用颜色、大小和描边宽度创建层次,而非透明度。
小标记替代形状
使用小点(10-20px 椭圆)作为:
- 时间线标记
- 项目符号
- 连接节点
- 自由浮动文本的视觉锚点
布局原则
通过缩放实现层次
- 主视觉:300×150 - 视觉锚点,最重要
- 主要:180×90
- 次要:120×60
- 小型:60×40
空白 = 重要性
最重要的元素周围有最多的空白(200px+)。
流向
引导眼睛:通常是左→右或上→下用于序列,径向用于中心辐射。
需要连接
位置 alone 不显示关系。如果 A 与 B 相关,必须有箭头。
文本规则
关键:JSON text 属性只包含可读的单词。
{
"id": "myElement1",
"text": "开始",
"originalText": "开始"
}
设置:fontSize: 16、fontFamily: 3、textAlign: "center"、verticalAlign: "middle"
JSON 结构
{
"type": "excalidraw",
"version": 2,
"source": "https://excalidraw.com",
"elements": [...],
"appState": {
"viewBackgroundColor": "#ffffff",
"gridSize": 20
},
"files": {}
}
元素模板
参见 references/element-templates.md 获取每种元素类型(文本、线条、点、矩形、箭头)的复制粘贴 JSON 模板。根据每个元素的语义目的从 references/color-palette.md 提取颜色。
渲染与验证(强制)
你无法仅从 JSON 判断图表。生成或编辑 Excalidraw JSON 后,你必须将其渲染为 PNG,查看图像,并修复你看到的内容——在一个循环中直到正确。这是工作流程的核心部分,而非最终检查。
如何渲染
cd .claude/skills/excalidraw-diagram/references && uv run python render_excalidraw.py <path-to-file.excalidraw>
这会在 .excalidraw 文件旁边输出一个 PNG。然后使用 Read 工具在 PNG 上实际查看它。
循环
生成初始 JSON 后,运行此循环:
1. 渲染与查看 —— 运行渲染脚本,然后读取 PNG。
2. 根据原始愿景审计 —— 在查找错误之前,将渲染结果与你在步骤 1-4 中设计的进行比较。问:
- 视觉结构是否与你计划的概念结构匹配?
- 每个部分是否使用了你预期的模式(扇出、汇聚、时间线等)?
- 眼睛是否按照你设计的顺序流经图表?
- 视觉层次是否正确——主视觉元素占主导,支持元素较小?
- 对于技术图表:证据工件(代码片段、数据示例)是否可读且放置正确?
3. 检查视觉缺陷:
- 文本被容器裁剪或溢出
- 文本或形状与其他元素重叠
- 箭头穿过元素而非绕过它们
- 箭头落在错误的元素上或指向空白空间
- 标签浮动不明确(不清楚锚定到它们描述的内容)
- 应该均匀间距的元素之间间距不均匀
- 空白太多的区域与太拥挤的区域相邻
- 文本在渲染尺寸下太小无法阅读
- 整体构图感觉倾斜或不平衡
4. 修复 —— 编辑 JSON 以解决你发现的 everything。常见修复:
- 文本裁剪时加宽容器
- 调整
x/y坐标以修复间距和对齐 - 向箭头
points数组添加中间路点以绕过元素 - 将标签重新定位到更接近它们描述的元素
- 调整元素大小以重新平衡各区域的视觉权重
5. 重新渲染与重新查看 —— 再次运行渲染脚本并读取新的 PNG。
6. 重复 —— 继续循环直到图表通过愿景检查(步骤 2)和缺陷检查(步骤 3)。通常需要 2-4 次迭代。不要在一次通过后停止,仅仅因为没有关键错误——如果构图可以更好,改进它。
何时停止
循环完成当:
- 渲染图表与计划步骤中的概念设计匹配
- 没有文本被裁剪、重叠或无法阅读
- 箭头路由干净并连接到正确的元素
- 间距一致且构图平衡
- 你会放心地把它展示给某人,无需免责声明
首次设置
如果渲染脚本尚未设置:
cd .claude/skills/excalidraw-diagram/references
uv sync
uv run playwright install chromium
质量检查清单
深度与证据(首先检查技术图表)
- 已完成研究:你是否查找了实际规范、格式、事件名称?
- 证据工件:是否有代码片段、JSON 示例或真实数据?
- 多缩放:是否有摘要流程 + 区域边界 + 细节?
- 具体而非抽象:展示的是真实内容,而非只是带标签的框?
- 教育价值:有人能从中学到具体的东西吗?
概念性
- 同构:每个视觉结构是否镜像其概念的行为?
- 论证:图表是否展示了文本 alone 无法展示的东西?
- 多样性:每个主要概念是否使用不同的视觉模式?
- 无统一容器:避免了卡片网格和等大小框?
容器规范
- 最小容器:任何带框的元素能否作为自由浮动文本工作?
- 线条作为结构:树/时间线模式是否使用线条 + 文本而非框?
- 排版层次:字体大小和颜色是否创建视觉层次(减少对框的需求)?
结构性
- 连接:每个关系都有箭头或线条
- 流程:眼睛跟随的清晰视觉路径
- 层次:重要元素更大/更孤立
技术性
- 文本干净:
text只包含可读的单词 - 字体:
fontFamily: 3 - 粗糙度:
roughness: 0用于干净/现代(除非请求手绘风格) - 不透明度:所有元素
opacity: 100(无透明度) - 容器比例:<30% 的文本元素应该在容器内
视觉验证(需要渲染)
- 渲染为 PNG:图表已被渲染并视觉检查
- 无文本溢出:所有文本都适合其容器
- 无重叠元素:形状和文本不意外重叠
- 均匀间距:相似元素有一致间距
- 箭头着陆正确:箭头连接到预期元素而不交叉其他元素
- 在导出尺寸下可读:文本在渲染的 PNG 中清晰可读
- 平衡构图:没有大的空白或过度拥挤的区域