Skip to content

Charts

Every chart is keyboard navigable: tab to a chart, then use the arrow keys to move between points — each one is read aloud. Press “Show data table” under any chart to see the numbers as a table. Colours follow the theme and charts mirror in RTL.

Keyboard: press Tab to focus a chart, then Arrow Left / Right to move between points and Arrow Up / Down to switch series. Home and End jump to the ends, Escape hides the tooltip. Every chart also has a “Show data table” button.

15 components on this page. Every demo is live — change the theme in the header or flip a demo to right-to-left with its RTL button. These components are React-only for now; Vue, Svelte and Angular versions are coming.

BarChart Link to BarChart

Grouped or stacked bars, vertical or horizontal.

Props

PropTypeDescription
title ReactNode Caption and accessible name (required).
description / summary ReactNode Extra context; summary overrides the automatic one.
table 'toggle' | 'visible' | 'none' Data-table fallback. Default toggle.
valueFormat / locale Intl.NumberFormatOptions | fn / string Number formatting (e.g. currency, compact).
data / x / series T[] / keyof T | fn / { key, label, value? }[] Data, category accessor and series.
orientation 'vertical' | 'horizontal' Bar direction.
stacked boolean Stack the series.
directLabels boolean Print values on the bars.

Accessibility

BarChart keyboard support
KeyAction
Tab Focus the plot (one tab stop per chart)
Arrow Left / Arrow Right Previous / next data point (mirrored in RTL)
Arrow Up / Arrow Down Switch series
Home / End First / last point
Escape Hide the tooltip

A <figure> with caption and an automatic text summary. The focused point is announced in a live region, patterns back up colour, and “Show data table” reveals the numbers as a real table.

Code

ReactComing to Vue, Svelte and Angular.

BarChart · React
<BarChart title="Revenue by quarter" data={revenue} x="quarter"
  series={[{ key: 'product', label: 'Product' }, { key: 'services', label: 'Services' }]}
  valueFormat={{ style: 'currency', currency: 'USD', notation: 'compact' }} />

LineChart Link to LineChart

Trends over time with band, time or linear x scales and smooth or step curves.

Props

PropTypeDescription
title ReactNode Caption and accessible name (required).
description / summary ReactNode Extra context; summary overrides the automatic one.
table 'toggle' | 'visible' | 'none' Data-table fallback. Default toggle.
valueFormat / locale Intl.NumberFormatOptions | fn / string Number formatting (e.g. currency, compact).
data / x / series … As BarChart.
xScale 'auto' | 'band' | 'time' | 'linear' X axis type.
curve 'linear' | 'monotone' | 'step' Line shape.
markers boolean | 'auto' Point markers.

Accessibility

LineChart keyboard support
KeyAction
Tab Focus the plot (one tab stop per chart)
Arrow Left / Arrow Right Previous / next data point (mirrored in RTL)
Arrow Up / Arrow Down Switch series
Home / End First / last point
Escape Hide the tooltip

A <figure> with caption and an automatic text summary. The focused point is announced in a live region, patterns back up colour, and “Show data table” reveals the numbers as a real table.

Code

ReactComing to Vue, Svelte and Angular.

LineChart · React
<LineChart title="Monthly active users" data={users} x="month" curve="monotone"
  series={[{ key: 'web', label: 'Web' }, { key: 'mobile', label: 'Mobile' }]}
  valueFormat={{ notation: 'compact' }} />

AreaChart Link to AreaChart

Stacked or overlapping areas with optional gradient fill.

Props

PropTypeDescription
title ReactNode Caption and accessible name (required).
description / summary ReactNode Extra context; summary overrides the automatic one.
table 'toggle' | 'visible' | 'none' Data-table fallback. Default toggle.
valueFormat / locale Intl.NumberFormatOptions | fn / string Number formatting (e.g. currency, compact).
mode 'stacked' | 'overlap' How series combine.
gradient boolean Gradient fill.

Accessibility

AreaChart keyboard support
KeyAction
Tab Focus the plot (one tab stop per chart)
Arrow Left / Arrow Right Previous / next data point (mirrored in RTL)
Arrow Up / Arrow Down Switch series
Home / End First / last point
Escape Hide the tooltip

A <figure> with caption and an automatic text summary. The focused point is announced in a live region, patterns back up colour, and “Show data table” reveals the numbers as a real table.

Code

ReactComing to Vue, Svelte and Angular.

AreaChart · React
<AreaChart title="Traffic by source" data={traffic} x="day" mode="stacked" gradient
  series={[{ key: 'organic', label: 'Organic' }, { key: 'social', label: 'Social' }, { key: 'paid', label: 'Paid' }]} />

