Definition identity is the application update boundary. A framework memo captures the current data and options; Charts rebuilds the scene when that definition changes or when the chart surface changes size.
function RankingChart({ rows, metric, accent }: Props) {
const definition = useMemo(() => {
const ranked = rankRows(rows, metric)
return defineChart({
animate: { duration: 280, easing: 'ease-out' },
chart: ({ width }) => ({
marks: [
barX(ranked, {
x: 'value',
y: 'label',
key: 'id',
fill: accent,
}),
],
x: {
scale: scaleLinear,
nice: true,
ticks: width < 420 ? 4 : 7,
},
y: {
scale: () => scaleBand<string>().padding(0.1),
},
}),
})
}, [rows, metric, accent])
return <Chart definition={definition} ariaLabel="Revenue ranking" />
}Use the framework's native equivalent: computed, createMemo, $derived, Angular computed, or Octane useMemo.
host.update({
...options,
definition: createRankingDefinition(nextRows, nextMetric, nextAccent),
})Built-in marks first use an explicit key, then a unique datum.id. Bars, lines, areas, and cells can also infer identity from their semantic positional channels:
barX(rows, {
x: 'value',
y: 'label',
})Here barX uses the unique y value when rows have no id. barY uses x; lineY and areaY use x; areaX uses y; rects and cells use their x/y interval tuple. Inference is scoped to each group and falls back to array position when a candidate is incomplete or duplicated. Development builds warn once for each affected mark.
Supply key when the inferred value is not the entity's identity or can change independently of it. Stable identity preserves surviving SVG elements, focused points, and transition continuity.
animate accepts true or:
Numeric geometry and compatible path data interpolate. Entering and exiting nodes reconcile by key. If an update interrupts a transition, it begins from the geometry currently painted on screen.
Static SVG, server rendering, and createChartScene do not include animation.
For high-rate data:
The final definition passed to host.update is applied synchronously.