关于 d3-animated-data-visualization
用于渲染媒体中动画数据可视化的 D3 技能,适合需要自定义编码、布局或数据驱动变化的项目。它强调保持数据含义,并为视频生成确定性帧。
主要功能
- 01自定义图表编码与布局
- 02保持身份稳定的数据联结
- 03基于帧的确定性动画
- 04比例尺、坐标轴与图形指导
- 05无障碍与数据完整性检查
适用场景
- 01为渲染视频制作数据动画
- 02构建标准组件无法表达的图表
- 03展示不同视觉状态间的数据变化
- 04制作响应式图表版本
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ calesthio/ generative-media-skills --skill d3-animated-data-visualization安装后在 Claude Code 中输入/d3-animated-data-visualization确认已加载。
附带文件EVAL.md
详细介绍
D3 动画数据可视化
当数据决定渲染媒体序列中的标记、比例尺、布局、标签和动画时,使用此技能。如果标准图表组件无法充分控制所需的编码或编排,D3 会很有用。
任务不是让数字动起来,而是在控制注意力随时间变化的同时保留其含义。来源完整性、分母、单位、不确定性、比例尺和转换都是制作输入,而非页脚装饰。
证据立场
- 文档记载的事实: 来自 D3、W3C 官方文档或引用标准文档的行为或要求。
- 制作启发: 取决于数据集、受众和交付方式的实用选择。
- 经验观察: 从实际数据、布局、渲染帧或编码输出中测得的结果。
D3 的各个包和 API 分别进行版本管理。事实核查日期为 2026-07-12。记录各模块的确切版本;如果安装的版本组合有所不同,请重新查阅官方文档。
何时使用 D3
在以下情况下使用 D3:
- 使用比例尺、形状、坐标轴以及 SVG 或 Canvas 标记构建自定义视觉编码;
- 时间线、分布、层级、地理投影、流向和网络;
- 需要在不同状态之间保持稳定标识的数据联结;
- 与数据关联的精确注释和来源说明;
- 在浏览器渲染的视频中进行确定性的帧求值;
- 需要重新计算比例尺和布局的响应式图表变体。
如果标准图表组件已经能满足真实表达、标签、无障碍和导出需求,请优先使用标准图表组件。如果数据已简化为少量经核准的数值,且不再需要数据驱动的布局,请优先使用动态合成器。不要用 D3 为说明性或虚构数字增添虚假的权威性。
确立数据和主张约定
选择图表前,请记录:
- 问题和预期结论;
- 来源组织、数据集/表格、URL 或标识符、访问日期、许可证和所有者;
- 总体、地理范围、时间范围、样本、分母、单位、货币口径和定义;
- 缺失值、排除项、修订、删失情况和已知的数据收集变更;
- 转换:聚合、归一化、索引化、通胀调整、平滑、滚动窗口、插值、投影或模型输出;
- 不确定性、置信区间、误差范围、情景范围或估算状态;
- 已核准的主张,以及可视化不得暗示的主张;
- 宽高比、时长、fps、字幕/来源说明区域和无障碍替代方案;
- 数据校验和及可视化配置版本。
如果无法确定这些信息,请将输出标记为探索性内容,或暂停发布。不要默默修补缺失数据、推断分母或选择有利的日期范围。
选择能回答问题的编码方式
根据比较任务选择图表:
| 问题 | 常见起点 | 主要完整性风险 |
|---|---|---|
| 比较类别 | 排序条形图或点图 | 长度基线截断、排序不稳定 |
| 展示随时间的变化 | 折线图、阶梯图、面积图或小多图 | 平滑处理暗示实际观测,隐藏缺失时间段 |
| 展示分布 | 直方图、条带图/点图、箱线图、密度图 | 操纵分箱/带宽、隐藏样本量 |
| 展示关系 | 带标注的散点图 | 暗示相关性就是因果关系、点重叠 |
| 部分与整体 | 堆叠条形图或标注清晰的面积图 | 总量不相等、小分段难以读取 |
| 地理 | 投影地图加标准化指标 | 将原始计数误认为比率、投影失真 |
| 层级 | 树图、矩形树图、分区图 | 面积/角度难以比较、层级含糊 |
| 网络/流 | 节点连线图、桑基图、弦图 | 将布局误认为地理位置或重要程度 |
生产启发:
- 精确比较时,优先使用共同刻度上的位置,其次是长度,再考虑面积、角度或色相。
- 用长度编码数值的条形图通常应从零开始。折线图可以使用受限范围,但必须明确标注并保留上下文。
- 除非关系和独立刻度至关重要、醒目且不易造成虚假相关,否则避免使用双轴。
- 当 3D 透视会扭曲位置、长度、面积或遮挡关系时,避免将其用于定量图形标记。
- 同时展示多个序列导致难以辨读时,使用小多图。
- 当排序能传达排名时,应对类别排序;如果排序会造成误导,则保留语义顺序或时间顺序。
不要仅仅因为平滑后的折线看起来更精致,就对折线进行平滑。曲线可能会超调,或暗示未测量的中间行为。如果线性插值或阶梯插值能更好地表示观测结果,就应使用它们;任何平滑方法都应加以说明。
构建比例尺、坐标轴和图形标记
有据可查的事实: D3 比例尺会将定义域映射到值域。D3 提供连续型、序列型、发散型、量化型、阈值型、序数型、分段型、点型、时间型等比例尺系列。坐标轴会根据比例尺绘制易读的刻度。形状生成器会将数据转换为路径几何图形。
实施约定:
- 根据已批准的数据和策略推导定义域,而不是为了追求视觉冲击;
- 除非有充分记录的例外理由,否则长度型数值标记应包含零;
- 明确处理无效、缺失、零值和负值;
- 仅对正值定义域使用对数比例尺,并清晰标注;当有符号数值很重要时,使用 symlog 或其他合理的方法;
- 选择能保留单位和重要含义的刻度格式;
- 在最终停留画面中保持坐标轴、单位、来源和不确定性可见;
- 为数据标记和注释使用稳定 ID。
比例尺设置示例:
const x = d3.scaleBand()
.domain(data.map((row) => row.category))
.range([plotLeft, plotRight])
.padding(0.22);
const y = d3.scaleLinear()
.domain([0, d3.max(data, (row) => row.value)])
.nice()
.range([plotBottom, plotTop]);
此示例适用于正值条形图的数值,不是通用的比例尺方案。
使用数据联结保持身份一致
有据可查的事实: selection.data(data, key) 会将数据绑定到选定元素。selection.join() 可以处理进入、更新和退出的元素。如果不提供键,则按索引进行匹配。
使用稳定的语义键,确保标记在不同状态中始终代表同一实体:
const marks = plot.selectAll("rect.bar")
.data(rows, (row) => row.id)
.join(
(enter) => enter.append("rect").attr("class", "bar"),
(update) => update,
(exit) => exit.remove(),
);
使用索引键可能导致条形图在排序或筛选后看起来变成了无关类别。应测试新增、删除、并列值和类别重排的情况。
将动画设计为解释工具
每个动画节拍都应回答以下问题之一:
- 参照框架是什么?
- 有哪些数据到达或发生了变化?
- 哪种比较最重要?
- 有哪些不确定性或注意事项需要说明?
- 观众应该记住什么最终状态?
建议的呈现顺序:
- 标题/问题和单位;
- 坐标轴或比较框架;
- 图形标记;
- 突出显示的关系;
- 注释和来源/注意事项;
- 稳定的最终画面。
避免使用暗示源数据不支持的测量精度的计数动画。不要用弹簧/弹性缓动让定量标记越过目标位置:条形暂时超过其数值,会在视觉上传达错误的数量。缓动可以控制呈现进度,但停留时的标记必须准确编码数值,并应避免产生误导性的中间状态。
确定性渲染
**有文档记载的事实:**D3 过渡通过 D3 的计时器系统,按经过的时间进行调度。它们适用于交互式浏览器动画,但视频渲染器可能会乱序请求帧,或不按实时速度播放。
对于固定媒体,应直接根据请求的帧计算视觉状态:
function renderFrame(frame, fps) {
const raw = clamp01((frame - startFrame) / durationFrames);
const progress = d3.easeCubicInOut(raw);
bars
.attr("y", (row) => d3.interpolateNumber(y(0), y(row.value))(progress))
.attr("height", (row) => d3.interpolateNumber(0, y(0) - y(row.value))(progress));
}
更好的做法是在数据固定后预先构建插值器。为进入、更新和退出的标记指定明确的起始/结束状态。根据同一帧状态推导注释、坐标轴过渡、标签和来源说明。
要求:
- 捕获期间不得实时获取数据;
- 不得使用墙上时钟时间或依赖事件的过渡状态;
- 随机布局必须使用固定种子或预先计算;
- 字体文件和文本测量结果必须稳定;
- 必须正确处理倒序和乱序帧;
- 必须反复比较压力测试帧。
对于力导向布局,应使用固定的初始位置和随机源运行固定次数的迭代,存储得到的坐标,然后从这些冻结的坐标开始动画。不要在每个渲染工作线程中独立运行无约束的实时力模拟。
地图、网络和层级结构
地理地图
- 说明指标是数量、比率、占比、变化量还是指数;
- 当论点有此要求时,按人口/暴露量进行标准化;
- 根据空间问题选择合适的投影并予以说明;
- 区分无数据和零值;
- 保留地理数据的来源/版本,以及几何数据与数据表之间的连接关系;
- 如果面积或投影导致数值难以比较,应加入非地图形式的比较。
网络和流向
- 定义节点、边、方向、宽度和距离各自表示什么;
- 说明经过筛选的边和布局规则;
- 除非确实如此,否则不要暗示力导向布局中的邻近关系代表测量距离;
- 在确定性捕获前冻结布局;
- 适用时展示流量守恒,或说明流失/聚合情况。
层级结构
- 验证父子结构和总计;
- 避免对后代节点和父节点重复计数;
- 说明面积、角度、深度或顺序是否用于编码数值;
- 对难以辨认的小型节点提供标签或表格。
响应式变体
基于同一数据/论点约定设计每种输出,但应针对其画布重新计算布局。
- 必要时调整边距、刻度密度、标签位置、注释顺序和图表形式。
- 竖屏视频应使用小倍图或按排名筛选的子集,而不是缩小密集的桌面图表。
- 每个精简版本都应保留单位、来源、不确定性和比较背景。
- 按预期的实际播放尺寸测试排版。
- 对于固定视频,不要用视口宽度缩放字体来代替布局调整。
无障碍
**WCAG 2.2 中记载的事实:**颜色不能作为传达信息的唯一视觉方式;普通文本通常需要至少 4.5:1 的对比度,大号文本至少需要 3:1;有意义的图形对象和状态通常需要与相邻颜色达到至少 3:1 的非文本对比度。
对于每种可视化:
- 将颜色与直接标签、位置、形状、纹理、线型或符号搭配使用;
- 使用排序方式和对比度符合数据类型的调色板;
- 撰写简洁的文字要点,并在发布渠道允许时提供底层的无障碍表格或结构化数据;
- 以文字说明不确定性和来源,而非只用颜色表达;
- 为旁白和有意义的音频添加字幕;
- 避免动画导致标签难以辨读;
- 检查标记、背景或高亮区域是否会闪烁。
对于交互式发布,应根据承载环境提供适当的键盘和屏幕阅读器语义,以及非视觉等效内容。对于预录视频,旁白、字幕、文字稿和无障碍数据表是切实可行的替代方案。声化可以作为补充,但不能自动替代结构化数据替代方案。
性能和输出质量
如果需要可检查的矢量标记和文本,且 DOM 规模可控,请使用 SVG。对于非常密集的标记,可考虑使用 Canvas,但需单独规划无障碍等效内容和清晰的文本。只有采用有文档记录的方法并保留所声称的模式时,才应减少数据。
测量:
- DOM/标记数量和布局时间;
- 交付分辨率下的帧渲染时间;
- 字体和标签测量的稳定性;
- 长时间渲染期间的内存占用;
- 路径复杂度和过度绘制;
- 编码后细线、小标签、网格和颜色渐变的清晰度。
不要设定普遍适用的数据点数量阈值。实际限制取决于图表类型、浏览器、渲染器、硬件和特效。
溯源和质量检查
维护一份可视化清单,其中包含:
- 输入文件名和校验和;
- 来源、访问日期、许可证和获取方法;
- 转换步骤和代码/配置版本;
- D3 包版本;
- 图表类型、域、范围、分箱、投影、布局种子/刻度、配色方案和缓动;
- 输出尺寸、fps、时长和渲染环境;
- 经批准的主张、注意事项和审核者。
质量检查应通过以下项目:
- **数据:**复现总数、样本、转换、缺失值和不确定性。
- **编码:**核实比例尺、基线、单位、面积/长度/位置、排序、投影和图例。
- **动画:**检查进入/更新/退出时的对象身份、真实的中间状态、标签、注释和最终停留帧。
- **确定性:**比较重复帧、重新排序和向后跳转。
- **无障碍:**检查颜色替代方案、对比度、字幕、文字要点和数据表。
- **交付:**检查裁切变体、来源说明的可读性、帧数、压缩和元数据。
严重问题包括:主张缺乏依据、遗漏来源或分母、比例尺具有误导性、总数错误、在后果重大时隐瞒不确定性、含义仅由颜色表达、布局不确定,或交付版本中的来源说明无法辨读。
示例 1:试点结果对比
这是一个完整示例,并非强制公式。
**意图:**为一条已获批准的声明制作一张 7 秒、9:16 的证据卡:“试点团队记录的人工升级次数减少了 31%。”
**数据约定:**内部试点;8 个团队;测量期为 2026 年 4 月至 6 月;对比对象为同一批团队在 2026 年 1 月至 3 月的工作流;数据访问日期为 2026-07-05;数值表示相对降幅;数据源并非随机研究;已提供精确计数和经批准的披露内容。
**设计:**使用两条带零基线的水平条形:Prior workflow 和 Pilot period。直接标签包含计数;另用单独的 31% fewer 标注说明相对对比。来源和样本说明在最后两秒内保持可见。颜色差异还通过标签和不同的网纹/实心样式加以区分。
动画:
00:00.00-00:00.60 Question, axis, unit, and baseline appear.
00:00.60-00:01.50 Prior bar grows linearly to its exact count.
00:01.20-00:02.10 Pilot bar grows to its exact count.
00:02.20-00:03.00 Difference bracket and "31% fewer" annotation appear.
00:03.00-00:05.00 Hold comparison.
00:05.00-00:07.00 Hold comparison plus source/sample disclosure.
根据帧推导的进度计算每个标记;不要使用弹性过冲。交付时一并提供底层两行数据表。
**预期结果:**数值准确、长度对比公平、分母和时间范围清晰、来源易读,且干净渲染生成的帧完全一致。
**常见问题:**将 31% 从零开始动画呈现,却不显示对比计数;未说明这是内部试点;条形基线被截断;来源显示时间过短;仅用颜色区分。
**变体:**如果无法公开精确计数,可使用清晰标注的指数化对比(prior workflow = 100),并解释转换方式,而不是捏造条形数值。
示例 2:区域干旱异常地图
这是一个完整示例,并非强制公式。
**意图:**制作一段 20 秒的纪录片插入片段,展示流域的标准化降水异常,随后比较受影响最大的 5 个流域。
**数据约定:**注明气象数据集及版本;注明流域几何数据来源及版本;月度异常相对于明确说明的 30 年基准期计算;记录缺失站点和插值方法;数值表示异常分数,而非原始降雨量。
工作流:
- 验证几何数据与数据的联接键,并将缺失流域与零异常分别分类。
- 选择适合该区域的等面积投影,并在制作说明中披露。
- 使用以零为中心的发散色阶,直接标注图例,并用纹理边界标示严重类别。
- 按月份显示地图,根据冻结的月度数值进行明确的帧间插值。
- 在选定月份标注 5 个流域,随后切换到有序点图,以便精确比较。
- 在最后停留画面和文字稿中保留基准期定义、来源和插值说明。
**预期结果:**观众先看到空间分布模式,随后获得精确的排名对比,且不会误将地图面积当作异常幅度。
**常见问题:**颜色由原始站点数量决定;无数据区域看起来像正常区域;未说明投影;将插值结果当作直接观测值呈现;不同工作进程生成的实时力导向/碰撞标签不一致;仅交付地图而未提供无障碍表格。
**变体:**制作短版社交媒体剪辑时,可省略月度动画,改用一个经批准的月份及有序点图;保留基准期和说明。
来源
已于 2026-07-12 核查的官方和权威来源:
- D3 文档:https://d3js.org/
- D3 选择集关联:https://d3js.org/d3-selection/joining
- D3 比例尺:https://d3js.org/d3-scale
- D3 坐标轴:https://d3js.org/d3-axis
- D3 图形:https://d3js.org/d3-shape
- D3 插值与缓动:https://d3js.org/d3-interpolate and https://d3js.org/d3-ease
- D3 计时器与过渡:https://d3js.org/d3-timer and https://d3js.org/d3-transition
- D3 地理投影:https://d3js.org/d3-geo
- D3 力模拟:https://d3js.org/d3-force/simulation
- D3 许可证(ISC):https://github.com/d3/d3/blob/main/LICENSE
- W3C WCAG 2.2,《颜色的使用》:https://www.w3.org/WAI/WCAG22/Understanding/use-of-color.html
- W3C WCAG 2.2,《对比度最低要求》:https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html
- W3C WCAG 2.2,《非文本对比度》:https://www.w3.org/WAI/WCAG22/Understanding/non-text-contrast.html
- 皇家统计学会,《数据可视化最佳实践》:https://royal-statistical-society.github.io/datavisguide/