Data & Configuration
Start with Installation if Charts is not yet installed. This guide follows a chart from its first rows through configuration, updates, interaction, exports and cleanup.
For dedicated interactive examples of drawing, navigation, linking, selection, exports and other shared features, see Chart tools.
For calculated overlays, calendar-aware comparisons, forecasts, faceting and performance comparisons, see the separate Analysis guide. These tools preserve source observations and use explicit statistical policies.
Try configuration changes
Section titled “Try configuration changes”Switch chart type, update rows, turn value labels or grid lines on and off, and export the result. The example uses only the two registered chart definitions.
Loading chart…
Create a chart
Section titled “Create a chart”Give the host an explicit height, then call the factory after the host is mounted. No stylesheet or custom element registration is required.
<div id="revenue-chart" style="width: 100%; height: 360px;"></div>import { createLineChart } from '@revolist/charts/line';
const container = document.getElementById('revenue-chart')!;const chart = await createLineChart({ container, data: [ { month: 'Jan', revenue: 120 }, { month: 'Feb', revenue: 180 }, { month: 'Mar', revenue: null }, ], mapping: { category: { field: 'month' }, series: [{ field: 'revenue', label: 'Revenue' }], }, presentation: { title: 'Monthly revenue' },});
// Later, when your application removes the host:// chart.destroy();Each row becomes one category. Values must be finite numbers or explicit null;
missing values and numeric strings are rejected. Category keys must be unique
by type and value. The converter preserves identities and does not aggregate
rows. Use category.label to map a separate string display-label field.
Configure presentation and chart options
Section titled “Configure presentation and chart options”Use presentation for titles, legend placement, axis titles and value labels.
Use chartOptions for the selected type’s options. Supported options and their
ranges are declared by that type’s definition; an unsupported option is rejected.
await chart.update({ presentation: { title: 'Monthly revenue', subtitle: 'Actual revenue · € thousands', legendPosition: 'bottom', yAxisTitle: '€ thousands', dataLabels: true, }, chartOptions: { showGridLines: false }, theme: 'dark',});Presentation is replaced as a whole, so include titles you want to retain. To edit an existing chart while keeping other presentation settings:
await chart.update({ presentation: { ...chart.model.presentation, dataLabels: true },});Use explicit datasets and channel bindings
Section titled “Use explicit datasets and channel bindings”Rows are convenient for simple categorical charts. Use createChartDataset to
reuse a conversion, or supply a complete ChartDataset from your own analytical
pipeline. Channel bindings reference series IDs, not display labels:
import { createScatterChart } from '@revolist/charts/scatter';
const scatter = await createScatterChart({ container, data: [ { product: 'A', cost: 20, revenue: 60 }, { product: 'B', cost: 35, revenue: 90 }, ], mapping: { category: { field: 'product' }, series: [{ field: 'cost' }, { field: 'revenue' }], }, bindings: { x: ['cost'], y: ['revenue'] },});scatter.destroy();Hierarchy charts require hierarchy metadata. Box plots and violins require observations or valid distribution summaries; aggregate totals cannot recover a distribution. Financial charts need explicit OHLC channels. The overview’s live catalog exposes a valid dataset and bindings for every built-in type.
Update, select and export
Section titled “Update, select and export”Updates reuse the last successful field mapping. Await an update before reading a snapshot or exporting. Invalid updates preserve the previous chart.
await chart.update({ data: [ { month: 'Apr', revenue: 240 }, { month: 'May', revenue: 210 }, ],});await chart.update({ interaction: { mode: 'select' } });// Clicking a point now commits local selection.await chart.clearSelection();
const csv = chart.getCSV();await chart.download({ fileFormat: 'svg', fileName: 'monthly-revenue' });// PNG, CSV and raster PDF downloads are also supported by the native renderer.Presentation updates replace that settings object. Include titles and other
presentation settings you want to keep. undefined preserves a setting owner;
{} resets it and arrays replace it.
Choose one type or compose several
Section titled “Choose one type or compose several”Per-type imports such as /line, /grouped-column, /pie and /box-plot expose
a definition and a bound factory, for example lineChart and createLineChart.
A bound factory keeps its chart type fixed.
For an application that switches types, register only the definitions it needs
with createChartFactory from /core. Here is the actual setup used by the live
example above. Save it as revenue-chart.ts:
import { createChartFactory } from '@revolist/charts/core';import { lineChart } from '@revolist/charts/line';import { groupedColumnChart } from '@revolist/charts/grouped-column';
export const revenueRows = [ { month: 'Jan', revenue: 120, costs: 80 }, { month: 'Feb', revenue: 180, costs: 110 }, { month: 'Mar', revenue: 160, costs: 95 }, { month: 'Apr', revenue: 240, costs: 140 }, { month: 'May', revenue: 210, costs: 125 }, { month: 'Jun', revenue: 290, costs: 165 },];
// Register only the types this application needs.const createRevenueChart = createChartFactory([lineChart, groupedColumnChart]);
export function mountRevenueChart( container: HTMLElement, theme: 'light' | 'dark' = 'light', signal?: AbortSignal,) { return createRevenueChart({ container, signal, theme, chartType: 'line', data: revenueRows, mapping: { category: { field: 'month' }, series: [ { field: 'revenue', label: 'Revenue' }, { field: 'costs', label: 'Costs' }, ], }, presentation: { title: 'Monthly performance', subtitle: 'Illustrative data · € thousands', legendPosition: 'bottom', yAxisTitle: '€ thousands', }, interaction: { mode: 'select' }, });}The returned controller supports both registered types:
import { mountRevenueChart } from './revenue-chart';
const container = document.getElementById('revenue-chart')!;const chart = await mountRevenueChart(container);await chart.update({ chartType: 'groupedColumn' });await chart.update({ chartType: 'line' });chart.destroy();The package-root createChart includes the full built-in catalog when arbitrary
type switching is needed. Specialized charts retain their data requirements:
for example, scatter charts need channel bindings and box plots need source
observations or valid distribution summaries. Supply an explicit ChartDataset
for analytical data, hierarchy metadata, bindings or distributions.
createChartDataset from /core also converts rows separately for reuse.
Customize renderer colors and locale
Section titled “Customize renderer colors and locale”Every per-type factory also accepts rendererOptions directly. See Chart Customization for all color, label, element-style and advanced SVG controls, including Pivot and geographic usage.
Pass a renderer to a bound factory when your application supplies theme tokens, a palette, or label formatting. This example still loads only the line renderer:
import { createNativeChartsRenderer } from '@revolist/charts/core';import { createLineChart, lineChart } from '@revolist/charts/line';
const chart = await createLineChart({ container, data: [{ month: 'Jan', revenue: 120 }], mapping: { category: { field: 'month' }, series: [{ field: 'revenue' }] }, renderer: createNativeChartsRenderer([lineChart], { palette: ['#6647f0', '#fd7e14'], theme: { foreground: '#172033', grid: '#e2e8f0' }, }), localeText: { dataTable: { categoryHeader: 'Month' } },});chart.destroy();Themes, saved state and cleanup
Section titled “Themes, saved state and cleanup”Set theme: 'light' or 'dark' to follow your application’s theme, or pass
renderer theme tokens through a custom renderer. theme: 'auto' follows the nearest host data-theme attribute, falling back to
the system color preference. Configure labels and titles with presentation, per-type
settings with chartOptions, and translations with localeText.
const saved = JSON.stringify(chart.model);chart.destroy();
const restored = await createLineChart({ container, model: JSON.parse(saved),});// Dispose when your component unmounts or route changes.restored.destroy();Chart models are version 1 and contain chart state. Pass either rows with a
mapping, an explicit dataset, or a saved model. A supplied AbortSignal cancels
pending creation and disposes the chart when aborted. Always destroy a chart
when its host unmounts; destroy() is idempotent.
Optional integrations and Pivot
Section titled “Optional integrations and Pivot”@revolist/charts/echartsaccepts an application-supplied ECharts runtime.@revolist/charts/vector-pdfaccepts a vector PDF encoder runtime.@revolist/charts/geographicprovides opt-in geographic capability packs with application-supplied providers and assets.
For linked charts built from grouped grid results, queries, drill-down or filter synchronization, use Pivot Charts. Pivot consumes the same chart engine and owns those grid-specific operations.
Advanced axes and graph data
Section titled “Advanced axes and graph data”Axes & number formatting documents numeric X (linear, log, symlog, sqrt), level/category-ID data mappings, placement/reversal/ticks, xAxes/yAxes, per-series assignments, grouped categories, measured gutters and Pivot authoring. Settings remain subject to each catalog definition’s capabilities.
Use Sankey graph data for general DAG inputs, sort/layout controls, colors, labels, callbacks and controlled highlights. Heatmap navigation covers independent row/column windows and navigator tracks.
For dense native line/area and combination paths,
chartOptions.sampling selects
'auto', 'none', 'm4', 'minmax', or 'lttb' without modifying raw data or
domains. The option persists in the model and is shared with Pivot.
For native line/area and combination categorical X axes, choose
axes.x.categoryPlacement
(or axes.xAxes[id].categoryPlacement) as 'point' or 'band'. Omit it to keep
the chart family default; it does not change raw category IDs or values.
Candlestick and OHLC role bindings can contain parallel arrays for multiple groups. Open/high/low helpers can broadcast, while each close field uniquely owns its group and X/Y assignments. See candlestick and OHLC collections. Volume-price adds one distinct paired volume measure per close owner and keeps shared price/volume Y roles.
Controller methods and creation callbacks
Section titled “Controller methods and creation callbacks”A ChartRef returned by the root, registered, or per-type factory exposes the
same lifecycle. A per-type factory restricts chartType updates to its type.
| Member | Purpose and lifetime |
|---|---|
model, getDataset() | Independent snapshots of committed state/canonical loaded data. Mutating a snapshot does not update the chart. |
capabilities | Active renderer contract, including supported types, interaction modes, image data URLs and download formats; also check the catalog type’s feature support. |
update(patch) | Validated asynchronous data/settings update. Nested setting owners replace rather than deep merge. Runtime callbacks and rendererOptions are creation options, not update patches. |
applyTransaction({ add?, update?, remove?, addIndex? }) | Atomic row changes by category-field identity; see live data. |
setSelection(targets), clearSelection() | Commit semantic source selection; see selection. |
setRangeSelection(rangeOrNull), clearRangeSelection() | Enable/set or clear the authored axis interval without dropping retained styling; see range selection. |
setDataSource(source?), reloadData() | Attach, detach or refresh the asynchronous data owner; see async data. |
subscribe(listener) | Observe committed model snapshots; returns an idempotent unsubscribe. It does not synthesize a first event or report animation frames. |
getCSV(options?), download(options?), getImageDataURL(options?) | Synchronous data serialization or asynchronous file/PNG capture; see all export options. |
focus() | Focus the native chart’s accessible inspection surface where supported. |
id, getSyncSnapshot(), subscribeEvents(), applyViewport(), applySyncState() | Provider-facing linking contract. Prefer createChartSyncGroup to hand-written propagation; see chart linking. |
destroy() | Idempotent cleanup of renderer, listeners, data requests and subscriptions; later operations reject. |
Creation options also include chartId for stable chart identity, signal for
creation/lifetime cancellation and localeText for UI/formatting. Do not pass
these through update. Reattach runtime values when restoring a saved model.
| Creation callback | Receives / when it runs |
|---|---|
onNodeClick(detail) | Canonical category, series and raw value; relationship points also expose bound channelValues/channelSeries. Native user activation can include originalEvent. Aggregate inspection does not invent source records. |
onChange(model) | A committed model snapshot after an accepted change. Notification failures do not undo a committed model or block other subscribers. |
onViewportChange(viewport, origin) | Committed public windows and 'pointer', 'keyboard', 'api' or 'calendar' origin. |
onHoverChange(hover) | Transient source-coordinate hover used by linking; separate from saved selection. |
onSelectionRequest(selection) | Semantic targets requested by interaction.mode: 'event'; the host decides whether to commit them. |
onRangeSelectionStart, onRangeSelectionChange, onRangeSelectionEnd | Axis-range gesture lifecycle with public range/origin context; see the range-selection guide. |
underlyingRecords | Runtime source-record provider, not model data; see underlying records. |
onReloadData | Inherited low-level host callback. Public factories route Retry to their own reloadData() source runtime and do not invoke a caller-supplied replacement. Use dataSource.load / reloadData for application refresh. |
onError(error) | Runtime/notification failures. Also catch rejected creation/update/export promises; validation may throw ordinary TypeError/RangeError as well as ChartError. |
exportHooks, onBeforeDownload, onDownloaded | Export operation lifecycle and synchronous legacy veto/notification; see export hooks. |
parseChartModel and cloneChartModel from /core parse/own saved model values;
assertChartDataset validates a canonical dataset. These utilities do not mount
a chart or establish backend support: creation still validates the complete
selected type/settings/renderer combination. chartDimensionFieldId(axis, field)
provides the stable field ID for generated analytical-frame dimensions.
Input budgets
Section titled “Input budgets”limits persists declared input budgets, independently of rendering policy and
path sampling. Standalone creation resolves defaults to 10,000 categories,
250 series and 50,000 category × series cells. DEFAULT_CHART_LIMITS exported
from /core is the shared base (1,000, 250, 50,000); hosts such as
Pivot can apply their own category policy. Supply all overrides explicitly when
comparing hosts or reproducing dense-renderer benchmarks.
const chart = await createChart({ container, chartType: 'scatter', dataset, bindings, limits: { maxCategories: 100_000, maxSeries: 4, maxDataPoints: 400_000 } });Only maxCategories, maxSeries and maxDataPoints are accepted. Values must be
finite, at least one and normalize to a safe integer; fractional values are
floored. Cell limits include null matrix cells, not just painted observations.
Distribution/histogram metadata also obeys the source validation budgets.
Exceeding a budget rejects with ChartError.code === 'LIMIT_EXCEEDED' and count/
limit details. Invalid budgets reject before replacing the accepted frame.
Increasing a limit does not promise a frame rate, GPU availability, one mark per
source observation or more browser memory; use the renderer performance guides
for measured host-specific limits.
Mixed Cartesian sample layers
Section titled “Mixed Cartesian sample layers”columnLine and areaLine also support explicitly bound bubble and histogram
layers through the existing combination owner. Sample-owned X differs from the
chart’s category-owned line/column X; complete histogram summaries do not invent
loaded records. See Cartesian bubble and histogram layers
for every channel, named-axis assignment, layer order, shared tooltip, async
source, inspector and export rule. This does not add arbitrary type composition.
Row mapping reference
Section titled “Row mapping reference”mapping and createChartDataset(rows, mapping) share the same contract. One
row becomes one category; conversion does not aggregate, coerce numeric strings
or group duplicate keys.
| Mapping field | Meaning |
|---|---|
category.field | Required source field for a unique finite string/number/boolean/null identity. Numeric -0 and 0 share identity. Duplicate keys reject; changing a label does not change identity. |
category.label | Optional field name whose row value is the display string, not a literal label. Omission uses the final path value. |
category.path | Optional nonempty list of unique hierarchy field names, at most 128. Path values must be finite typed scalars/null. It cannot be combined with parent. |
category.parent | Optional parent-ID field for organization hierarchy. Every nonnull referenced parent must exist; cycles and chains exceeding 128 levels reject. |
category.subtitle, category.image | Optional source field names for organization card metadata. Nonmissing values must be strings; image loading/export follows the organization family’s policy. |
series[].field | Required numeric value source field. Missing/undefined/null produces a null observation; all other values must be finite numbers. |
series[].id | Stable series ID; defaults to its field name. Use these IDs in bindings and overrides. |
series[].label | Literal display label; defaults to its field name. |
Category IDs are generated from typed source keys, rather than display labels or
array positions. A new mapping must accompany new data in an update. An invalid
replacement does not replace the last accepted mapping or row set.