PicoBot/.qoder/skills/lark-slides/references/lark-slides-whiteboard.md
ooodc a7883dbed9 refactor(todo): 重构待办事项管理逻辑及更新状态规则
- 移除 TodoItem 中的 priority、created_at 和 updated_at 字段
- 强制每个任务都必须有唯一 id,且由用户负责生成
- 修改合并模式逻辑,merge=true 下保留未提及的旧任务
- 支持已完成和已取消任务重新激活(状态改回 pending 或 in_progress)
- 禁止 in_progress 状态退回到 pending,必须标记为 completed 或 cancelled
- 优化状态转换校验,允许特定状态间合法切换
- 简化任务变更消息,移除详细的新增/更新/移除统计
- 更新文档和示例,明确 id 必须由用户生成和使用
- 修复和补充测试,增强状态转换和合并模式验证
- 调整任务时间戳生成逻辑,统一使用当前时间及索引
- 该变更提供更合理的任务状态机械及管理模式,提升稳定性和易用性
2026-06-13 09:22:33 +08:00

13 KiB
Raw Blame History

Whiteboard 画板元素

<whiteboard> 放在 <data> 内,内部可放 SVGMermaid,用于绘制流程图、时序图、架构图、散点图、漏斗图、自定义图标、装饰图案等 <chart><shape> 难以覆盖的视觉内容。

前置条件:使用本文档前先阅读 lark-slides SKILL.md


<chart> 还是 <whiteboard>

先判断内容类型,再进入本文档:

场景 推荐元素
有结构化数据序列的柱/条/折线/面积/雷达/饼/组合图 <chart> — 原生渲染,支持 legend / tooltip / 系列配色
散点图、漏斗图(<chart> 不支持) <whiteboard> SVG
流程图、时序图、架构图、类图、ER 图等拓扑图 <whiteboard> Mermaid 或 SVG
自定义图标、徽标、示意性图形(需要 path/polygon 精确控制) <whiteboard> SVG
进度条、波浪背景、装饰图案、像素级自定义可视化 <whiteboard> SVG

适合 <chart> 的内容就用 <chart>,不要用 SVG 手绘——原生渲染更省力且质量更高。


whiteboard 公共属性

属性 必需 说明
topLeftX 左上角 X 坐标slide 坐标系slide 默认宽 960
topLeftY 左上角 Y 坐标slide 坐标系slide 默认高 540
width 画板宽度(像素)
height 画板高度(像素)

