Active Foundation · Example
Every chart family
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> );}