ComboChart Link to ComboChart

Bars and lines together, with an optional secondary axis.

Props

PropTypeDescription
title ReactNode Caption and accessible name (required).
description / summary ReactNode Extra context; summary overrides the automatic one.
table 'toggle' | 'visible' | 'none' Data-table fallback. Default toggle.
valueFormat / locale Intl.NumberFormatOptions | fn / string Number formatting (e.g. currency, compact).
series { key, label, type: "bar" | "line", axis?: "primary" | "secondary" }[] Mixed series.
secondaryFormat / primaryLabel / secondaryLabel … Axis formatting and titles.

Accessibility

ComboChart keyboard support
KeyAction
Tab Focus the plot (one tab stop per chart)
Arrow Left / Arrow Right Previous / next data point (mirrored in RTL)
Arrow Up / Arrow Down Switch series
Home / End First / last point
Escape Hide the tooltip

A <figure> with caption and an automatic text summary. The focused point is announced in a live region, patterns back up colour, and “Show data table” reveals the numbers as a real table.

Code

ReactComing to Vue, Svelte and Angular.

ComboChart · React
<ComboChart title="Orders and conversion" data={orders} x="month"
  series={[{ key: 'orders', label: 'Orders', type: 'bar' },
           { key: 'conversion', label: 'Conversion', type: 'line', axis: 'secondary' }]}
  secondaryFormat={{ style: 'percent' }} />

PieChart Link to PieChart

Parts of a whole; small slices are grouped into “Other”.

Props

PropTypeDescription
title ReactNode Caption and accessible name (required).
description / summary ReactNode Extra context; summary overrides the automatic one.
table 'toggle' | 'visible' | 'none' Data-table fallback. Default toggle.
valueFormat / locale Intl.NumberFormatOptions | fn / string Number formatting (e.g. currency, compact).
data / label / value T[] / accessor / accessor Slices.
otherThreshold / maxSlices number Group small slices.
sort boolean Largest first.

Accessibility

PieChart keyboard support
KeyAction
Tab Focus the plot (one tab stop per chart)
Arrow Left / Arrow Right Previous / next data point (mirrored in RTL)
Arrow Up / Arrow Down Switch series
Home / End First / last point
Escape Hide the tooltip

A <figure> with caption and an automatic text summary. The focused point is announced in a live region, patterns back up colour, and “Show data table” reveals the numbers as a real table.

Code

ReactComing to Vue, Svelte and Angular.

PieChart · React
<PieChart title="Traffic sources" data={sources} label="source" value="visits" />

DonutChart Link to DonutChart

A pie with a hole for a headline number.

Props

PropTypeDescription
title ReactNode Caption and accessible name (required).
description / summary ReactNode Extra context; summary overrides the automatic one.
table 'toggle' | 'visible' | 'none' Data-table fallback. Default toggle.
valueFormat / locale Intl.NumberFormatOptions | fn / string Number formatting (e.g. currency, compact).
innerRadius number (0–1) Hole size. Default 0.6.
centerLabel / centerSubLabel ReactNode Text in the middle.

Accessibility

DonutChart keyboard support
KeyAction
Tab Focus the plot (one tab stop per chart)
Arrow Left / Arrow Right Previous / next data point (mirrored in RTL)
Arrow Up / Arrow Down Switch series
Home / End First / last point
Escape Hide the tooltip

A <figure> with caption and an automatic text summary. The focused point is announced in a live region, patterns back up colour, and “Show data table” reveals the numbers as a real table.

Code

ReactComing to Vue, Svelte and Angular.

DonutChart · React
<DonutChart title="Plan mix" data={plans} label="plan" value="users"
  centerLabel="12.4k" centerSubLabel="users" />

ScatterChart Link to ScatterChart

Relationships between two measures, grouped by category with distinct marker shapes.

Props

PropTypeDescription
title ReactNode Caption and accessible name (required).
description / summary ReactNode Extra context; summary overrides the automatic one.
table 'toggle' | 'visible' | 'none' Data-table fallback. Default toggle.
valueFormat / locale Intl.NumberFormatOptions | fn / string Number formatting (e.g. currency, compact).
x / y accessor Numeric axes.
group / pointLabel accessor Series grouping and point names.
xLabel / yLabel string Axis titles.

Accessibility

ScatterChart keyboard support
KeyAction
Tab Focus the plot (one tab stop per chart)
Arrow Left / Arrow Right Previous / next data point (mirrored in RTL)
Arrow Up / Arrow Down Switch series
Home / End First / last point
Escape Hide the tooltip