SVG 模式下 <svg> 需声明 xmlns="http://www.w3.org/2000/svg";内容大小由子元素包围盒决定,width/height/viewBox 不影响渲染(仅当元素属性使用百分比值时需要 viewBox 提供计算基准。Mermaid 模式不需要额外属性。

SVG 内的坐标相对于 whiteboard 自身左上角0,0与 slide 坐标系无关。


SVG 还是 Mermaid

选择分两步:先看图表类型,再看当前模型身份

第一步:图表类型优先判断

以下类型推荐 Mermaid,自动布局、代码简洁;如需精确匹配品牌配色或自定义节点样式,可改用 SVG

图表类型 Mermaid 关键字
流程图、决策树、架构图 flowchart TD / flowchart LR
时序图 sequenceDiagram
类图 classDiagram
饼图 pie
甘特图 gantt
状态图 stateDiagram-v2
思维导图 mindmap
ER 图 erDiagram

第二步:数据图表与装饰元素按模型身份选路径

上表以外的场景散点图、漏斗图、进度条、时间线、波浪背景、星点纹理等需要精确控制坐标和配色SVG 表达力更强,但各模型生成 SVG 的能力有差异:

模型身份 路径
Claude / Gemini / GPT / GLM SVG — 精确控制坐标、颜色、透明度
Doubao / Seed / Other Mermaid — 用 piegantt 等近似表达;确实无法用 Mermaid 表达时才回退到简单 SVG 矩形/线条

先自报身份再选路径:在决定使用 SVG 之前,确认当前模型属于哪一类。不要跳过这一步。


模式一SVG

⚠️ 设计品质要求

在 slide 里嵌入 <whiteboard> 的目的是提升视觉质量,不是把数字堆进去。

  • 不要只用矩形加文字应付:通篇纯白底色 + 方块 + 黑字等于白做,这是不及格输出
  • 数据图表必须有坐标系:坐标轴、网格线、数值标注缺一不可,不要只画柱子或点
  • 字号必须有层级:标题 ≠ 标签 ≠ 数值,混用同一字号会消灭视觉焦点
  • 配色要与 slide 主题呼应:深色 slide 背景下图表用透明底或深色卡片;浅色背景下避免再加纯白底块
  • 每个 whiteboard 都是设计机会:主动用圆角、半透明填充、折线面积、点装饰等细节拉开与默认模板的差距
  • 写 SVG 前先判断背景亮度:背景亮度 < 30% 时,装饰元素"对比不足"比"过强"危害更大,宁重勿轻;
  • 装饰层次用亮度跳跃,不用线性叠透明度α=0.04→0.08→0.12 的等差递增在深色底上几乎看不出差异(相邻层亮度差 ≈20正确做法是非线性跳跃如 0.10→0.40→0.70→1.0,相邻层亮度差 ≥60。

语法

<whiteboard width="400" height="300" topLeftX="500" topLeftY="120">
  <svg xmlns="http://www.w3.org/2000/svg">
    <rect x="50" y="50" width="80" height="200" rx="4" fill="rgba(59,130,246,0.85)"/>
    <text x="90" y="270" text-anchor="middle" font-size="12" fill="rgba(100,116,139,1)">ABC</text>
  </svg>
</whiteboard>

<svg> 需声明 xmlns="http://www.w3.org/2000/svg"width/height/viewBox 无需填写,若元素属性使用百分比值则需额外声明 viewBox

⚠️ 渲染包围盒规则

whiteboard 渲染时以所有子元素的几何包围盒合并结果为内容区域,自适应缩放到容器。

<svg> 上的 widthheightviewBox 不影响内容区域的计算,但 viewBox 有一个实际用途:为百分比属性提供计算基准。若元素使用 width="50%" 等百分比值,必须声明 viewBox 才能正确解析;绝对坐标元素则无需关心。推荐统一使用绝对坐标,避免引入百分比依赖。

支持的 SVG 元素

元素 说明 典型用途
<rect> 矩形,支持 rx 圆角 柱图、卡片、进度条
<circle> 节点、装饰点、环形图
<ellipse> 椭圆 自定义轮廓图形
<line> 直线 坐标轴、分隔线
<path> 任意路径(支持 Q/C 曲线) 波浪、折线、弧形
<text> 文本,支持中文 标签、数值
<polygon> 多边形 箭头、星形、面积填充
<g> 分组 批量变换、语义分组
<linearGradient> 线性渐变定义,配合 fill="url(#id)" 使用 渐变背景、渐变填充

颜色: 统一用 rgba(R,G,B,A),对深浅背景都友好。
虚线: stroke-dasharray="4,4" 用于网格线 / 坐标轴。
变换: transform="translate(x,y)" / rotate(deg cx cy) / scale(n) 均支持。


元素计算

SVG 中只要涉及批量定位、等间距排布或数据映射,建议额外运行一个 Python 脚本把坐标算出来再填入 SVG,而不是手动估值。适用范围不限于数据图表——装饰性点阵、等间距圆、重复图案同样适用。

主动去算:写 SVG 之前先运行脚本,把输出当注释贴在 <svg> 开头,再照着填坐标。估值几乎每次都需要反复调整,跳过这步反而更慢。

数据图表(柱状图范式)

W, H = 360, 260
origin_x, origin_y = 50, 216  # 左下角SVG Y 轴向下
cw, ch = 290, 184

data, y_max = [120, 160, 90], 200
bar_w = int(cw / len(data) * 0.62)
for i, v in enumerate(data):
    cx = round(origin_x + (i + 0.5) * cw / len(data))
    y  = round(origin_y - v / y_max * ch)
    print(f"bar-{i}: x={cx - bar_w//2} y={y} w={bar_w} h={round(origin_y - y)}")

折线图:x = origin_x + i/(n-1)*cwy = origin_y - (v-y_min)/(y_max-y_min)*ch

装饰性元素(等间距范式)

n, total_w, cy, r = 8, 340, 40, 4
step = total_w / (n - 1)
for i in range(n):
    print(f"circle-{i}: cx={round(i * step)} cy={cy} r={r}")

最大包围盒 → whiteboard 尺寸

所有元素坐标算完后,汇总出整体包围盒,直接作为 whiteboard 的 width/height

# 每个元素登记 (x, y, w, h),含 stroke 外扩
elements = [
    (10, 20, 80, 160),   # bar-0
    (107, 10, 80, 170),  # bar-1
    (204, 40, 80, 140),  # bar-2
    (0, 0, 300, 1),      # x-axis
]

xs = [x for x, y, w, h in elements]
ys = [y for x, y, w, h in elements]
x2 = [x + w for x, y, w, h in elements]
y2 = [y + h for x, y, w, h in elements]

wb_w = max(x2) - min(xs)
wb_h = max(y2) - min(ys)
print(f"whiteboard width={wb_w} height={wb_h}")

输出即 <whiteboard width=... height=...> 的值,无需手动估算。


布局模式

全屏装饰层

<whiteboard width="960" height="540" topLeftX="0" topLeftY="0">
  <svg xmlns="http://www.w3.org/2000/svg">
    ...
  </svg>
</whiteboard>

⚠️ 全屏装饰 whiteboard 必须放在所有 <shape> / <img> / <table> 之前否则会遮挡文字内容。XML 中元素位置越靠后,渲染层级越高。

侧栏图表(与文字 shape 并排)

<!-- 左侧文字 -->
<shape type="text" topLeftX="60" topLeftY="120" width="500" height="340">...</shape>
<!-- 右侧图表 -->
<whiteboard width="340" height="340" topLeftX="580" topLeftY="120">
  <svg xmlns="http://www.w3.org/2000/svg">
    ...
  </svg>
</whiteboard>

底部装饰条

<whiteboard width="960" height="100" topLeftX="0" topLeftY="440">
  <svg xmlns="http://www.w3.org/2000/svg">
    ...
  </svg>
</whiteboard>

禁止使用的 SVG 特性

以下特性在 slide <whiteboard> 渲染端不支持或行为不可预测,必须避免:

禁止 原因 替代方案
<radialGradient> 渲染失败 <linearGradient>rgba() 透明度模拟深浅层次
<filter>(阴影、模糊等) 渲染失败 用半透明 <rect> 叠加模拟阴影
<clipPath> / <mask> 渲染失败 调整元素坐标和尺寸自然裁切
<pattern> 渲染失败 手动铺 <circle> / <rect> 点阵
skewX / skewY / matrix(...) 空间扭曲,降级渲染 rotate + translate 替代
<image> 外链 URL 不支持外链 先上传得到 file_token再用 <img> 元素

模式二Mermaid

语法

<whiteboard topLeftX="72" topLeftY="60" width="816" height="360">
  <mermaid>
    <![CDATA[
        flowchart TD
            A[检查 lark-cli 与 jq] --> B[编写每页 slide XML]
            B --> C[通过 jq 生成 slides JSON]
            C --> D[执行 slides +create]
            D --> E[读取 xml_presentation_id]
            E --> F[回读并验证创建结果]
    ]]>
  </mermaid>
</whiteboard>

关键点:

  • 内容用 <![CDATA[...]]> 包裹——Mermaid 语法里的 [>--> 是 XML 特殊字符CDATA 避免转义问题
  • whiteboard 只需 topLeftXtopLeftYwidthheight

支持的 Mermaid 图表类型

类型 关键字 适用场景
流程图 flowchart TD / flowchart LR 业务流程、决策树、工作流
时序图 sequenceDiagram 系统交互、API 调用链
甘特图 gantt 项目计划、里程碑
饼图 pie 占比数据
类图 classDiagram 对象关系、架构设计
ER 图 erDiagram 数据库结构
状态图 stateDiagram-v2 状态机、生命周期
思维导图 mindmap 主题梳理、知识架构
用户旅程 journey 用户体验路径

Mermaid 布局建议

Mermaid 图表会自动撑满 whiteboard 区域。建议:

  • 流程图留足高度,节点较多时适当增加 height比如 400-480
  • 避免一页放超过 15 个节点,内容太密时考虑分页
  • 推荐尺寸参考:
图表类型 建议 width 建议 height
流程图5-8 节点) 720-816 300-400
时序图3-5 参与者) 720-816 320-420
饼图 500-600 300-360
甘特图 816 280-360
思维导图 816 380-480

注意事项 & 已知问题

z-orderSVG 模式)

