Charts
Components

Charts

Choose charts for time series, distributions, hierarchies, and maps with shared tooltips, legends, and axes.

Components in this category

Chart types at a glance

Chart components props
PropTypeDefaultDescription
LineChartMulti-series line—Time series with crosshair and per-series dots.
AreaChartStacked / overlaid area—Parts of a whole over time, or overlaid measures.
BarChartStacked columns—Per-category volumes with stacked segments.
DonutChartShare of total ring—Categorical breakdown with hoverable legend.
SparklineTiny inline line—Trend indicator for KPI cards and table cells.
ScatterPlotTwo-axis correlation—Latency vs throughput, with optional trend line.
HistogramBinned distribution—Distribution of a single measure with percentile markers.
HeatmapIntensity matrix—Error density by shard × hour, auth rate by day × hour.
FunnelChartConversion stages—Top-of-funnel to bottom, with per-stage conversion rates.
WaterfallChartBridge / running total—How a metric moved from opening to closing.
CandlestickChartOHLC candlesticks—Open-high-low-close data with volume and moving averages.
ChoroplethMapUS 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.

LineChart props props
PropTypeDefaultDescription
seriesChartSeries[]—Series with values, color, label, optional area/dashed/strokeWidth.
heightnumber84Chart height in px.
yLabels[string,string,string] | false—Axis labels, or false for no axis.
minnumber—Pin y-domain floor. Defaults to 0 for all-positive data.
maxnumber—Pin y-domain ceiling.
formatValue(v: number) => string—Axis and tooltip formatter.
xLabelsstring[]—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.
hoverIndexnumber | null—Controlled hover index.
LineChart exampleTSX
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.

AreaChart props props
PropTypeDefaultDescription
seriesAreaSeries[]—Series with label, values, and color.
labelsstring[]—X-axis category labels.
heightnumber140Chart height in px.
mode"stacked" | "overlay""stacked"Stacked sums series; overlay draws on shared baseline.
maxnumber—Upper y-axis bound. Defaults to the largest value or stacked total plus 8%.
formatValue(v: number) => string—Tick and tooltip formatter.
ticksnumber4Y tick count.
curvedbooleantrueMonotone cubic interpolation.
legendbooleantrueShow legend. Hidden for single series.
renderTooltip(index: number) => ReactNode—Custom hover tooltip.
xLabelEverynumber—Show every Nth x label.
AreaChart exampleTSX
<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.

BarChart props props
PropTypeDefaultDescription
dataBarDatum[]—Data with per-bar label and stacked segments.
heightnumber84Chart height in px.
maxnumber—Upper y-axis bound. Defaults to the largest value or stacked total plus 8%.
yLabels[string,string,string]—Axis labels.
xLabelEverynumber—Show every Nth x label.
legend{ label, color }[]—Legend entries.
renderTooltip(index: number) => ReactNode—Custom hover tooltip.
BarChart exampleTSX
<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.

DonutChart props props
PropTypeDefaultDescription
segmentsDonutSegment[]—Segments with label, value, and color.
sizenumber104Diameter in px.
thicknessnumber12Ring thickness.
centerLabelReactNode—Center headline.
centerSubReactNode—Center sub label.
formatValue(s: DonutSegment) => ReactNode—Per-segment value formatter.
noLegendboolean—Hide the legend.
DonutChart exampleTSX
<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.

Sparkline props props
PropTypeDefaultDescription
valuesnumber[]—Trend series.
widthnumber72SVG width.
heightnumber22SVG height.
colorstring"var(--m-color-primary)"Line color.
strokeWidthnumber1.25Line thickness.
Sparkline

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.