A <figure> with caption and an automatic text summary. The focused point is announced in a live region, patterns back up colour, and “Show data table” reveals the numbers as a real table.

Code

ReactComing to Vue, Svelte and Angular.

ScatterChart · React
<ScatterChart title="Session length vs pages" data={sessions} x="minutes" y="pages"
  group="device" pointLabel="id" xLabel="Minutes" yLabel="Pages" />

BubbleChart Link to BubbleChart

A scatter chart whose point size encodes a third value.

Props

PropTypeDescription
title ReactNode Caption and accessible name (required).
description / summary ReactNode Extra context; summary overrides the automatic one.
table 'toggle' | 'visible' | 'none' Data-table fallback. Default toggle.
valueFormat / locale Intl.NumberFormatOptions | fn / string Number formatting (e.g. currency, compact).
size accessor Bubble size value (required).
minRadius / maxRadius / sizeLabel number / string Size scale.

Accessibility

BubbleChart keyboard support
KeyAction
Tab Focus the plot (one tab stop per chart)
Arrow Left / Arrow Right Previous / next data point (mirrored in RTL)
Arrow Up / Arrow Down Switch series
Home / End First / last point
Escape Hide the tooltip

A <figure> with caption and an automatic text summary. The focused point is announced in a live region, patterns back up colour, and “Show data table” reveals the numbers as a real table.

Code

ReactComing to Vue, Svelte and Angular.

BubbleChart · React
<BubbleChart title="Markets" data={markets} x="growth" y="margin" size="revenue"
  pointLabel="country" xLabel="Growth %" yLabel="Margin %" sizeLabel="Revenue" />

RadarChart Link to RadarChart

Compare several series across the same set of dimensions.

Props

PropTypeDescription
title ReactNode Caption and accessible name (required).
description / summary ReactNode Extra context; summary overrides the automatic one.
table 'toggle' | 'visible' | 'none' Data-table fallback. Default toggle.
valueFormat / locale Intl.NumberFormatOptions | fn / string Number formatting (e.g. currency, compact).
data / x / series … Axes are the x categories.
max number Outer ring value.

Accessibility

RadarChart keyboard support
KeyAction
Tab Focus the plot (one tab stop per chart)
Arrow Left / Arrow Right Previous / next data point (mirrored in RTL)
Arrow Up / Arrow Down Switch series
Home / End First / last point
Escape Hide the tooltip

A <figure> with caption and an automatic text summary. The focused point is announced in a live region, patterns back up colour, and “Show data table” reveals the numbers as a real table.

Code

ReactComing to Vue, Svelte and Angular.

RadarChart · React
<RadarChart title="Framework scores" data={scores} x="metric" max={10}
  series={[{ key: 'pelagic', label: 'Pelagic UI' }, { key: 'other', label: 'Average' }]} />

Heatmap Link to Heatmap

Values on a grid of two categories — plus calendarHeatmapData() for GitHub-style calendars.

Props

PropTypeDescription
title ReactNode Caption and accessible name (required).
description / summary ReactNode Extra context; summary overrides the automatic one.
table 'toggle' | 'visible' | 'none' Data-table fallback. Default toggle.
valueFormat / locale Intl.NumberFormatOptions | fn / string Number formatting (e.g. currency, compact).
data / x / y / value T[] / accessors Cells.
xCategories / yCategories string[] Order of rows and columns.
showValues boolean Print values in cells.
calendarHeatmapData(entries) helper Turns { date, value }[] into weeks × weekdays.

Accessibility

Heatmap keyboard support
KeyAction
Tab Focus the plot (one tab stop per chart)
Arrow Left / Arrow Right Previous / next data point (mirrored in RTL)
Arrow Up / Arrow Down Switch series
Home / End First / last point
Escape Hide the tooltip

A <figure> with caption and an automatic text summary. The focused point is announced in a live region, patterns back up colour, and “Show data table” reveals the numbers as a real table.

Code

ReactComing to Vue, Svelte and Angular.

Heatmap · React
<Heatmap title="Visits by hour" data={visits} x="hour" y="day" value="count" showValues />

const cal = calendarHeatmapData(commits);
<Heatmap title="Contributions" {...cal} x="week" y="weekday" value="value" cellLabel="label" />

GaugeChart Link to GaugeChart

A single value against a range, with coloured thresholds and a target.

Props

PropTypeDescription
title / value ReactNode / number Required.
min / max / target number Scale and target marker.
thresholds { upTo, tone }[] Coloured bands.
variant 'semi' | 'radial' Shape.

