关于 tldraw-skill
tldraw-skill 用于生成白板风格图表,以 .tldr JSON 文件保存,并通过 @kitschpatrol/tldraw-cli 导出为 PNG 或 SVG。它适合系统和流程可视化,图表由手动定位的形状与连线构成。
主要功能
- 01生成 .tldr JSON 图表
- 02导出 PNG 和 SVG 文件
- 03使用形状与箭头构建图表
- 04检查导出图像的布局问题
- 05通过定点编辑修改图表
适用场景
- 01可视化多步骤流程和数据流
- 02展示服务或模块之间的关系
- 03绘制架构图和决策树
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ agents365-ai/ tldraw-skill --skill tldraw-skill安装后在 Claude Code 中输入/tldraw-skill确认已加载。
详细介绍
tldraw 白板图表
概述
生成现代白板风格的图表,保存为 .tldr JSON 文件,并使用 @kitschpatrol/tldraw-cli 导出为 PNG/SVG。tldraw 可生成简洁的手绘风格图表,提供丰富的形状库和流畅的箭头路径,非常适合休闲或白板风格的可视化内容。
格式: .tldr JSON
导出: PNG、SVG(通过 @kitschpatrol/tldraw-cli)
风格: 默认采用手绘白板风格;可通过 font 属性切换为简洁字体。
适用场景
明确触发条件: 用户提到“图表”“流程图”“绘制”“可视化”“白板图表”“tldraw 图表”“架构图”或“画个草图”。
主动触发条件:
- 解释包含 3 个或更多相互作用组件的系统
- 描述多步骤流程、数据流或管道
- 展示服务/模块之间的关系
- 架构概览、时序流程、决策树、ML 模型层
跳过场景: 简单列表或表格即可满足需求;用户需要精致的商务演示图表(优先使用 drawio-skill);或用户正在进行快速问答。
不适用场景——转用其他工具:
- Logo / 纯色图形 / 实心图标:tldraw 不支持不透明填充(
solid= 浅色调;无法复现深色背景上的白色图形)→ 使用 drawio 技能或原始矢量文件。 - 精确矢量几何图形或严格的(空心箭头)UML → 使用 drawio(或使用 plantuml 绘制 UML)。
- 对大量节点进行自动布局 → 使用 mermaid(tldraw 需要手动设置坐标)。
- 忠实复刻现有图片的像素级副本 → 这不是图表技能的任务。
前置条件
# Install tldraw-cli
npm install -g @kitschpatrol/tldraw-cli
# Verify
tldraw --version
在 macOS、Windows 和 Linux 上的使用方式完全相同。
首次导出说明: tldraw export 通过 puppeteer 使用固定版本的 Chrome 进行渲染。首次导出可能会失败,并提示 Could not find Chrome (ver. <x>)。错误信息会指出所需的确切版本——安装一次后即可正常导出:
# The error message names the version; substitute it here
npx puppeteer browsers install chrome@<version-from-error>
(安装到 ~/.cache/puppeteer;每个 CLI 版本只需安装一次。)
工作流
开始前,先判断用户的请求是否足够具体。如果缺少关键信息,请提出 1 到 3 个有针对性的问题:
- 图表类型 — 使用哪种预设?(架构图、流程图、时序图、ML/DL、ERD、UML 或通用图表)
- 输出格式 — PNG(默认)还是 SVG?
- 输出位置 — 默认是用户的工作目录;如果用户指定了路径(例如“放到
./artifacts/”),请遵照执行。用户未提及时无需询问。 - 范围/保真度 — 有多少个组件?是否需要指定技术或标签?
如果请求已明确说明这些细节,或内容显然很简单(例如“画一张 X 的流程图”),则跳过澄清。
- 检查依赖项 — 确认
tldraw --version能正常运行;如果缺少依赖项,运行npm install -g @kitschpatrol/tldraw-cli。 - 规划 — 确定形状(每个节点的几何类型)、连接(包含源/目标的箭头)和布局(TB 或 LR,按层级/角色分组)。编写 JSON 前先绘制坐标网格草图。
- 生成 — 编写
.tldrJSON 文件。默认输出目录为用户的工作目录;如果用户指定了路径或目录(例如./artifacts/),先运行mkdir -p创建目录,再将文件写入其中。步骤 4 和 7 中导出的 PNG/SVG 也使用同一目录。 - 导出草稿 — 运行 CLI,生成 PNG 供预览。
- 自检 — 使用 Agent 内置的视觉能力查看导出的 PNG,发现明显问题并在展示给用户前自动修复(需要支持视觉能力的模型,例如 Claude Sonnet/Opus)。如果无法使用视觉能力,则跳过此步骤。
- 审阅循环 — 向用户展示图片、收集反馈、针对性地修改 JSON、重新导出,然后重复此流程,直到用户确认。
- 最终导出 — 将获批版本导出为所有要求的格式;报告
.tldr源文件和导出图像的文件路径。
步骤 5:自检
导出草稿 PNG 后,使用 Agent 的视觉能力(例如 Claude 的图像输入)读取图像,并在展示给用户前检查以下问题。如果 Agent 不支持视觉能力,则跳过自检,直接展示 PNG。
tldraw 自带的 AI Agent 会标记恰好三种结构缺陷——文本溢出(框太小,容不下标签)、文本重叠以及孤立箭头(箭头有一端未绑定)。下表的前三行针对这些问题;提前正确设置框的尺寸(参见“按标签调整框的尺寸”),这些问题就很少发生。
| 检查项 | 检查内容 | 自动修复操作 |
|---|---|---|
| 文本溢出 | 标签超出形状边框,或框看起来比设定的更高(tldraw 会自动扩大尺寸不足的框) | 增大 w/h 以适应标签——参见下方的尺寸计算公式 |
| 文本重叠 | 两个包含文本的形状,其标签相触或重叠,影响可读性 | 将形状彼此移开 ≥200px |
| 孤立箭头 | 箭头有一端未连接到形状(悬空) | 绑定两端:每个箭头的 start 和 end 都需要一个与现有形状匹配的 boundShapeId |
| 画布外形状 | 形状位于负坐标处,或远离主要分组 | 将其移至正坐标处的邻近区域 |
| 箭头与形状重叠 | 箭头在视觉上穿过无关形状 | 调整 bend 值,或将端点移至不同的 normalizedAnchor 侧 |
| 箭头堆叠 | 多个箭头在同一路径上相互重叠 | 沿形状周边分布 normalizedAnchor(使用不同的 x/y 值) |
- 最多进行 2 轮自检——若修复 2 次后仍有问题,也要展示给用户。
- 每次修复后都重新导出并重新读取 PNG。
步骤 6:审核循环
自检后,展示导出的图像并征求用户反馈。
针对性编辑规则——对于每种反馈,应用最小限度的 JSON 修改:
| 用户请求 | JSON 编辑操作 |
|---|---|
| 更改 X 的颜色 | 查找 props.text 与 X 匹配的形状,并更新 props.color |
| 添加新节点 | 添加一条新的形状记录,使用下一个可用索引,并将其放置在相关节点附近 |
| 删除节点 | 删除该形状记录以及绑定到它的所有箭头记录 |
| 移动形状 X | 更新该形状的 x/y 字段 |
| 调整形状 X 的大小 | 更新 props.w/props.h |
| 添加从 A 指向 B 的箭头 | 添加一条新的箭头记录,将其绑定到 A 和 B 的形状 ID |
| 更改标签文本 | 更新匹配形状或箭头的 props.text |
| 更改布局方向 | 完整重新生成——重新规划网格并重建 |
规则:
- 对于单个元素的更改:直接编辑现有 JSON——保留之前迭代中的布局调整。
- 对于影响整体布局的更改(例如,将 LR↔TB 对调、“重新开始”):重新生成完整 JSON。
- 每次迭代都覆盖同一个
{name}.png——不要创建v1、v2、v3文件。 - 应用编辑后,重新导出并展示更新后的图像。
- 循环持续进行,直到用户表示已批准 / 完成 / LGTM。
- **安全措施:**经过 5 轮迭代后,建议用户在 tldraw.com 或桌面应用中打开
.tldr文件进行精细调整。
文件格式
完整的 .tldr 骨架
{
"tldrawFileFormatVersion": 1,
"schema": {
"schemaVersion": 1,
"storeVersion": 4,
"recordVersions": {
"asset": {"version": 1, "subTypeKey": "type", "subTypeVersions": {"image": 2, "video": 2, "bookmark": 0}},
"camera": {"version": 1},
"document": {"version": 2},
"instance": {"version": 17},
"instance_page_state": {"version": 3},
"page": {"version": 1},
"shape": {"version": 3, "subTypeKey": "type", "subTypeVersions": {"group": 0, "embed": 4, "bookmark": 1, "image": 2, "text": 1, "draw": 1, "geo": 7, "line": 0, "note": 4, "frame": 0, "arrow": 1, "highlight": 0, "video": 1}},
"instance_presence": {"version": 4},
"pointer": {"version": 1}
}
},
"records": [
{"id": "document:document", "typeName": "document", "gridSize": 10, "name": "", "meta": {}},
{"id": "page:page1", "typeName": "page", "name": "Page 1", "index": "a1", "meta": {}}
/* shapes and arrows go here */
]
}
关键规则:
document:document和page:page1记录始终必需。- 所有形状都放在页面记录之后的
records数组中。 - 所有形状的
"parentId": "page:page1"。 - 形状 ID 使用
"shape:xxx"格式,并带有唯一后缀(例如"shape:s1"、"shape:a1")。 index值是分数索引键。使用"a"+ 一个 base-62 字符,按顺序为"a0"–"a9"、"aA"–"aZ",然后是"aa"–"az"(62 个有序键,足以满足任何常规图表的需求)。- **不要追加第二个字符:
"a10"无效。**也不要使用以"b"/"c"开头的键("b1"、"c1"、"b0")——这些会编码更长的整数部分,因此属于格式错误的分数键,并会触发invalidRecords。请使用上述单字符"a*"键。
Geo 形状记录
{
"id": "shape:s1",
"typeName": "shape",
"type": "geo",
"parentId": "page:page1",
"index": "a1",
"x": 100,
"y": 100,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"props": {
"w": 180,
"h": 60,
"geo": "rectangle",
"color": "blue",
"labelColor": "black",
"fill": "semi",
"dash": "draw",
"size": "m",
"font": "draw",
"text": "API Gateway",
"align": "middle",
"verticalAlign": "middle",
"growY": 0,
"url": ""
}
}
Geo 类型
geo 值 | 用途 |
|---|---|
rectangle | 服务、模块、组件 |
ellipse | 数据库、起始/结束节点 |
oval | 胶囊形起始/结束终止符(流程图) |
diamond | 决策点 |
cloud | 外部服务、基础设施 |
hexagon | 事件中心、消息总线 |
triangle | 网关、负载均衡器 |
star | 突出显示、关键功能 |
pentagon | 阶段、里程碑 |
octagon | 停止/终止/阻塞状态 |
trapezoid | 手动操作、转换 |
rhombus / rhombus-2 | 平行四边形——输入/输出步骤(向左/向右倾斜) |
arrow-right / arrow-left / arrow-up / arrow-down | 定向流程块、数据移动 |
x-box | 失败/无效/拒绝状态(带 ✕ 的方框) |
check-box | 通过/已验证/完成状态(带 ✓ 的方框) |
heart | 点缀(技术图表中很少需要) |
所有 20 个 geo 值均有效;以上是适用于技术图表的实用子集。
颜色调色板
color | 用途 |
|---|---|
blue | 客户端、核心服务 |
green | 成功、数据库、存储 |
orange | 队列、事件总线、警告 |
red | 外部 API、错误、警报 |
light-red | 柔和警报、次要警告 |
violet | 网关、安全、身份验证 |
yellow | 决策、缓存 |
grey | 中性、背景、遗留系统 |
light-blue | 次要服务、元数据 |
light-violet | 柔和的身份验证/安全、次要网关 |
light-green | 柔和成功、次要存储 |
white | 空白/空节点、占位符(搭配 fill: solid 使用) |
black | 标题、强调 |
完整调色板(13 种):black、grey、light-violet、violet、blue、light-blue、yellow、orange、green、light-green、light-red、red、white。
样式选项
| 属性 | 值 | 说明 |
|---|---|---|
fill | semi、solid、none、pattern | semi = 染色填充(推荐) |
dash | draw、solid、dashed、dotted | draw = 默认手绘样式 |
size | s、m、l、xl | m = 默认值 |
font | draw、sans、serif、mono | draw = 默认白板样式 |
箭头记录
{
"id": "shape:a1",
"typeName": "shape",
"type": "arrow",
"parentId": "page:page1",
"index": "aG",
"x": 0,
"y": 0,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"props": {
"dash": "draw",
"size": "m",
"fill": "none",
"color": "black",
"labelColor": "black",
"bend": 0,
"start": {
"type": "binding",
"boundShapeId": "shape:s1",
"normalizedAnchor": {"x": 0.5, "y": 1},
"isExact": false
},
"end": {
"type": "binding",
"boundShapeId": "shape:s2",
"normalizedAnchor": {"x": 0.5, "y": 0},
"isExact": false
},
"arrowheadStart": "none",
"arrowheadEnd": "arrow",
"text": "",
"font": "draw"
}
}
箭头连接规则
- 箭头记录的
x和y始终为0, 0。 - 使用
"type": "binding"和boundShapeId连接到特定形状。 normalizedAnchor指定箭头连接到目标形状的哪个位置(取值范围为 0–1):{x: 0.5, y: 0}= 顶部中央{x: 0.5, y: 1}= 底部中央{x: 0, y: 0.5}= 左侧中央{x: 1, y: 0.5}= 右侧中央{x: 0.5, y: 0.5}= 中央
- 在箭头属性中添加
"text": "label",为连接添加标签。 - 使用
"bend": 20(或-20)绘制轻微弯曲,以避免与其他箭头重叠。 - 对于虚线/点线箭头(例如异步流程、可选链接),设置
"dash": "dashed"或"dotted"。 - 设置
"spline": "cubic"可绘制平滑曲线箭头(默认"line"为直线/折线)。适用于跳过连接和回边。
箭头
arrowheadStart 和 arrowheadEnd 均接受以下 9 个值(全部可在 @kitschpatrol/tldraw-cli 中渲染):
| 值 | 外观 | 用途 |
|---|---|---|
none | (无箭头) | 单向箭头的起点 |
arrow | 开口 V 形 | 默认流向 |
triangle | 实心 ▶ | UML 继承 /“是一个” |
diamond | 实心 ◆ | UML 组合 / 聚合(在所有者一端) |
dot | ● | 序列图消息端点 |
square | ■ | 终端 / 固定端点 |
bar | | | “停止”/ 边界标记 |
pipe | || | 备用边界标记 |
inverted | 空心 V 形 | 弱化方向 |
默认箭头使用 "arrowheadStart": "none"、"arrowheadEnd": "arrow"。双向连接请将两端都设为 "arrow"。
在形状上分布箭头
当多个箭头连接到同一形状时,分配不同的 normalizedAnchor 点以避免堆叠:
| 位置 | x | y | 使用场景 |
|---|---|---|---|
| 顶部中心 | 0.5 | 0 | 连接到上方节点 |
| 左上 | 0.25 | 0 | 从顶部起的第 2 个连接 |
| 右上 | 0.75 | 0 | 从顶部起的第 3 个连接 |
| 右侧中心 | 1 | 0.5 | 连接到右侧节点 |
| 底部中心 | 0.5 | 1 | 连接到下方节点 |
| 左侧中心 | 0 | 0.5 | 连接到左侧节点 |
规则: 如果形状的一侧有 N 个连接,请将它们均匀分布(例如,底部有 3 个连接 → x = 0.25、0.5、0.75)。
同一对节点之间的多个箭头
上面的锚点分布规则适用于指向不同节点的箭头。当 N 个箭头连接同一对节点(例如,双向请求/响应,或 A↔B 之间存在多种关系)时,锚点无法将它们分开——应改为对称分布 bend 值,让箭头展开成不同的弧线:
- 选择最大弯曲值
amount(约为 30–60;节点相距越远,值越大)。 - 将 N 个箭头的弯曲值均匀分布在
−amount到+amount之间:- 2 个箭头 →
bend: -amount、bend: +amount - 3 个箭头 →
bend: -amount、0、+amount - 通用公式:
bend[i] = -amount + i * (2*amount / (N-1)),其中i = 0..N-1
- 2 个箭头 →
- 对于请求/响应这一对,一条直箭头加一条弯曲箭头(
bend: 0和bend: 40)看起来清晰简洁。
容器与注释形状
除了 geo 和 arrow,还有两种形状类型适用于技术图表。
Frame(带标签的容器 — 层级、子系统、泳道)
frame 是一种带标题的原生矩形容器。可用它为层级或子系统分组并显示边界;堆叠多个 frame 可模拟泳道。
{
"id": "shape:frame1", "typeName": "shape", "type": "frame",
"parentId": "page:page1", "index": "a1",
"x": 60, "y": 60, "rotation": 0, "isLocked": false, "opacity": 1, "meta": {},
"props": { "w": 360, "h": 220, "name": "Backend Tier", "color": "black" }
}
props.name是显示在 frame 左上角的标题。- 子形状设置
"parentId": "shape:frame1"(而非page:page1),其x/y相对于 frame 的左上角,而不是页面。子形状位于x: 40, y: 60时,表示从 frame 的原点向右 40px、向下 60px。 - Frame 会渲染为简洁的(非手绘风格)矩形,适合用于结构分组。箭头仍可正常跨 frame 绑定。
Note(便笺式注释 / 标注)
note 是一张便笺,适合用于 TODO、标注和叠加在图表上的评论。
{
"id": "shape:n1", "typeName": "shape", "type": "note",
"parentId": "page:page1", "index": "a4",
"x": 480, "y": 80, "rotation": 0, "isLocked": false, "opacity": 1, "meta": {},
"props": { "color": "yellow", "size": "m", "text": "TODO: add retry\nlogic here",
"font": "draw", "align": "middle", "verticalAlign": "middle",
"growY": 0, "fontSizeAdjustment": 0, "url": "", "scale": 1, "labelColor": "black" }
}
- Note 没有
w/h——它是固定大小的正方形(约 200px),文本较长时会自动增高。不要添加w/h。 yellow是经典便笺颜色;也可以使用调色板中的任意颜色。- 谨慎使用 note——用于添加关于图表的注释,而非作为主要节点(主要节点请使用
geo)。
索引排序规则
索引控制 z 轴顺序(堆叠顺序)。请按以下顺序设置:
a1, a2, a3, a4, a5, a6, a7, a8, a9,
aA, aB, aC, aD, aE, aF, aG, aH, aI, aJ, aK, aL, aM,
aN, aO, aP, aQ, aR, aS, aT, aU, aV, aW, aX, aY, aZ,
aa, ab, ac, ... az ← continue here past aZ; never "a10"
- Geo 形状在前:
a1到aF(或按需使用更多索引)。 - Arrow 形状在后:
aG、aH等。 - 每个形状都必须使用唯一索引。
布局提示
间距——根据复杂度调整:
| 图表复杂度 | 节点数 | 水平间距 | 垂直间距 |
|---|---|---|---|
| 简单 | ≤5 | 200px | 150px |
| 中等 | 6–10 | 280px | 200px |
| 复杂 | >10 | 350px | 250px |
调整框的大小以适应标签(预先完成,而不是在自检时调整):draw 字体较宽。根据标签计算 w/h,确保文字不会被截断。默认 draw 字体的每字符宽度和行高近似值:
size | 字符宽度(px) | 行高(px) |
|---|---|---|
s | 11 | 18 |
m(默认) | 15 | 28 |
l | 22 | 40 |
xl | 32 | 56 |
每侧设置 padding = 16:
w = ceil(最长一行的字符数 * 字符宽度 + 2*padding),然后向上取整到 10 的倍数。h = ceil(行数 * 行高 + 2*padding),然后向上取整到 10 的倍数。
示例:标有 "API Gateway" 的 size-m 框(11 个字符,1 行)→ w ≈ 11*15 + 32 = 197 → 200,h ≈ 28 + 32 = 60。多行标签(包含 \n)计算 w 时取最长一行,计算 h 时取行数。尺寸略大更好——额外留白看起来没问题,太窄的框则会在单词中间换行。
这样做很重要的原因:如果框的高度不足以容纳其中的文字,tldraw 会在渲染时静默地将其增高(它会设置形状的 growY),因此最终框的高度会大于你写下的 h,并与下方放置的元素重叠。预先正确设置尺寸可使 growY 保持为 0,让布局不变。这是导出后“图表看起来很拥挤/框互相重叠”最常见的原因。
**路由通道:**在形状的行/列之间额外留出约 80px 的空白通道,让箭头可以通过而不与其他形状交叉。箭头需要经过的间隙中绝不要放置形状。
**网格对齐:**将所有 x、y、w、h 值对齐到 10 的倍数——这与 tldraw 的默认值 gridSize: 10 相匹配,也便于手动编辑。
通用规则:
- 分配 x/y 坐标前先规划网格——先在脑中勾勒节点位置。
- 将相关节点放在同一水平或垂直带内。
- 将连接密集的“枢纽”节点放在中央,让箭头向外辐射,而不是彼此交叉。
- 对于较宽的形状(例如跨越多个下游服务的 API Gateway),将
w设为覆盖整个跨度。 - 将子节点居中对齐在父节点下方(中心 x 坐标相同),避免箭头沿对角线连接。
- 事件总线模式:将总线(六边形)放在服务行的中央,而不是下方——两侧的服务通过短水平箭头连接到总线(左侧
normalizedAnchor.x = 1,右侧0),从而消除交叉。 - 水平连接不会与同一行中的垂直节点交叉;将其用于对等连接和发布连接。
避免箭头与形状重叠:
- 确定坐标前,先在脑中描绘每条箭头路径——如果路径必须穿过无关形状,就移动该形状或使用
bend绕行。 - 对于树形/分层布局:将节点分配到各层(行),只在相邻层之间连接,以尽量减少交叉。
- 对于星形/枢纽布局:将枢纽放在中心,卫星节点分布在周围——箭头保持短小并呈放射状。
图表类型预设
当用户要求特定图表类型时,应用下方匹配的预设,遵循其中的形状、颜色和布局惯例。
架构图
| 元素 | geo | color | 说明 |
|---|---|---|---|
| 客户端(Web/移动端) | rectangle | blue | 顶部行,按客户端类型标注 |
| 服务 / 模块 | rectangle | blue | 中间各行,按层级分组 |
| 数据库 | ellipse | green | 底部行,每个服务对应一个 |
| 缓存 | ellipse | yellow | 位于所属服务旁边 |
| 队列 / 事件总线 | hexagon | orange | 对于中心枢纽模式,位于服务行的中央 |
| 网关 / 负载均衡器 | triangle | violet | 位于服务上方 |
| 外部 API | cloud | red | 位于画布边缘,使用虚线箭头指向内部 |
| 身份验证 / 安全 | rectangle | violet | 通常位于网关附近 |
布局: 根据层级数量选择 TB 或 LR;层级数 ≥4 时使用 TB。枢纽节点居中。间距随复杂度调整(参见上表)。
流程图
| 元素 | geo | color | 说明 |
|---|---|---|---|
| 开始 / 结束 | ellipse | green | 始终位于顶部和底部 |
| 处理步骤 | rectangle | blue | 默认操作框 |
| 判断 | diamond | yellow | 始终为出向箭头添加标签(是 / 否) |
| 输入 / 输出 | rectangle(带 dash: dashed) | orange | 使用虚线边框与处理步骤区分 |
| 子流程 | rectangle | violet | 表示可调用的子流程 |
布局: 使用 TB,垂直间距约为 200px。判断分支向左 / 右延伸,然后合并回中央。始终在箭头的 props.text 中标注判断分支。
序列图
tldraw 没有原生生命线形状。可使用以下元素近似表示:
| 元素 | geo | color | 说明 |
|---|---|---|---|
| 参与者 / 对象标题 | rectangle | blue | 位于列顶部 |
| 生命线 | rectangle(w: 2、fill: solid、color: grey) | grey | 位于每个参与者标题下方的细垂直线 |
| 同步消息 | 带有 arrowheadEnd: arrow 的箭头 | black | 实线水平箭头 |
| 异步消息 | 带有 dash: dashed 的箭头 | black | 虚线水平箭头 |
| 返回消息 | 带有 dash: dashed、color: grey 的箭头 | grey | 灰色虚线 |
布局: 参与者沿 LR 方向排列(间距为 200–280px),时间沿 TB 方向推进。每条消息都是两条生命线之间的水平箭头,y 值逐渐增加。
ML / 深度学习模型图
用于绘制神经网络架构图,适合论文插图和讲解材料。
| 元素 | geo | color | 说明 |
|---|---|---|---|
| 输入 / 输出 | rectangle | green | 位于堆栈顶部和底部 |
| 卷积 / 池化 | rectangle | blue | 标准层模块 |
| Attention / Transformer | rectangle | violet | 使用区别明显的颜色表示自注意力模块 |
| RNN / LSTM / GRU | rectangle | yellow | 循环层 |
| 全连接 / 线性层 | rectangle | orange | 稠密投影层 |
| 损失 / 激活 | rectangle | red | 最终损失 / softmax / 激活函数 |
| 跳跃连接 | 带有 bend: 30、dash: dashed 的箭头 | grey | 弯曲的虚线旁路 |
张量形状标注: 在 props.text 中的第二行包含各维度。tldraw 会在 JSON 字符串中按字面渲染 \n,因此请使用实际换行符(JSON 编码器会写入 \n):
"text": "Conv2D\n(B, 64, 32, 32)"
布局: 使用 TB(数据从上到下流动),层间距约为 150px。跳跃连接沿主堆栈外围弯曲。
ER 图(ERD)
tldraw 没有原生的表格/行形状。可将每个实体近似为一个带多行文本的高矩形。
| 元素 | geo | color | 备注 |
|---|---|---|---|
| 实体 | rectangle(fill: solid,color: light-blue) | light-blue | 标题和列作为一个多行文本标签 |
| 列表 | 嵌入 props.text,行之间用 \n 分隔 | — | PK 前缀标记为 *,FK 前缀标记为 > |
| 关系 | 两端带箭头的箭头,arrowheadStart: arrow,arrowheadEnd: arrow | black | 多对多关系的两端都带箭头 |
| 可选/弱关系 | 带 dash: dashed 的箭头 | grey | 可选 FK 使用虚线 |
通过 props.text 为箭头标注基数(例如 1..*、0..1)。
布局: TB 或网格;实体间距至少为 300px,为列列表留出空间。
UML 类图
| 元素 | geo | color | 备注 |
|---|---|---|---|
| 类 | rectangle(fill: solid,color: light-blue) | light-blue | 标题、属性和方法作为一个多行 text |
| 继承 | 带 arrowheadEnd: triangle 的箭头 | black | tldraw 会渲染实心的 triangle 箭头,将其指向父类 |
| 组合 | 带 arrowheadStart: diamond、arrowheadEnd: none 的箭头 | black | tldraw 会渲染实心的 diamond 箭头,将其放在所有者(整体)一端 |
| 聚合 | 带 arrowheadStart: diamond 的箭头 | black | 同样是菱形箭头;通过标签或备注与组合区分 |
| 关联 | 带 arrowheadEnd: arrow 的箭头 | black | 标准箭头 |
注意: tldraw 的 triangle/diamond 箭头是实心的,而严格的 UML 使用空心三角形(继承)以及实心或空心菱形(组合/聚合)。这些形状适用于草图和说明图;若要绘制出版级 UML 空心箭头,drawio-skill(独立技能)更合适。
布局: TB,类间距约为 250px,接口置于实现类上方。
导出命令
# Check CLI version
tldraw --version
# PNG at 2x scale (recommended) — outputs diagram.png in ./
tldraw export diagram.tldr -f png --scale 2 -o ./
# SVG — outputs diagram.svg in ./
tldraw export diagram.tldr -f svg -o ./
# Transparent background
tldraw export diagram.tldr -f png --scale 2 --transparent -o ./
# Dark theme
tldraw export diagram.tldr -f png --scale 2 --dark -o ./
# Custom output directory (e.g. CI artifacts dir) — create if missing, then export there
mkdir -p ./artifacts && tldraw export diagram.tldr -f png --scale 2 -o ./artifacts/
注意: -o 是输出目录,不是文件路径。输出文件以输入文件命名(diagram.tldr → diagram.png)。
导出后自动启动
建议在用户默认的 tldraw 查看器/编辑器中打开 .tldr 文件:
| 操作系统 | 命令 |
|---|---|
| macOS | open diagram.tldr |
| Linux | xdg-open diagram.tldr |
| Windows | start diagram.tldr |
或者上传到 https://tldraw.com(将 .tldr 文件拖放到页面中),以便在浏览器中编辑。
常见错误
| 错误 | 修复方法 |
|---|---|
找不到 tldraw 命令 | 运行 npm install -g @kitschpatrol/tldraw-cli |
导出时出现 Could not find Chrome (ver. X) | 安装指定版本:npx puppeteer browsers install chrome@X(使用错误信息中的确切版本) |
导出时出现 invalidRecords | 使用单字符 a 键(a1…a9、aA…aZ、aa…az);a10、b1、c1 是格式错误的分数索引键 |
| 导出结果空白/为空 | 确认存在 document:document 和 page:page1 记录 |
| 找不到输出文件 | -o 是目录;文件名与输入文件相同:tldraw export foo.tldr -o ./ → ./foo.png |
| 箭头未显示 | 使用 "type": "binding" 和 boundShapeId;将箭头的 x/y 设为 0,0 |
| 形状重叠 | 分配 x/y 前规划一个间距至少为 200px 的网格;根据复杂程度调整间距 |
| 方框比预期高/与下方内容碰撞 | 标签溢出过小的方框,因此 tldraw 自动增高了方框(growY)。根据尺寸公式预先设置 w/h,使其适应标签 |
| 文本不可见 | 检查是否设置了 props.text;如果 fill: "none",确保文本颜色有足够对比度 |
| 索引冲突 | 所有形状的 index 值都必须唯一 |
| 形状 ID 冲突 | 使用唯一 ID:"shape:s1"、"shape:s2"、"shape:a1" 等 |
| 导出失败 | 确保 .tldr 文件是有效的 JSON:python3 -m json.tool file.tldr > /dev/null |
| 多行标签 | 在 JSON 字符串中使用真实的换行符("text": "Line1\nLine2");tldraw 会保留 \n |
| 箭头穿过形状 | 使用 bend 绕开形状弯曲箭头,或将端点移至不同的 normalizedAnchor |
| 迭代循环无法结束 | 进行 5 轮后,建议用户在 tldraw.com 中打开 .tldr 进行微调 |
后备方案
工具不可用时,优雅地降级:
| 场景 | 处理方式 |
|---|---|
缺少 tldraw-cli | 仅生成 .tldr JSON;指导用户将其拖放到 https://tldraw.com,或安装 CLI |
| 无法使用视觉功能进行自检 | 跳过自检(步骤 5);直接向用户展示导出的 PNG |
| 导出失败 | 使用 python3 -m json.tool 验证 JSON;交付 .tldr 文件并建议在 tldraw.com 中打开 |