ScatterPlot props props
PropTypeDefaultDescription
pointsScatterPoint[]—Points with x, y, optional size, label, and group.
groups{ name, color }[]—Color per group.
heightnumber200Chart height in px.
xLabelReactNode—X axis label.
yLabelReactNode—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.
ticksnumber4Tick count.
pointRadiusnumber4Marker radius when no size is given.
trendLineboolean—Overlay a least-squares fit.
renderTooltip(p: ScatterPoint) => ReactNode—Per-point hover tooltip.
ScatterPlot exampleTSX
<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.

Histogram props props
PropTypeDefaultDescription
valuesnumber[]—Raw values for automatic binning. Use bins for pre-aggregated data.
binsHistogramBin[]—Pre-computed bins with from, to, count.
binCountnumber—Overrides the automatic bin count.
heightnumber140Chart height in px.
colorstring"var(--m-color-primary)"Bar fill.
markersHistogramMarker[]—Vertical threshold lines with labels.
formatValue(v: number) => string—X axis formatter.
ticksnumber4Y tick count.
renderTooltip(bin: HistogramBin, i: number) => ReactNode—Per-bin hover tooltip.
cumulativeboolean—Overlay running share line.
Histogram exampleTSX
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.

Heatmap props props
PropTypeDefaultDescription
rowsHeatmapRow[]—Rows with a label and values (0-100).
xLabelsReactNode[]—Column labels.
colorstring"var(--m-color-primary)"Cell fill color, ramped by opacity.
cellHeightnumber14Cell height in px.
renderTooltip(row: number, col: number) => ReactNode—Per-cell hover tooltip.
Heatmap exampleTSX
<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.

FunnelChart props props
PropTypeDefaultDescription
stagesFunnelStage[]—Top-of-funnel first. Each has label, value, and optional meta.
colorstring"var(--m-color-primary)"Bar color.
formatValue(v: number) => string—Per-stage value formatter.
showConversionbooleantrueShow per-stage conversion rates.
FunnelChart exampleTSX
<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.

WaterfallChart props props
PropTypeDefaultDescription
itemsWaterfallItem[]—Items with label, value, and optional total flag.
heightnumber96Chart height in px.
upColorstring"var(--m-color-ok)"Positive delta color.
downColorstring"var(--m-color-err)"Negative delta color.
totalColorstring"var(--m-color-border-strong)"Total bar color.
showValuesboolean—Direct +/− label above each bar.
formatValue(v: number) => string—Value formatter.
legend{ label, color }[]—Legend entries.
renderTooltip(index: number) => ReactNode—Custom hover tooltip.
WaterfallChart exampleTSX
<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.

CandlestickChart props props
PropTypeDefaultDescription
dataCandle[]—OHLC candles with label, open, high, low, close, and optional volume.
heightnumber200Price panel height.
volumeHeightnumber40Volume strip height. 0 hides it.
upColorstring"var(--m-color-ok)"Bull candle color.
downColorstring"var(--m-color-err)"Bear candle color.
formatPrice(v: number) => string—Price axis formatter.
ticksnumber5Price axis tick count.
movingAverages{ period, color }[]—SMA overlays.
renderTooltip(candle: Candle, i: number) => ReactNode—Custom hover tooltip.
xLabelEverynumber—Show every Nth x label.
CandlestickChart exampleTSX
<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.

ChoroplethMap props props
PropTypeDefaultDescription
dataMapRegion[]—Per-region values keyed by state code.
layoutMapLayoutCell[]US_STATE_GRIDGrid layout. Defaults to the US state tile grid.
colorstring"var(--m-color-primary)"Sequential ramp base color.
stepsnumber5Discrete 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.
legendLabelReactNode—Legend caption.
showLegendbooleantrueShow the color legend.
showCodesbooleantruePrint state codes inside tiles.
tileSizenumber26Tile size in px.
onSelect(region: MapRegion, cell: MapLayoutCell) => void—Tile click handler.
renderTooltip(region: MapRegion | null, cell: MapLayoutCell) => ReactNode—Per-tile hover tooltip.
ChoroplethMap exampleTSX
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()}`}
/>