chart gallery
Lollipop, 100% Stacked, Smoothed and Half Pie Charts
Five variations on the familiar charts, each a single option on a chart you already use.
Lollipop chart
A lollipop chart draws each category as a thin stem with a dot at the value, a lighter alternative to a solid column. It is easier on the eye when there are many categories or when the values matter more than the bulk, and it leaves room for labels. It is a mark on the bar chart rather than a separate type, so everything else a bar does still applies: several measures sit side by side, sorting and axes work as before, and the tooltip, legend and keyboard stops are the same. Use it for ranked lists and for dashboards with a lot going on.
The code
createChart({
grid,
container,
type: 'bar',
mark: 'lollipop',
x: 'month',
y: 'tickets',
title: 'Support tickets by month',
});
Options used:
mark: 'lollipop', sort
Sample data
({
columns: [
{ field: 'month', title: 'Month' },
{ field: 'tickets', title: 'Tickets', type: 'number' },
],
rows: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'].map((month, i) => ({
id: i,
month,
tickets: [118, 96, 124, 140, 163, 189, 205, 198, 171, 150, 132, 177][i],
})),
})
100% stacked bar chart
A 100% stacked chart makes every column the same full height and splits it by share, so you compare the mix rather than the total. Use it when the question is how the split changed, such as each region’s share of sales by quarter, and the totals would only distract. The measure axis reads zero to one hundred percent and the tooltip shows each series’ real value beside its share, so nothing is hidden. It works on bar, horizontal bar, area and combo charts, and follows the grid’s filter like every other chart.
The code
createChart({
grid,
container,
type: 'bar',
x: 'q',
y: 'sales',
series: 'region',
stack: 'percent',
title: 'Share of sales by quarter',
});
Options used:
stack: 'percent', series
Sample data
({
columns: [
{ field: 'q', title: 'Quarter' },
{ field: 'region', title: 'Region' },
{ field: 'sales', title: 'Sales (k)', type: 'number' },
],
rows: [
['Q1', [120, 90, 70]], ['Q2', [150, 110, 85]], ['Q3', [135, 125, 95]], ['Q4', [180, 140, 120]],
].flatMap(([q, v]) => ['North', 'South', 'East'].map((region, i) => ({ id: q + region, q, region, sales: v[i] }))),
})
Smoothed line chart
Line and area charts can be smoothed so a trend reads as a curve instead of a zig-zag. Choose a monotone curve, which never overshoots the data, a Catmull-Rom spline, or a step, for the whole chart or one series at a time. Markers and the tooltip stay on the real readings, so smoothing changes the look and never the numbers. Use it for slow-moving measures such as load, temperature or demand, where the shape of the trend is the message and the jitter between samples is not.
The code
createChart({
grid,
container,
type: 'area',
x: 't',
y: 'cpu',
curve: 'monotone',
axis: { x: { scale: 'linear' } },
title: 'CPU (%) by minute',
});
Options used:
curve
Sample data
({
columns: [
{ field: 't', title: 'Minute', type: 'number' },
{ field: 'cpu', title: 'CPU (%)', type: 'number' },
{ field: 'latency', title: 'Latency (ms)', type: 'number' },
],
rows: Array.from({ length: 30 }, (_, t) => ({
id: t,
t,
cpu: Math.round(38 + 30 * Math.exp(-Math.pow(t - 18, 2) / 40) + 6 * Math.sin(t * 1.3)),
latency: Math.round(120 + 260 * Math.exp(-Math.pow(t - 19, 2) / 30) + 14 * Math.cos(t * 1.1)),
})),
})
Half pie and donut chart
A pie or donut does not have to be a full circle. Set the start and end angles and the chart becomes a semicircle or any partial arc, scaled to fill its box so a half circle uses the full height instead of leaving half the pane empty. It is a compact way to show a share of a total on a dashboard, and the labels, legend and hover all follow the arc. With a donut the hole stays free for a total or a label. Use a half donut where space is tight or where a gauge-like read suits the figure.
The code
createChart({
grid,
container,
type: 'donut',
x: 'region',
y: 'revenue',
startAngle: -90,
endAngle: 90,
title: 'Revenue by region (k)',
});
Options used:
startAngle, endAngle
Sample data
({
columns: [
{ field: 'region', title: 'Region' },
{ field: 'revenue', title: 'Revenue (k)', type: 'number' },
{ field: 'margin', title: 'Margin (k)', type: 'number' },
],
rows: [
{ id: 1, region: 'North', revenue: 420, margin: 120 },
{ id: 2, region: 'South', revenue: 310, margin: 40 },
{ id: 3, region: 'East', revenue: 250, margin: 95 },
{ id: 4, region: 'West', revenue: 180, margin: 30 },
{ id: 5, region: 'Central', revenue: 90, margin: 55 },
],
})
Variable-radius pie chart
A variable-radius pie carries two numbers in one chart. The angle of each slice still comes from the first measure, such as revenue, while a second measure, such as margin, sets how far the slice reaches from the centre. Big slices with short reach are easy to spot, and so are small slices that punch above their weight. The radius is area-true by default, so the picture does not exaggerate, and the tooltip shows both values. Use it when a single share-of-total chart is hiding the thing you actually want to compare.
The code
createChart({
grid,
container,
type: 'pie',
x: 'region',
y: 'revenue',
radius: { col: 'margin' },
title: 'Revenue (angle) and margin (reach)',
});
Options used:
radius
Sample data
({
columns: [
{ field: 'region', title: 'Region' },
{ field: 'revenue', title: 'Revenue (k)', type: 'number' },
{ field: 'margin', title: 'Margin (k)', type: 'number' },
],
rows: [
{ id: 1, region: 'North', revenue: 420, margin: 120 },
{ id: 2, region: 'South', revenue: 310, margin: 40 },
{ id: 3, region: 'East', revenue: 250, margin: 95 },
{ id: 4, region: 'West', revenue: 180, margin: 30 },
{ id: 5, region: 'Central', revenue: 90, margin: 55 },
],
})
Every chart type, live → The charts API reference → How a chart binds to a grid →