Families
Every public chart family, drawn with small fixed data, and the props that shape each archetype.
@workspace/active-charts 6.0.0Status unknowncontent differs from the recorded release 6.0.0baseline ce081dc3
Choose a family to draw it. Each one is the public component with the props shown in the source; the data is in the example's data module.
Every chart familyClient
Full source examples/charts/families.tsx
// apps/docs/examples/charts/families.tsx'use client';
import {useState, type ReactNode} from 'react';import { BEFORE_AFTER, DAILY_PRICES, DELIVERY_DAYS, DELIVERY_SPREAD, FLOW_LINKS, FLOW_NODES, FUNNEL, MILESTONES, MONTHLY_SALES, ORGANISATION, PRICE_VS_RATING, PRODUCT_TREE, PROFIT_BRIDGE, SALES_SERIES, SHARE_BY_REGION, SKILL_SERIES, SKILLS, TEMPERATURE_BAND, WEEKDAY_ORDERS,} from '@/lib/examples/chart-data';
import { AreaChart, BarChart, BoxPlotChart, BulletChart, CandlestickChart, ChartDefaults, DumbbellChart, englishChartTranslator, FunnelChart, GaugeChart, HeatmapChart, Histogram, LinearGauge, LineChart, LollipopChart, NightingaleChart, OhlcChart, OrgChart, PieChart, RadarChart, RadialBarChart, RangeAreaChart, RangeBarChart, SankeyChart, ScatterChart, Sparkline, SunburstChart, TimelineChart, TreemapChart, WaterfallChart,} from '@workspace/active-charts';import { Field, FieldLabel,} from '@workspace/active-ui/components/primitives/field';import { NativeSelect, NativeSelectOptGroup, NativeSelectOption,} from '@workspace/active-ui/components/primitives/native-select';
const H = 280;const PRICE = {kind: 'price', currency: 'EUR', decimals: 2} as const;
/** Every public chart family, grouped by the archetype that shapes its props. */const FAMILIES: Record<string, Record<string, () => ReactNode>> = { Cartesian: { Line: () => ( <LineChart data={MONTHLY_SALES} xKey="month" xAxis="category" series={SALES_SERIES} legend height={H} /> ), Area: () => ( <AreaChart data={MONTHLY_SALES} xKey="month" xAxis="category" series={SALES_SERIES} stacked legend height={H} /> ), Bar: () => ( <BarChart data={MONTHLY_SALES} xKey="month" xAxis="category" series={SALES_SERIES} legend height={H} /> ), Histogram: () => ( <Histogram data={DELIVERY_DAYS} xKey="days" name="Orders" binCount={8} height={H} /> ), Scatter: () => ( <ScatterChart data={PRICE_VS_RATING} xKey="price" xAxis={{type: 'number', title: 'Price'}} yKey="rating" name="Products" yAxis={{title: 'Rating'}} height={H} /> ), Candlestick: () => ( <CandlestickChart data={DAILY_PRICES} xKey="date" xAxis={{temporalSemantic: 'calendarDate'}} openKey="open" highKey="high" lowKey="low" closeKey="close" name="Price" yAxis={{valueSemantics: PRICE}} height={H} /> ), OHLC: () => ( <OhlcChart data={DAILY_PRICES} xKey="date" xAxis={{temporalSemantic: 'calendarDate'}} openKey="open" highKey="high" lowKey="low" closeKey="close" name="Price" yAxis={{valueSemantics: PRICE}} height={H} /> ), 'Range area': () => ( <RangeAreaChart data={TEMPERATURE_BAND} xKey="month" xAxis="category" yLowKey="low" yHighKey="high" name="Temperature" height={H} /> ), 'Range bar': () => ( <RangeBarChart data={TEMPERATURE_BAND} xKey="month" xAxis="category" yLowKey="low" yHighKey="high" name="Temperature" height={H} /> ), 'Box plot': () => ( <BoxPlotChart data={DELIVERY_SPREAD} xKey="carrier" xAxis="category" minKey="min" q1Key="q1" medianKey="median" q3Key="q3" maxKey="max" outliersKey="out" name="Delivery days" height={H} /> ), Dumbbell: () => ( <DumbbellChart data={BEFORE_AFTER} xKey="team" xAxis="category" yLowKey="before" yHighKey="after" lowName="2025" highName="2026" height={H} /> ), Lollipop: () => ( <LollipopChart data={MONTHLY_SALES} xKey="month" xAxis="category" yKey="online" name="Online" height={H} /> ), Waterfall: () => ( <WaterfallChart data={PROFIT_BRIDGE} xKey="step" yKey="amount" kindKey="kind" name="Profit" height={H} /> ), Heatmap: () => ( <HeatmapChart data={WEEKDAY_ORDERS} xKey="day" yKey="part" colorKey="orders" name="Orders" label={{enabled: true}} height={H} /> ), }, Categorical: { Pie: () => ( <PieChart data={SHARE_BY_REGION} valueKey="value" categoryKey="region" name="Share" legend height={H} /> ), Funnel: () => ( <FunnelChart data={FUNNEL} valueKey="count" categoryKey="stage" name="Visitors" height={H} /> ), 'Radial bar': () => ( <RadialBarChart data={SHARE_BY_REGION} valueKey="value" categoryKey="region" name="Share" height={H} /> ), Nightingale: () => ( <NightingaleChart data={SHARE_BY_REGION} valueKey="value" categoryKey="region" name="Share" legend height={H} /> ), Radar: () => ( <RadarChart data={SKILLS} categoryKey="skill" series={SKILL_SERIES} min={0} max={10} legend height={H} /> ), }, 'Hierarchy and flow': { Treemap: () => <TreemapChart data={PRODUCT_TREE} height={H} />, Sunburst: () => <SunburstChart data={PRODUCT_TREE} height={H} />, Sankey: () => ( <SankeyChart nodes={FLOW_NODES} links={FLOW_LINKS} height={H} /> ), 'Organisation chart': () => ( <OrgChart data={ORGANISATION} direction="horizontal" height={320} /> ), Timeline: () => <TimelineChart data={MILESTONES} height={220} />, }, Scalar: { Gauge: () => ( <GaugeChart value={72} min={0} max={100} zones={[ {from: 0, to: 40, color: 'var(--chart-negative)', label: 'low'}, {from: 40, to: 75, color: 'var(--chart-caution)', label: 'fair'}, {from: 75, to: 100, color: 'var(--chart-positive)', label: 'good'}, ]} label="Satisfaction" height={220} /> ), 'Linear gauge': () => ( <LinearGauge value={68} min={0} max={100} target={75} label="Budget used (%)" height={120} /> ), Bullet: () => ( <BulletChart value={82} min={0} max={120} target={100} label="Orders vs target" height={90} /> ), Sparkline: () => ( <Sparkline data={MONTHLY_SALES.map((row) => row.online)} width={220} height={48} type="area" showLastPoint /> ), },};
const ALL = Object.entries(FAMILIES).flatMap(([group, members]) => Object.keys(members).map((name) => ({group, name})),);
/** The public chart families, each with small fixed data; pick one to draw it. */export default function ChartFamilies() { const [choice, setChoice] = useState('Cartesian/Line'); const [group, name] = choice.split('/') as [string, string]; const render = FAMILIES[group]![name]!; return ( <div className="flex w-full flex-col gap-4"> <Field className="max-w-xs"> <FieldLabel htmlFor="chart-family">Chart family</FieldLabel> <NativeSelect id="chart-family" className="w-full" value={choice} onChange={(event) => setChoice(event.target.value)} > {Object.keys(FAMILIES).map((g) => ( <NativeSelectOptGroup key={g} label={g}> {ALL.filter((entry) => entry.group === g).map((entry) => ( <NativeSelectOption key={entry.name} value={`${g}/${entry.name}`} > {entry.name} </NativeSelectOption> ))} </NativeSelectOptGroup> ))} </NativeSelect> </Field> <ChartDefaults locale="en-GB" t={englishChartTranslator}> <div key={choice} data-chart-family={choice}> {render()} </div> </ChartDefaults> </div> );}Archetypes#
Every chart takes BaseChartProps (size, title, tooltip, legend, context menu, animation,
accessibility, export) plus the props of its archetype:
| Archetype | Data props | Keyboard |
|---|---|---|
| Cartesian | data, x, y or series, x, y | arrow keys along the series; Space selects |
| Categorical | data, value, category | arrow keys between slices or bars |
| Hierarchical | data: one Hierarchy (label, value, children) | arrow keys through the tree; drill down |
| Graph | nodes and links (sankey) | Enter switches between nodes and links |
| Scalar | value, min, max, target, zones | one stop with a full description |
The complete contract per family is in the API reference and its capabilities in Capabilities.
The data#
lib/examples/chart-data.ts
// apps/docs/lib/examples/chart-data.ts
/** * Small, fixed datasets for the chart examples: a fictitious company's * sales, costs and organisation. Shapes follow the chart reference of the * lab the examples came from; the content is neutral and invented. */
export const MONTHLY_SALES = [ {month: 'Jan', online: 42, stores: 61, costs: 70}, {month: 'Feb', online: 45, stores: 58, costs: 68}, {month: 'Mar', online: 51, stores: 63, costs: 74}, {month: 'Apr', online: 49, stores: 66, costs: 77}, {month: 'May', online: 56, stores: 64, costs: 79}, {month: 'Jun', online: 61, stores: 69, costs: 83}, {month: 'Jul', online: 58, stores: 72, costs: 81}, {month: 'Aug', online: 63, stores: 70, costs: 85}, {month: 'Sep', online: 67, stores: 75, costs: 88}, {month: 'Oct', online: 71, stores: 77, costs: 90}, {month: 'Nov', online: 78, stores: 81, costs: 96}, {month: 'Dec', online: 92, stores: 88, costs: 104},];
export const SALES_SERIES = [ {yKey: 'online', name: 'Online'}, {yKey: 'stores', name: 'Stores'},];
/** Daily prices of one product over two weeks, as `Date` values. */export const DAILY_PRICES = [ [2, 101.2, 103.4, 100.8, 102.9], [3, 102.9, 104.1, 102.2, 103.6], [6, 103.6, 103.9, 101.5, 101.9], [7, 101.9, 102.8, 100.9, 102.5], [8, 102.5, 105.2, 102.3, 104.8], [9, 104.8, 106.0, 104.1, 105.1], [10, 105.1, 105.4, 103.2, 103.7], [13, 103.7, 104.6, 102.8, 104.2], [14, 104.2, 107.1, 104.0, 106.6], [15, 106.6, 107.3, 105.2, 105.9],].map(([day, open, high, low, close]) => ({ date: new Date(Date.UTC(2026, 6, day!)), open: open!, high: high!, low: low!, close: close!,}));
export const SHARE_BY_REGION = [ {region: 'North', value: 34}, {region: 'East', value: 22}, {region: 'South', value: 27}, {region: 'West', value: 17},];
export const DELIVERY_DAYS = [ 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 8, 9, 12, 15,].map((days) => ({days}));
export const PRICE_VS_RATING = [ {product: 'A', price: 12, rating: 3.9, sold: 120}, {product: 'B', price: 18, rating: 4.3, sold: 80}, {product: 'C', price: 25, rating: 4.1, sold: 150}, {product: 'D', price: 31, rating: 4.6, sold: 60}, {product: 'E', price: 44, rating: 4.4, sold: 40}, {product: 'F', price: 9, rating: 3.5, sold: 210},];
export const WEEKDAY_ORDERS = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'].flatMap( (day, d) => ['Morning', 'Afternoon', 'Evening'].map((part, p) => ({ day, part, orders: 20 + ((d * 7 + p * 11) % 23), })),);
export const TEMPERATURE_BAND = MONTHLY_SALES.map((row, i) => ({ month: row.month, low: 2 + Math.round(8 * Math.sin((i / 11) * Math.PI)), high: 8 + Math.round(14 * Math.sin((i / 11) * Math.PI)),}));
export const DELIVERY_SPREAD = [ {carrier: 'Carrier A', min: 1, q1: 2, median: 3, q3: 4, max: 7, out: [11]}, {carrier: 'Carrier B', min: 1, q1: 3, median: 4, q3: 5, max: 8, out: []}, {carrier: 'Carrier C', min: 2, q1: 3, median: 5, q3: 6, max: 9, out: [14]},];
export const BEFORE_AFTER = [ {team: 'Sales', before: 62, after: 71}, {team: 'Support', before: 74, after: 79}, {team: 'Product', before: 58, after: 66}, {team: 'Finance', before: 69, after: 68},];
export const SKILLS = [ {skill: 'Speed', teamA: 7, teamB: 5}, {skill: 'Quality', teamA: 6, teamB: 8}, {skill: 'Cost', teamA: 5, teamB: 7}, {skill: 'Service', teamA: 8, teamB: 6}, {skill: 'Range', teamA: 4, teamB: 7},];
export const SKILL_SERIES = [ {valueKey: 'teamA', name: 'Team A'}, {valueKey: 'teamB', name: 'Team B'},];
export const FUNNEL = [ {stage: 'Visited', count: 12000}, {stage: 'Viewed a product', count: 5400}, {stage: 'Added to basket', count: 1900}, {stage: 'Ordered', count: 760},];
export const PROFIT_BRIDGE = [ {step: 'Revenue', amount: 820}, {step: 'Cost of goods', amount: -410}, {step: 'Staff', amount: -190}, {step: 'Other costs', amount: -95}, {step: 'Profit', amount: null, kind: 'total' as const},];
export const PRODUCT_TREE = { label: 'Revenue', children: [ { label: 'Hardware', children: [ {label: 'Laptops', value: 210}, {label: 'Phones', value: 160}, {label: 'Accessories', value: 60}, ], }, { label: 'Services', children: [ {label: 'Support', value: 120}, {label: 'Training', value: 70}, ], }, {label: 'Software', children: [{label: 'Licences', value: 200}]}, ],};
export const ORGANISATION = { label: 'Managing director', meta: {title: 'Board'}, children: [ { label: 'Operations', meta: {title: 'Director'}, children: [ {label: 'Warehouse', meta: {title: 'Team'}}, {label: 'Transport', meta: {title: 'Team'}}, ], }, { label: 'Commerce', meta: {title: 'Director'}, children: [ {label: 'Online sales', meta: {title: 'Team'}}, {label: 'Stores', meta: {title: 'Team'}}, ], }, ],};
export const FLOW_NODES = [ {id: 'online', label: 'Online orders'}, {id: 'stores', label: 'Store sales'}, {id: 'revenue', label: 'Revenue'}, {id: 'goods', label: 'Cost of goods'}, {id: 'staff', label: 'Staff'}, {id: 'profit', label: 'Profit'},];
export const FLOW_LINKS = [ {source: 'online', target: 'revenue', value: 380}, {source: 'stores', target: 'revenue', value: 440}, {source: 'revenue', target: 'goods', value: 410}, {source: 'revenue', target: 'staff', value: 190}, {source: 'revenue', target: 'profit', value: 220},];
export const MILESTONES = [ {date: '15 Jan 2026', label: 'Plan approved', category: 'Board'}, {date: '3 Mar 2026', label: 'Supplier chosen', category: 'Operations'}, {date: '12 May 2026', label: 'Pilot store', category: 'Commerce'}, {date: '1 Sep 2026', label: 'Roll-out', category: 'Commerce'},];