Skip to content

Link charts

Synchronize chart windows and hover through the shared Charts API. This feature belongs to @revolist/charts and can be used without Pivot or a grid.

Choose Link charts, then Zoom first chart or hover either chart. The second chart follows the linked X window and hover. Choose Unlink charts and repeat: the charts now act independently.

The buttons here are example application UI. Pivot’s built-in “Link charts” dropdown discovers open Pivot charts and calls the same shared synchronization API.

Loading chart…

Inspect live chart state

The chart uses the native Charts renderer. Buttons outside the plot are example application controls calling the public API.

Complete chart setup with sample data

Install Charts using the installation guide, then run this setup after the host mounts. The data is illustrative. Additional actions for this tool are explained below.

<div id="chart" style="width:100%;height:500px"></div>
import { createChartFactory } from '@revolist/charts/core';
import { lineChart } from '@revolist/charts/line';
import { groupedColumnChart } from '@revolist/charts/grouped-column';
import { columnLineChart } from '@revolist/charts/column-line';
const rows = [
{
"date": 1767225600000,
"month": "Jan",
"revenue": 65,
"costs": 45
},
{
"date": 1769904000000,
"month": "Feb",
"revenue": 82,
"costs": 50
},
{
"date": 1772323200000,
"month": "Mar",
"revenue": 76,
"costs": 48
},
{
"date": 1775001600000,
"month": "Apr",
"revenue": 95,
"costs": 65
},
{
"date": 1777593600000,
"month": "May",
"revenue": 110,
"costs": 72
},
{
"date": 1780272000000,
"month": "Jun",
"revenue": 102,
"costs": 68
},
{
"date": 1782864000000,
"month": "Jul",
"revenue": 121,
"costs": 80
},
{
"date": 1785542400000,
"month": "Aug",
"revenue": 115,
"costs": 76
},
{
"date": 1788220800000,
"month": "Sep",
"revenue": 135,
"costs": 89
},
{
"date": 1790812800000,
"month": "Oct",
"revenue": 128,
"costs": 85
},
{
"date": 1793491200000,
"month": "Nov",
"revenue": 145,
"costs": 92
},
{
"date": 1796083200000,
"month": "Dec",
"revenue": 155,
"costs": 100
}
];
const mapping = {
"category": {
"field": "date",
"label": "month"
},
"series": [
{
"field": "revenue",
"label": "Revenue"
},
{
"field": "costs",
"label": "Costs"
}
]
};
const createChart = createChartFactory([lineChart, groupedColumnChart, columnLineChart]);
const container = document.getElementById('chart')!;
const chart = await createChart({
container,
data: rows,
mapping,
"chartType": "line",
"axes": {
"x": {
"scale": "time"
}
},
"presentation": {
"title": "Monthly performance",
"subtitle": "Illustrative data · 2026",
"legendPosition": "bottom"
},
"interaction": {
"mode": "select",
"selectionMode": "multiple"
},
"navigation": {
"enabled": true
}
});
// When the host unmounts:
// chart.destroy();
import { createChartSyncGroup } from '@revolist/charts/core';
// firstChart and secondChart are mounted ChartRef controllers.
const group = createChartSyncGroup({
viewport: 'x', domain: false, hover: true,
onError: (error, targetId) => console.error(targetId, error),
});
const disconnectFirst = group.connect(firstChart);
const disconnectSecond = group.connect(secondChart);
await group.flush();
// Later: disconnectFirst(); disconnectSecond(); group.destroy();

Targets must expose compatible axes: scale types and declared numeric units must match, and categorical linking requires compatible category identities. X, Y or XY viewport/domain propagation is configurable; domains and hover are transient peer state. No unit conversion occurs. The API does not synchronize Pivot queries, grid filters or annotation shapes.

Authored settings are available through chart.model. Updates replace whole settings objects: spread fields you want to retain, and await the returned promise before reading state or exporting. Destroy the controller when its host unmounts.

All chart tools · Chart types · Data & Configuration