Charts
Choose charts for time series, distributions, hierarchies, and maps with shared tooltips, legends, and axes.
Components in this category
Multi-series line chart with tooltips.
AreaChartStacked or single area chart.
BarChartBar chart with stacked and grouped variants.
DonutChartDonut or pie chart with center value.
PieChartFull pie (or donut) with hoverable legend.
SparklineInline chart for trends.
ScatterPlotScatter plot with tooltips.
HistogramBinned distribution histogram.
BoxPlotStatistical distribution with quartiles and outliers.
HeatmapHeatmap with color-coded cells.
CalendarHeatmapGitHub-style activity grid for time-series density.
RadarChartMulti-variable comparison on radial axes.
TreeMapHierarchical proportional data as nested tiles.
SunburstChartMulti-level hierarchy as concentric rings.
SankeyDiagramFlow and funnel visualization between nodes.
ParallelCoordinatesMulti-dimensional data exploration across axes.
SlopeGraphBefore/after comparison between two time points.
BulletChartGauge with value, target, and qualitative ranges.
FunnelChartConversion funnel visualization.
WaterfallChartRunning total waterfall chart.
CandlestickChartOHLC candlestick chart.
ChoroplethMapUS state choropleth map.
ChartTooltipHeaderHeader row for custom chart tooltips.
ChartTooltipRowData row for custom chart tooltips.
Chart types at a glance
| Prop | Type | Default | Description |
|---|---|---|---|
LineChart | Multi-series line | — | Time series with crosshair and per-series dots. |
AreaChart | Stacked / overlaid area | — | Parts of a whole over time, or overlaid measures. |
BarChart | Stacked columns | — | Per-category volumes with stacked segments. |
DonutChart | Share of total ring | — | Categorical breakdown with hoverable legend. |
Sparkline | Tiny inline line | — | Trend indicator for KPI cards and table cells. |
ScatterPlot | Two-axis correlation | — | Latency vs throughput, with optional trend line. |
Histogram | Binned distribution | — | Distribution of a single measure with percentile markers. |
Heatmap | Intensity matrix | — | Error density by shard × hour, auth rate by day × hour. |
FunnelChart | Conversion stages | — | Top-of-funnel to bottom, with per-stage conversion rates. |
WaterfallChart | Bridge / running total | — | How a metric moved from opening to closing. |
CandlestickChart | OHLC candlesticks | — | Open-high-low-close data with volume and moving averages. |
ChoroplethMap | US state tile map | — | One equal square per state, colored by value. |
Line & area charts
LineChart
See the LineChart page for detailed props and examples.
The primary time-series chart. Multiple series with crosshair hover, per-series value dots, and an optional tooltip. The chart derives its own y-domain from the data and labels the axis in rounded steps; pin either end with min/max. Hover can be controlled externally for synced crosshairs across a row of charts.
| Prop | Type | Default | Description |
|---|---|---|---|
series | ChartSeries[] | — | Series with values, color, label, optional area/dashed/strokeWidth. |
height | number | 84 | Chart height in px. |
yLabels | [string,string,string] | false | — | Axis labels, or false for no axis. |
min | number | — | Pin y-domain floor. Defaults to 0 for all-positive data. |
max | number | — | Pin y-domain ceiling. |
formatValue | (v: number) => string | — | Axis and tooltip formatter. |
xLabels | string[] | — | X-axis labels. |
legend | { label, color }[] | — | Explicit legend entries. |
renderTooltip | (index: number) => ReactNode | — | Custom hover tooltip. |
onHoverChange | (index: number | null) => void | — | Synchronise hover across charts. |
hoverIndex | number | null | — | Controlled hover index. |
import {
LineChart,
ChartTooltipHeader,
ChartTooltipRow,
} from "@solarius/onset";
<LineChart
series={[
{
label: "CPU",
values: [42, 38, 45, 52, 48, 44, 50],
color: "var(--m-color-primary)",
},
{
label: "Memory",
values: [64, 62, 66, 68, 65, 63, 67],
color: "var(--m-color-warn)",
},
]}
height={120}
renderTooltip={(i) => (
<>
<ChartTooltipHeader>14:00</ChartTooltipHeader>
<ChartTooltipRow
swatch="var(--m-color-primary)"
label="CPU"
value="45%"
/>
<ChartTooltipRow swatch="var(--m-color-warn)" label="Mem" value="66%" />
</>
)}
/>;AreaChart
See the AreaChart page for detailed props and examples.
Filled time series: stacked for parts of a whole (request types over time) or overlaid for independent measures (error rate vs throughput). Both modes share one y-axis. Two measures on different scales belong in two charts, not two axes.
| Prop | Type | Default | Description |
|---|---|---|---|
series | AreaSeries[] | — | Series with label, values, and color. |
labels | string[] | — | X-axis category labels. |
height | number | 140 | Chart height in px. |
mode | "stacked" | "overlay" | "stacked" | Stacked sums series; overlay draws on shared baseline. |
max | number | — | Upper y-axis bound. Defaults to the largest value or stacked total plus 8%. |
formatValue | (v: number) => string | — | Tick and tooltip formatter. |
ticks | number | 4 | Y tick count. |
curved | boolean | true | Monotone cubic interpolation. |
legend | boolean | true | Show legend. Hidden for single series. |
renderTooltip | (index: number) => ReactNode | — | Custom hover tooltip. |
xLabelEvery | number | — | Show every Nth x label. |
<AreaChart
mode="stacked"
legend
series={[
{
label: "GET",
values: [120, 132, 101, 134, 90, 230, 210],
color: "var(--m-color-primary)",
},
{
label: "POST",
values: [220, 182, 191, 234, 290, 330, 310],
color: "var(--m-color-ok)",
},
{
label: "Other",
values: [150, 232, 201, 154, 190, 330, 410],
color: "var(--m-color-warn)",
},
]}
labels={["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]}
/>Bar & donut charts
BarChart
See the BarChart page for detailed props and examples.
Stacked column chart for per-bucket volumes such as daily payments, hourly requests, or error counts by status code. Same card treatment, gridlines, legend, and hover-tooltip contract as LineChart.
| Prop | Type | Default | Description |
|---|---|---|---|
data | BarDatum[] | — | Data with per-bar label and stacked segments. |
height | number | 84 | Chart height in px. |
max | number | — | Upper y-axis bound. Defaults to the largest value or stacked total plus 8%. |
yLabels | [string,string,string] | — | Axis labels. |
xLabelEvery | number | — | Show every Nth x label. |
legend | { label, color }[] | — | Legend entries. |
renderTooltip | (index: number) => ReactNode | — | Custom hover tooltip. |
<BarChart
data={[
{
label: "Mon",
segments: [
{ value: 420, color: "var(--m-color-primary)" },
{ value: 180, color: "var(--m-color-ok)" },
],
},
{
label: "Tue",
segments: [
{ value: 380, color: "var(--m-color-primary)" },
{ value: 220, color: "var(--m-color-ok)" },
],
},
{
label: "Wed",
segments: [
{ value: 510, color: "var(--m-color-primary)" },
{ value: 190, color: "var(--m-color-ok)" },
],
},
]}
legend={[
{ label: "2xx", color: "var(--m-color-primary)" },
{ label: "3xx", color: "var(--m-color-ok)" },
]}
/>DonutChart
See the DonutChart page for detailed props and examples.
Share-of-total ring, for example payment methods or spend by category. Has a hoverable legend showing values and percentages. Pass noLegend for a ring-only variant.
| Prop | Type | Default | Description |
|---|---|---|---|
segments | DonutSegment[] | — | Segments with label, value, and color. |
size | number | 104 | Diameter in px. |
thickness | number | 12 | Ring thickness. |
centerLabel | ReactNode | — | Center headline. |
centerSub | ReactNode | — | Center sub label. |
formatValue | (s: DonutSegment) => ReactNode | — | Per-segment value formatter. |
noLegend | boolean | — | Hide the legend. |
<DonutChart
segments={[
{ label: "Stripe", value: 4230, color: "var(--m-color-primary)" },
{ label: "PayPal", value: 2140, color: "var(--m-color-ok)" },
{ label: "Wire", value: 1620, color: "var(--m-color-warn)" },
{ label: "Crypto", value: 410, color: "var(--m-color-info)" },
]}
centerLabel="€8,400"
centerSub="total payments"
formatValue={(s) => `€${s.value.toLocaleString()}`}
/>Sparkline
Sparkline
See the Sparkline page for detailed props and examples.
Tiny inline trend line for KPI cards and table cells. No axes or labels; the shape conveys the trend.
| Prop | Type | Default | Description |
|---|---|---|---|
values | number[] | — | Trend series. |
width | number | 72 | SVG width. |
height | number | 22 | SVG height. |
color | string | "var(--m-color-primary)" | Line color. |
strokeWidth | number | 1.25 | Line thickness. |
Scatter plot & histogram
ScatterPlot
See the ScatterPlot page for detailed props and examples.
Two-measure correlation plot, such as latency vs throughput or spend vs conversions. Optionally encode a third measure as bubble size and a fourth as group color. Set trendLine to overlay a least-squares fit.
| Prop | Type | Default | Description |
|---|---|---|---|
points | ScatterPoint[] | — | Points with x, y, optional size, label, and group. |
groups | { name, color }[] | — | Color per group. |
height | number | 200 | Chart height in px. |
xLabel | ReactNode | — | X axis label. |
yLabel | ReactNode | — | Y axis label. |
xDomain | [number,number] | — | Pin x-axis domain. |
yDomain | [number,number] | — | Pin y-axis domain. |
formatX | (v: number) => string | — | X tick formatter. |
formatY | (v: number) => string | — | Y tick formatter. |
ticks | number | 4 | Tick count. |
pointRadius | number | 4 | Marker radius when no size is given. |
trendLine | boolean | — | Overlay a least-squares fit. |
renderTooltip | (p: ScatterPoint) => ReactNode | — | Per-point hover tooltip. |
<ScatterPlot
points={[
{ x: 120, y: 45, label: "node-a" },
{ x: 340, y: 82, label: "node-b" },
{ x: 220, y: 61, label: "node-c" },
{ x: 410, y: 93, size: 80, label: "node-d" },
{ x: 180, y: 52, label: "node-e" },
]}
xLabel="Throughput (req/s)"
yLabel="P99 latency (ms)"
trendLine
/>Histogram
See the Histogram page for detailed props and examples.
Distribution of a single measure, such as request latency, order values, or file sizes. Pass raw values to have them binned automatically (Freedman–Diaconis), or pre-aggregated bins. Use markers for vertical threshold lines (p50/p95, SLO targets). The helper binValues buckets raw data and percentile computes linear-interpolated percentiles.
| Prop | Type | Default | Description |
|---|---|---|---|
values | number[] | — | Raw values for automatic binning. Use bins for pre-aggregated data. |
bins | HistogramBin[] | — | Pre-computed bins with from, to, count. |
binCount | number | — | Overrides the automatic bin count. |
height | number | 140 | Chart height in px. |
color | string | "var(--m-color-primary)" | Bar fill. |
markers | HistogramMarker[] | — | Vertical threshold lines with labels. |
formatValue | (v: number) => string | — | X axis formatter. |
ticks | number | 4 | Y tick count. |
renderTooltip | (bin: HistogramBin, i: number) => ReactNode | — | Per-bin hover tooltip. |
cumulative | boolean | — | Overlay running share line. |
import { Histogram, percentile } from "@solarius/onset";
const latencySample = [
12, 15, 18, 22, 25, 28, 28, 30, 32, 35, 42, 48, 55, 68, 82, 120, 240,
];
<Histogram
values={latencySample}
markers={[
{
value: percentile(latencySample, 0.5),
label: "p50",
color: "var(--m-color-primary)",
},
{
value: percentile(latencySample, 0.95),
label: "p95",
color: "var(--m-color-warn)",
},
]}
formatValue={(v) => `${v} ms`}
cumulative
/>;Heatmap
Heatmap
See the Heatmap page for detailed props and examples.
Heatmap displays category matrices with cell opacity derived from values from 0 to 100. Zero uses the lightest fill; 100 uses the base color.
| Prop | Type | Default | Description |
|---|---|---|---|
rows | HeatmapRow[] | — | Rows with a label and values (0-100). |
xLabels | ReactNode[] | — | Column labels. |
color | string | "var(--m-color-primary)" | Cell fill color, ramped by opacity. |
cellHeight | number | 14 | Cell height in px. |
renderTooltip | (row: number, col: number) => ReactNode | — | Per-cell hover tooltip. |
<Heatmap
rows={[
{
label: "Mon",
values: [
12, 8, 3, 2, 4, 8, 15, 22, 28, 45, 62, 78, 72, 58, 42, 35, 28, 22, 18,
15, 12, 10, 8, 6,
],
},
{
label: "Tue",
values: [
10, 6, 2, 1, 3, 6, 12, 18, 24, 38, 54, 68, 62, 52, 38, 32, 25, 20, 15,
12, 8, 6, 4, 3,
],
},
{
label: "Wed",
values: [
8, 5, 2, 1, 2, 5, 10, 15, 20, 32, 45, 58, 54, 45, 35, 28, 22, 18, 12, 8,
5, 4, 2, 1,
],
},
]}
xLabels={[
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12",
"13",
"14",
"15",
"16",
"17",
"18",
"19",
"20",
"21",
"22",
"23",
]}
color="var(--m-color-primary)"
/>Funnel & waterfall
FunnelChart
See the FunnelChart page for detailed props and examples.
Centered conversion funnel; each stage scales against the first, with per-stage conversion rates. Used for lead-to-deal, signup-to-activation, or any pipeline where each step is a subset of the previous one.
| Prop | Type | Default | Description |
|---|---|---|---|
stages | FunnelStage[] | — | Top-of-funnel first. Each has label, value, and optional meta. |
color | string | "var(--m-color-primary)" | Bar color. |
formatValue | (v: number) => string | — | Per-stage value formatter. |
showConversion | boolean | true | Show per-stage conversion rates. |
<FunnelChart
stages={[
{ label: "Impressions", value: 14200, meta: "100%" },
{ label: "Clicks", value: 3120, meta: "22% CTR" },
{ label: "Signups", value: 840 },
{ label: "Active", value: 520 },
{ label: "Paid", value: 142 },
]}
formatValue={(v) => v.toLocaleString()}
/>WaterfallChart
See the WaterfallChart page for detailed props and examples.
Bridge chart showing how a metric moved from an opening anchor to a closing one, such as a revenue bridge, headcount, or cash flow. Total bars reset the running level; delta bars move it up or down. The gap between totals is the net change.
| Prop | Type | Default | Description |
|---|---|---|---|
items | WaterfallItem[] | — | Items with label, value, and optional total flag. |
height | number | 96 | Chart height in px. |
upColor | string | "var(--m-color-ok)" | Positive delta color. |
downColor | string | "var(--m-color-err)" | Negative delta color. |
totalColor | string | "var(--m-color-border-strong)" | Total bar color. |
showValues | boolean | — | Direct +/− label above each bar. |
formatValue | (v: number) => string | — | Value formatter. |
legend | { label, color }[] | — | Legend entries. |
renderTooltip | (index: number) => ReactNode | — | Custom hover tooltip. |
<WaterfallChart
items={[
{ label: "Jan", value: 2400, total: true },
{ label: "New rev", value: 800 },
{ label: "Churn", value: -320 },
{ label: "Upgrades", value: 150 },
{ label: "Downgrades", value: -90 },
{ label: "Feb", value: 2940, total: true },
]}
showValues
formatValue={(v) => `€${Math.abs(v).toLocaleString()}`}
/>Candlestick chart
CandlestickChart
See the CandlestickChart page for detailed props and examples.
Open-High-Low-Close (OHLC) candlestick chart with an optional volume strip and moving average overlays. Up candles are filled, down candles are bordered, so the chart reads in grayscale. Set volumeHeight to 0 to hide the volume strip.
| Prop | Type | Default | Description |
|---|---|---|---|
data | Candle[] | — | OHLC candles with label, open, high, low, close, and optional volume. |
height | number | 200 | Price panel height. |
volumeHeight | number | 40 | Volume strip height. 0 hides it. |
upColor | string | "var(--m-color-ok)" | Bull candle color. |
downColor | string | "var(--m-color-err)" | Bear candle color. |
formatPrice | (v: number) => string | — | Price axis formatter. |
ticks | number | 5 | Price axis tick count. |
movingAverages | { period, color }[] | — | SMA overlays. |
renderTooltip | (candle: Candle, i: number) => ReactNode | — | Custom hover tooltip. |
xLabelEvery | number | — | Show every Nth x label. |
<CandlestickChart
data={[
{ label: "Mon", open: 100, high: 108, low: 98, close: 106, volume: 1200 },
{ label: "Tue", open: 106, high: 112, low: 104, close: 110, volume: 980 },
{ label: "Wed", open: 110, high: 114, low: 107, close: 108, volume: 1450 },
{ label: "Thu", open: 108, high: 110, low: 102, close: 104, volume: 1320 },
{ label: "Fri", open: 104, high: 118, low: 103, close: 116, volume: 2100 },
]}
height={160}
volumeHeight={30}
movingAverages={[{ period: 3, color: "var(--m-color-bright)" }]}
/>Choropleth map
ChoroplethMap
See the ChoroplethMap page for detailed props and examples.
The map uses equal-sized state tiles arranged to approximate US geography. It is a cartogram rather than a geographic projection. Regions without data render with hatching.
| Prop | Type | Default | Description |
|---|---|---|---|
data | MapRegion[] | — | Per-region values keyed by state code. |
layout | MapLayoutCell[] | US_STATE_GRID | Grid layout. Defaults to the US state tile grid. |
color | string | "var(--m-color-primary)" | Sequential ramp base color. |
steps | number | 5 | Discrete ramp steps. |
domain | [number,number] | — | Value range for the color scale. Defaults to zero through the maximum value. |
formatValue | (v: number) => string | — | Legend and tooltip formatter. |
legendLabel | ReactNode | — | Legend caption. |
showLegend | boolean | true | Show the color legend. |
showCodes | boolean | true | Print state codes inside tiles. |
tileSize | number | 26 | Tile size in px. |
onSelect | (region: MapRegion, cell: MapLayoutCell) => void | — | Tile click handler. |
renderTooltip | (region: MapRegion | null, cell: MapLayoutCell) => ReactNode | — | Per-tile hover tooltip. |
import { ChoroplethMap } from "@solarius/onset";
<ChoroplethMap
data={[
{ code: "CA", value: 89200 },
{ code: "TX", value: 67400 },
{ code: "NY", value: 52100 },
{ code: "FL", value: 41300 },
{ code: "IL", value: 31200 },
{ code: "WA", value: 28800 },
... // one entry per state or pass only the states you have data for
]}
legendLabel="Revenue per state"
formatValue={(v) => `€${v.toLocaleString()}`}
/>