Skip to content

Export & download

Download chart data and rendered images. This feature belongs to @revolist/charts and can be used without Pivot or a grid.

Choose a download button for CSV, SVG, PNG or PDF. These are application buttons using the native controller. PDF output is raster by default; the optional vector-PDF integration needs an application-supplied encoder.

Saved annotation shapes appear in image exports. Drawing controls, unfinished drafts and hover feedback are not exported. CSV contains data, not drawing shapes.

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"
}
});
// When the host unmounts:
// chart.destroy();
await chart.download({ fileFormat: 'svg', fileName: 'monthly-performance' });
await chart.download({ fileFormat: 'png', fileName: 'monthly-performance' });
await chart.download({ fileFormat: 'pdf', fileName: 'monthly-performance' });
const csv = chart.getCSV({ dataScope: 'all' });
const imageUrl = await chart.getImageDataURL({ width: 1200, height: 600 });

Check chart.capabilities.downloadFormats for the active backend. Await committed updates before exporting. Current-scope CSV follows the visible window; dataScope: 'all' exports all canonical rows currently held by the controller. Export never fetches unloaded server data. Image output uses the displayed view.

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

import { createChart, type ChartExportHooks } from '@revolist/charts';
const exportHooks: ChartExportHooks = {
async before(context) {
return await approveExport(context.options, context.signal);
},
after(context) { recordExport(context.operationId); },
error(error, context) { reportExportError(error, context.operationId); },
};
const chart = await createChart({ container, chartType: 'line', data, mapping, exportHooks });
// Also: createStandalonePivotChart({ ..., exportHooks })
// or grid.pivotCharts = { renderer: createPivotChartsRenderer(), exportHooks }.
HookResult and lifetime
before(context)?Sync/async boolean or void; false cancels before capture. Downloads resolve quietly, image data URL requests reject AbortError and notify error.
after(context)?Sync/async void; once after successful capture/download initiation. It does not confirm a filesystem save.
error(error, context)?Sync/async void; once for before/export/after failure or in-flight abort. Its errors cannot replace the primary rejection. On abort, notification starts without awaiting the host observer.

ChartExportContext includes chartId, chartType, host (standalone or pivot), scope (chart or selection), canonical selection, bindings, viewport, full committed dataset, optional active Pivot drillScope, operationId, kind (download or imageDataURL), copied export options and an operation signal. The options’ source signal is represented by context.signal. Every callback receives an independent snapshot with the same operation ID. Callback edits do not change the export or model.

Hooks cover controller downloads (including CSV) and PNG image data URLs, subject to existing backend capabilities. Pure getCSV, getChartCSV and exportChartToCsv serializers remain synchronous and do not invoke hooks. Pivot validates download options before entering the lifecycle. A failed operation rejects and later operations can proceed.

The source request signal or chart destruction/replacement aborts pending hooks and encoders. Already initiated downloads and host side effects cannot be undone. Await committed updates first. Standalone retains its operation queue: do not await another queued update/export on the same chart from a hook. Schedule it after the export settles. Pivot rejects capture if its model or dataset changed while an async before hook was pending. Keep host async work signal-aware.

Existing onBeforeDownload remains synchronous; returning false still cancels. Pivot’s cancelable pivot-chart-before-download also stays supported. Ordering: new before, legacy veto, exporter, legacy success notification, new after. A legacy veto skips after without error. Existing Pivot events stay download-only; new hook errors are observed independently. Without new hooks, Pivot preserves its synchronous export startup. Existing transition, viewport and backend image/vector export policies remain unchanged.

Hooks and surface actions are runtime-only: reattach after restore/hydration. Menus and controls are excluded from normal exports. Pivot exposes shared contract aliases PivotChartHostContext, PivotChartHostAction, PivotChartHostActionResolver, PivotChartHostActionsOptions, PivotChartExportContext and PivotChartExportHooks from its root and /charts entries. This does not add server export services or replace Pivot’s record actions.

getCSV accepts only ChartCsvOptions; download adds download fields to the same CSV options. CSV-only settings apply to CSV output. Image capture is PNG through getImageDataURL; it is not a CSV or SVG string serializer.

OptionDefault / contract
dataScope'current': visible series and window membership according to the family. 'all': complete committed canonical frame, including hidden series, without acquiring unloaded records.
valueFormat'raw' finite numeric values. 'formatted' uses provided display values or the locale number formatter. Nulls export as empty cells.
columnDelimiter','; nonempty string of at most 16 UTF-16 units without NUL or double quote.
rowDelimiter'\r\n'; the same validation. Neither delimiter may contain the other.
bomfalse; true prepends a UTF-8 BOM character for spreadsheet consumers.
escapeFormulasfalse; true prefixes formula-like text starting with =, +, -, @, tab or carriage return with an apostrophe. Numeric values remain numbers.
Download fileFormat'png'; native support is 'png', 'svg', 'pdf', 'csv', subject to renderer capabilities.
Download fileNameLocalized download name when omitted/blank. A recognized image/CSV extension is replaced with the selected format.
Image/download width, heightCurrent SVG view-box size when omitted, independently per dimension. Finite positive numbers up to 16,384 px, rounded to integer pixels; combined output must not exceed 64 × 1024 × 1024 pixels. This scales the committed snapshot rather than changing the live viewport. CSV rejects image dimensions.
Image/download signalOptional operation AbortSignal. Already initiated browser saves cannot be undone; rejection does not corrupt later exports.
Image fileFormatOnly 'png', including when omitted. Use download for other supported formats.
const csv = chart.getCSV({ dataScope: 'all', valueFormat: 'formatted',
columnDelimiter: ';', rowDelimiter: '\r\n', bom: true, escapeFormulas: true });
await chart.download({ fileFormat: 'csv', fileName: 'revenue',
dataScope: 'all', escapeFormulas: true });

CSV serializers quote delimiter/quote/newline-containing text. Source IDs and values remain canonical regardless of sampled SVG geometry or GPU paint. Histogram sample/bin views and combination sample-owned layers keep their family-specific data-view contracts; CSV is not a dump of synthetic bin marks. exportChartToCsv(dataset, model, options, localeText) from /core is the pure, synchronous equivalent when no mounted controller is needed.

rendererOptions.imageEncoder(svg, { width, height }) can replace PNG encoding; pdfEncoder replaces PDF encoding and can declare encoding: 'raster', 'vector' or 'custom'. Encoders receive the clean committed SVG snapshot. Default PDF is raster; vector PDF integration requires an application-supplied runtime. Check capabilities.pdfEncoding for the installed encoder policy. Runtime encoders are not saved and must be reattached after restore/hydration. Custom encoders own their asynchronous work; chart cancellation prevents stale acceptance but cannot undo host side effects.