whiteboard 在 XML 中的位置决定渲染层级:在 shape 前 → 在下层;在 shape 后 → 在上层。全屏装饰 whiteboard 应放在所有 shape 之前。

Mermaid CDATA 必要性

Mermaid 语法包含 [>-->,不用 CDATA 直接写会破坏 XML 解析。始终使用 <![CDATA[ ... ]]>


快速自检清单

SVG 模式——结构检查:

  • <svg> 声明了 xmlns="http://www.w3.org/2000/svg"
  • whiteboard 的 width/height 由所有元素的最大包围盒(含 stroke 外扩)计算得出,不手动估值
  • topLeftX + width ≤ 960topLeftY + height ≤ 540
  • <radialGradient> / <filter> / <clipPath>
  • 文字 y 坐标为 baseline 位置,最小值 ≥ font-size避免被裁切

SVG 模式——视觉品质检查:

  • 坐标轴、网格线、数值标注齐全,没有"裸柱子"或"裸折线"
  • 字号有层级:标题 > 数值 > 轴标签,非全部相同
  • 单一数据系列用同一颜色,多系列用不同颜色且对比充足
  • 轴标签与图表元素互不遮挡,留有足够空间
  • 坐标推导有注释(写明 originX/Y、chartW/H、数据映射公式

Mermaid 模式:

  • 内容包在 <![CDATA[...]]>
  • CDATA 结束符 ]]> 不出现在 Mermaid 代码本身中
  • topLeftX + width ≤ 960topLeftY + height ≤ 540
  • 节点数量合理(单图不超过 15-20 个节点)

通用:

  • XML 标签全部闭合,属性引号完整
  • 如果失败,检查是否是偶发 5001000重试一次

参考