用途
Prepare Chart Data 是 TanStack Charts 的一项数据准备技能,用于在创建图表标记(mark)之前,对应用数据行进行排序(order)、聚合(aggregate)、派生(derive)与转换(transform),同时保留语义单位(semantic units)与数据血缘(lineage)。
其工作流程为:触发 → 检查 → 决策 → 构建 → 验证。核心原则是把分析性准备放在响应式布局之外,并保留 tooltip、选择、表格与下钻所需的原始行血缘。
主要能力
一次准备语义行,再传给标记
资料给出的示例:
import { groupBy, lineY, rollingWindow } from '@tanstack/charts'
interface Order {
day: string
region: string
amount: number
}
export function prepareRevenue(orders: readonly Order[]) {
const daily = groupBy(orders, {
by: { region: 'region', day: 'day' },
outputs: {
revenue: { value: 'amount', reduce: 'sum' },
orders: { reduce: 'count' },
},
})
return rollingWindow(daily, {
by: 'region',
orderBy: 'day',
size: 7,
partial: false,
outputs: { revenue7d: { value: 'revenue', reduce: 'sum' } },
})
}
const prepared = prepareRevenue([
{ day: '2026-08-01', region: 'West', amount: 120 },
{ day: '2026-08-02', region: 'West', amount: 160 },
])
export const revenueMark = lineY(prepared, {
x: 'day',
y: 'revenue7d',
z: 'region',
})
按作用域选择归属方
| 工作 | 归属方 |
|---|---|
| 从单行计算 | 通道访问器(channel accessor) |
| 可复用的跨行结果 | 急切数据转换(eager data transform) |
| 仅在一个标记内有意义的几何 | layout: stack() 或 layout: group() |
| 产品特定的富化或过滤 | 普通应用函数 |
| 边距确定后的像素空间工作 | 已解析布局标记(resolved-layout mark),而非数据转换 |
组合结构性与分析性转换
import { normalize, select } from '@tanstack/charts'
import { fold } from '@tanstack/charts/transform/fold'
const services = [
{ service: 'api', latency: 180, throughput: 820 },
{ service: 'worker', latency: 240, throughput: 510 },
]
const folded = fold(services, {
fields: ['latency', 'throughput'] as const,
as: { key: 'metric', value: 'measurement' },
})
const normalized = normalize(folded, {
by: 'metric',
value: 'measurement',
basis: 'extent',
as: 'relativeMeasurement',
})
export const baselines = select(normalized, {
by: 'metric',
select: 'first',
})
每个阶段应有单一的语义职责与具名输出。
在标记构建前对路径数据排序
import { lineY } from '@tanstack/charts'
const rows = [
{ date: new Date('2026-08-03'), value: 14 },
{ date: new Date('2026-08-01'), value: 10 },
{ date: new Date('2026-08-02'), value: 12 },
]
const ordered = [...rows].sort((left, right) => +left.date - +right.date)
export const trend = lineY(ordered, { x: 'date', y: 'value' })
比例尺域(scale domains)不会重排线或面的拓扑顺序。
保留直接血缘
TanStack 的转换会在 source 中记录其直接输入。如果应用代码创建了额外的派生行,在需要聚焦、下钻或审计可追溯到原始观测时,应保留等价的引用。
在组合转换族之前,应先阅读转换决策表。
常见错误
严重:在创建标记之后再排序
错误写法:
const mark = lineY(rows, { x: 'date', y: 'value' })
rows.sort((left, right) => +left.date - +right.date)
正确写法:
const ordered = [...rows].sort((left, right) => +left.date - +right.date)
const mark = lineY(ordered, { x: 'date', y: 'value' })
线与面标记会将输入顺序捕获为路径顺序。
来源:docs/reference/marks/line-and-area.md
高:在响应式构建器中运行急切转换
错误写法:
defineChart(({ width }) => ({
marks: [lineY(rollingWindow(rows, options), channels)],
}))
正确写法:
const prepared = rollingWindow(rows, options)
defineChart(({ width }) => ({ marks: [lineY(prepared, channels)] }))
响应式构建器可能因尺寸与布局变化而重新运行,而源数据行保持不变。
来源:docs/guides/transforms-and-reactivity.md; API-FRICTION.md F-128
高:手动累积普通堆叠
错误做法:为每个 x 值与系列维护应用层累计值。
正确做法:
barY(rows, {
x: 'quarter',
y: 'revenue',
z: 'product',
layout: stack(),
})
原生堆叠布局负责处理缺失系列、负值、顺序与更新。该问题在当前 API 中已修复,但基于早期示例训练的代理仍可能生成手动累积。
来源:GitHub issue 9; API-FRICTION.md F-163
高:无血缘地平坦化派生行
错误做法:用未标注的数值元组替换聚合行。
正确做法:通过每个应用拥有的步骤保留具名输出、分组字段与直接源引用。
否则 tooltip、选择与下钻将丢失贡献该值的记录。
来源:docs/reference/transforms.md; docs/guides/transforms-and-reactivity.md
高:分析诚实性与视觉简洁性的张力
聚合与归一化会减少视觉噪声,但可能隐藏分母、样本量、不确定性以及缺失值策略。在降低行细节之前,应先准备 design-a-chart 所需的证据。
另见:design-a-chart/SKILL.md § Common Mistakes
使用方式
在技术栈中加载此技能,按「触发 → 检查 → 决策 → 构建 → 验证」的流程准备图表数据:先确定各类转换的归属方,再组合结构性与分析性转换,最后在标记构建前完成排序与血缘保留。
适用场景
- 使用 TanStack Charts 构建堆叠、分箱、分组等图表前的数据准备。
- 需要在标记构建前完成聚合、派生与排序的可视化场景。
- 需要保留 tooltip、选择、表格与下钻所需行血缘的交互式图表。
参考资料
- 转换选择与输出契约
- 另见:configure-scales-guides-color/SKILL.md、build-chart-interactions/SKILL.md 与 coordinate-charts-with-tanstack/SKILL.md——派生值决定域、图例、tooltip 内容、可用血缘以及共享图表网格投影。
限制
关于具体的收费、价格、支持平台与效果数据,资料暂未提供。