Accessibility

The summary states the value, percentage and distance from the target (“72 of 100 (72%). Target 80: 8 below target.”).

Code

ReactComing to Vue, Svelte and Angular.

GaugeChart · React
<GaugeChart title="Server load" value={72} target={80} valueFormat={{ style: 'unit', unit: 'percent' }}
  thresholds={[{ upTo: 60, tone: 'success' }, { upTo: 85, tone: 'warning' }, { upTo: 100, tone: 'danger' }]} />

RadialProgress Link to RadialProgress

A full-circle gauge for goals and completion.

Props

PropTypeDescription
title / value / max … As GaugeChart.
size number Diameter (px).

Accessibility

Code

ReactComing to Vue, Svelte and Angular.

RadialProgress · React
<RadialProgress title="Quarterly goal" value={68} max={100} size={160} />

WaterfallChart Link to WaterfallChart

How a starting value becomes an ending value through increases and decreases.

Props

PropTypeDescription
title ReactNode Required.
data { label, value, total? }[] Steps; total marks subtotal bars.
increaseLabel / decreaseLabel / totalLabel string Legend text.
valueFormat ValueFormat Number format.

Accessibility

WaterfallChart keyboard support
KeyAction
Tab Focus the plot (one tab stop per chart)
Arrow Left / Arrow Right Previous / next data point (mirrored in RTL)
Arrow Up / Arrow Down Switch series
Home / End First / last point
Escape Hide the tooltip

A <figure> with caption and an automatic text summary. The focused point is announced in a live region, patterns back up colour, and “Show data table” reveals the numbers as a real table.

Code

ReactComing to Vue, Svelte and Angular.

WaterfallChart · React
<WaterfallChart title="Profit bridge" valueFormat={{ style: 'currency', currency: 'USD', notation: 'compact' }}
  data={[{ label: 'Revenue', value: 420000, total: true }, { label: 'COGS', value: -160000 }, { label: 'Profit', value: 260000, total: true }]} />

Sparkline Link to Sparkline

A tiny inline trend line for tables and stat cards.

Props

PropTypeDescription
data number[] Values.
label / period string Used in the generated text summary.
area / showEnd boolean Fill and end dot.
tone ChartTone Colour.

Accessibility

role="img" with a generated text summary of the trend as its accessible name.

Code

ReactComing to Vue, Svelte and Angular.

Sparkline · React
<Sparkline data={[12, 14, 13, 17, 19, 18, 24]} label="Signups" period="last 7 days" area showEnd />

Chart primitives Link to Chart primitives

Build your own chart from ChartContainer, ChartPlot, scales, Axis, Gridlines, series, ReferenceLine, Annotation and Legend — accessibility included.

Props

PropTypeDescription
ChartContainer title, summary, legend, tableData, children(frame) Accessible shell; measures width.
ChartPlot points ChartPoint[][] Keyboard navigation, tooltip and announcements.
linearScale / bandScale / timeScale functions Scales with ticks and invert.
Axis / Gridlines scale, position / orientation Axes and grid.
BarSeries / LineSeries / AreaSeries / PointSeries / ArcSeries geometry Marks.
ReferenceLine / Annotation / Legend … Context.

Accessibility

Chart primitives keyboard support
KeyAction
Tab Focus the plot (one tab stop per chart)
Arrow Left / Arrow Right Previous / next data point (mirrored in RTL)
Arrow Up / Arrow Down Switch series
Home / End First / last point
Escape Hide the tooltip

Code

ReactComing to Vue, Svelte and Angular.

Chart primitives · React
<ChartContainer title="Visitors" tableData={table}>
  {(frame) => {
    const x = bandScale(days, frame.rtl ? [frame.innerWidth, 0] : [0, frame.innerWidth]);
    const y = linearScale([0, max], [frame.innerHeight, 0], { nice: true });
    return (
      <ChartPlot points={[days.map((d, i) => ({ x: x.center(d), y: y(values[i]), title: d, series: 'Visitors', value: String(values[i]) }))]}>
        <Gridlines scale={y} orientation="horizontal" />
        <BarSeries bars={days.map((d, i) => ({ x: x(d), y: y(values[i]), width: x.bandwidth, height: y(0) - y(values[i]) }))} />
        <ReferenceLine y={y(target)} label="Target" dashed />
        <Axis scale={x} position="bottom" />
        <Axis scale={y} position="start" />
      </ChartPlot>
    );
  }}
</ChartContainer>

Search Pelagic UI