chart gallery
Chart Zoom, Pan and Measure Tool, Live
Zoom into a long history and the table follows, then measure a move between two points. Both are live below, with the code that drives them.
Chart zoom, pan and follow
Give a chart zoom and a reader can narrow it to the stretch they care about with the wheel, a drag, a pinch or the buttons. Add viewportFilter and the grid follows: once the zoom settles, the table and every other chart over the same grid show only the rows in view. On a time axis that is the dates in range, and on a category axis it is the categories left on screen. Zoom back out, or clear the filter in the grid, and everything returns. Use it for long histories, busy time series and any chart where the table should answer what exactly is in this window.
Try it. Zoom the line with the wheel, and the bars with the zoom-in button that appears when you hover over them. The grid narrows to the rows in view. Reset with the 0 key or a double-click.
See it in a whole application: zoom, measure and annotate a chart.
The code
createChart({
grid,
container: containers[0],
type: 'line',
x: 'day',
y: 'sessions',
axis: { x: { scale: 'time' } },
zoom: true,
viewportFilter: true,
title: 'Sessions by day',
});
createChart({
grid,
container: containers[1],
type: 'bar',
x: 'channel',
y: 'sessions',
zoom: true,
viewportFilter: true,
title: 'Sessions by channel',
});
Options used:
zoom, viewportFilter
Sample data
({
columns: [
{ field: 'day', title: 'Day', type: 'datetime', layout: { width: 140 } },
{ field: 'channel', title: 'Channel' },
{ field: 'sessions', title: 'Sessions', type: 'number' },
],
rows: ['Search', 'Email', 'Social', 'Direct', 'Referral', 'Paid', 'Video', 'Partner'].flatMap((channel, c) =>
Array.from({ length: 21 }, (v, d) => ({
id: channel + d,
day: new Date(Date.UTC(2026, 8, 1 + d)),
channel,
sessions: Math.round(120 + c * 35 + 60 * Math.sin((d + c) / 3) + d * (4 - (c % 3))),
}))),
})
Chart measure tool
The measure tool turns a chart into a ruler. Press its button, or M with the chart focused, then drag between two points and a band appears with the change in time, the change in value, the percentage change and the slope. Ends snap to the nearest reading. Press Enter or click the band to pin it, and a pinned measurement stays put as you zoom and pan. One button covers three readings: set axes to x for the span between two points, y for the rise or fall, or xy for both at once. Use it on prices, usage or any series where someone asks how much, and how fast.
Try it. Press the measure button, or M with the chart focused, then drag between two points. Press Enter to pin the measurement.
See it in a whole application: zoom, measure and annotate a chart.
The code
createChart({
grid,
container,
type: 'line',
x: 'at',
y: 'close',
axis: { x: { scale: 'time' } },
measure: { axes: 'xy' },
title: 'Closing price',
});
Options used:
measure, measure.axes
Sample data
({
columns: [
{ field: 'at', title: 'Date', type: 'datetime', layout: { width: 140 } },
{ field: 'close', title: 'Close', type: 'number' },
],
rows: Array.from({ length: 30 }, (v, i) => ({
id: i,
at: new Date(Date.UTC(2026, 8, 1 + i)),
close: Math.round((100 + i * 1.2 + 9 * Math.sin(i / 2.5)) * 10) / 10,
})),
})
Freehand pen on a chart
The pen lets a reader mark up a chart the way they would a printout. Press, drag and release to draw a smooth freehand stroke, then select it to move it, or delete it like any other drawing. The stroke is anchored to the data rather than to the screen, so when you zoom, pan or resize the chart it stays on the same readings instead of floating away. Strokes are saved with the chart and come back when it is restored, and each one is announced through the chart events. Use it for reviews, handovers and any chart where someone needs to circle what matters.
Try it. Pick the pen on the left rail and circle the part of the line you want to flag. Then zoom with the wheel: the stroke stays on the readings you drew it over.
See it in a whole application: zoom, measure and annotate a chart.
The code
createChart({
grid,
container,
type: 'line',
x: 'at',
y: 'close',
axis: { x: { scale: 'time' } },
annotate: { tools: ['select', 'pen', 'delete'], pen: { width: 3 } },
zoom: true,
title: 'Closing price',
});
Options used:
annotate, annotate.pen, zoom
Sample data
({
columns: [
{ field: 'at', title: 'Date', type: 'datetime', layout: { width: 140 } },
{ field: 'close', title: 'Close', type: 'number' },
],
rows: Array.from({ length: 30 }, (v, i) => ({
id: i,
at: new Date(Date.UTC(2026, 8, 1 + i)),
close: Math.round((100 + i * 1.2 + 9 * Math.sin(i / 2.5)) * 10) / 10,
})),
})
Every chart type, live → The charts API reference → How a chart binds to a grid →