
Description
Order, aggregate, derive, and transform application rows for TanStack Charts while preserving semantic units and lineage. Load for stacks, bins, groups, rolling windows, ranks, regression, hierarchy, missing values, or reactive transform work.
SKILL.md
Prepare Chart Data
Use trigger → inspect → decide → build → verify. Keep analytical preparation outside responsive layout and preserve the row lineage needed by tooltips, selection, tables, and drill-down.
Setup
Prepare semantic rows once, then pass them to marks:
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',
})
Core Patterns
Choose the owner by scope
| Work | Owner |
|---|---|
| Calculation from one row | channel accessor |
| Reusable cross-row result | eager data transform |
| Geometry meaningful only inside one mark | layout: stack() or layout: group() |
| Product-specific enrichment or filtering | ordinary application function |
| Pixel-space work after margins resolve | resolved-layout mark, not a data transform |
Compose structural and analytical transforms
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',
})
Each stage should have one semantic responsibility and a named output.
Order path data before mark construction
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 do not reorder line or area topology.
Preserve direct lineage
TanStack transforms record their immediate input in source. If application code creates additional derived rows, preserve equivalent references when focus, drill-down, or audit must reach the original observations.
Read the transform decision table before combining transform families.
Common Mistakes
CRITICAL Sorting after creating the mark
Wrong:
const mark = lineY(rows, { x: 'date', y: 'value' })
rows.sort((left, right) => +left.date - +right.date)
Correct:
const ordered = [...rows].sort((left, right) => +left.date - +right.date)
const mark = lineY(ordered, { x: 'date', y: 'value' })
Line and area marks capture input order as path order.
Source: docs/reference/marks/line-and-area.md
HIGH Running eager transforms in responsive builders
Wrong:
defineChart(({ width }) => ({
marks: [lineY(rollingWindow(rows, options), channels)],
}))
Correct:
const prepared = rollingWindow(rows, options)
defineChart(({ width }) => ({ marks: [lineY(prepared, channels)] }))
Responsive builders may rerun for size and layout changes while source rows remain unchanged.
Source: docs/guides/transforms-and-reactivity.md; API-FRICTION.md F-128
HIGH Manually accumulating ordinary stacks
Wrong: maintain application running totals for each x value and series.
Correct:
barY(rows, {
x: 'quarter',
y: 'revenue',
z: 'product',
layout: stack(),
})
Native stack layout owns missing series, negative values, order, and updates. Fixed in the current API, but agents trained on early examples may still generate manual accumulation.
Source: GitHub issue 9; API-FRICTION.md F-163
HIGH Flattening derived rows without lineage
Wrong: replace aggregated rows with unlabeled numeric tuples.
Correct: keep named outputs, grouping fields, and direct source references through each application-owned step.
Tooltips, selection, and drill-down otherwise lose the records that contributed to the value.
Source: docs/reference/transforms.md; docs/guides/transforms-and-reactivity.md
HIGH Tension: analytical honesty versus visual simplicity
Aggregation and normalization reduce visual noise but can hide denominators, sample sizes, uncertainty, and missing-value policy. Prepare the evidence required by design-a-chart before reducing row detail.
See also: design-a-chart/SKILL.md § Common Mistakes
References
See also: configure-scales-guides-color/SKILL.md, build-chart-interactions/SKILL.md, and coordinate-charts-with-tanstack/SKILL.md — derived values determine domains, legends, tooltip content, available lineage, and shared chart-grid projections.
More skills from the charts repository
View all 12 skillsbuild-chart-interactions
build chart interactions with TanStack Charts
Aug 15ChartsFrontendInteractionTanStackcompose-marks-and-views
compose marks and views in TanStack Charts
Aug 15ChartsFrontendTanStackUI Componentsconfigure-scales-guides-color
configure scales and guides for TanStack Charts
Aug 15ChartsData VisualizationFrontendTanStackcoordinate-charts-with-tanstack
coordinate TanStack Charts with data sources
Aug 15ChartsData AnalysisData EngineeringFrontend +1debug-and-verify-charts
debug and verify TanStack Charts
Aug 15ChartsDebuggingFrontendTanStackdesign-a-chart
design charts with TanStack Charts
Aug 15ChartsData VisualizationFrontendTanStack
More from TanStack
View publisheraggregation
perform data aggregation in TanStack Table
table
Aug 11Data AnalysisFrontendTanStackapi-not-found
diagnose TanStack Table API errors
table
Aug 11DebuggingFrontendTanStackcell-selection
select rectangular cell ranges in tables
table
Aug 11Data AnalysisTanStackUI Componentscell-spanning
configure cell spanning in TanStack Table
table
Aug 11Data VisualizationFrontendTanStackUI Componentsclient-vs-server
manage TanStack Table data pipelines
table
Aug 11Data PipelineFrontendPerformanceTanStackcolumn-faceting
build faceted filter UIs
table
Aug 11Data VisualizationFrontendTanStack