Skip to main content

Chart spec

A ChartSpec is a plain-JSON description of a chart, discriminated on type and versioned (version: 1). <Chart spec={spec} rows={rows} /> renders it. Nothing in a spec is a function or JSX, so specs can be stored, transmitted, diffed, and built by end users at runtime.

import Chart, {type ChartSpec} from '@zuilib/charts'

const spec: ChartSpec = {
version: 1,
type: 'bar',
title: 'Revenue by region',
xKey: 'region',
series: [{field: 'revenue', label: 'Revenue', format: 'currency:USD'}],
yAxis: {format: 'compact'},
}

Series and colors

Cartesian specs (line, area, bar, composed, radar) declare series: each entry names a row field, an optional label, an optional palette slot (paletteSlot: 18, assigned in declaration order when left out — fixed order, never cycled), an optional axis: 'secondary' for a secondary value axis, and stacking via stackId or the spec-level stacked: true | 'percent'.

Category specs (pie, donut, radial-bar, funnel, treemap) declare nameKey + valueKey/sizeKey; categories take palette slots in data order. Scatter declares xKey/yKey and an optional groupKey that splits points into colored groups — at most three concurrently, the palette subset validated for every-pair discrimination.

A dual axis is supported but discouraged: two measures of different scale read better as two charts or an indexed series. Keep axis: 'secondary' for the genuinely paired cases (a count and a rate over the same buckets).

Format tokens

Formats are named, not passed: 'number', 'compact', 'percent' (0–1 fraction), 'currency:USD' (any ISO code), 'date:short|medium|long', 'datetime:short|medium', 'none'. All are Intl-backed and honor the locale prop. A custom format keeps the spec serializable — the spec names a token and the function arrives as a prop:

<Chart
spec={{...spec, yAxis: {format: 'sla-ms'}}}
rows={rows}
formats={{'sla-ms': (v) => `${v} ms`}}
/>

A factory receives the part after the colon, so one entry can serve a family of tokens:

<Chart spec={spec} rows={rows} formats={{unit: (arg) => (v) => `${v} ${arg}`}} />
// the spec may now name 'unit:req/s', 'unit:GB', …

Interaction

  • tooltip (default on) renders the themed tooltip.
  • legend defaults to on for two or more entries, off for one; a single series needs no legend — the title names it.
  • interaction decides what a mark click does inside a CrossFilterProvider: 'filter' (default) toggles the category into the shared filters (shift-click accumulates), 'highlight' only sets the shared highlight, 'none' does nothing. Every click also reports through onMarkClick.
  • brush: true adds a range brush under a cartesian plot.
  • referenceLines draw targets and thresholds: {axis: 'y', value: 90000, label: 'Target'}.

Every chart type, each rendered live from the spec shown below it.

Loading example
Loading example
Loading example
Loading example
Loading example
Loading example
Loading example
Loading example
Loading example
Loading example