Skip to content

Underlying records

View underlying records opens the original facts behind a real chart observation. This differs from View data, which displays the chart’s aggregated dataset. Charts owns the action, table, loading/error states, pagination and keyboard focus. Your application or Pivot owns the source query.

The application below supplies both the aggregate chart rows and the original orders. Charts does not reverse an aggregate into invented transactions.

import { createGroupedColumnChart } from '@revolist/charts/grouped-column';
const orders = [
{ orderId: 'N-1', region: 'North', revenue: 100 },
{ orderId: 'N-2', region: 'North', revenue: 50 },
{ orderId: 'S-1', region: 'South', revenue: 80 },
];
const chart = await createGroupedColumnChart({
container: document.getElementById('chart')!, // Give the host an explicit height.
data: [
{ region: 'North', revenue: 150 },
{ region: 'South', revenue: 80 },
],
mapping: {
category: { field: 'region' },
series: [{ field: 'revenue', label: 'Revenue' }],
},
underlyingRecords: async ({ target, offset, limit, signal }) => {
signal.throwIfAborted();
const matching = orders.filter(order => order.region === target.category.path[0]);
return {
records: matching.slice(offset, offset + limit),
totalCount: matching.length,
columns: [
{ key: 'orderId', label: 'Order' },
{ key: 'region', label: 'Region' },
{ key: 'revenue', label: 'Revenue' },
],
};
},
});

Inspect an observation by pointer or keyboard, then activate View underlying records. The action is disabled until a real observation has been inspected. Synthetic Others, cumulative Pareto shares, analytical overlays and forecasts cannot request source transactions.

For remote records, pass the provided signal to your fetch/query and apply pagination at the source. Use stable semantic fields and measure IDs rather than display labels. The provider controls authorized fields and source access.

With Pivot and Pivot Charts already registered, opt into native source queries:

const chart = await charts.createChart({
container,
chartType: 'groupedColumn',
totals: 'none',
underlyingRecords: true,
});

The built-in provider uses Pivot’s existing paginated drillthrough API. It requires a current linked chart without an independent chart query, so the visible chart and source query share the same scope. For independent queries, unlinked snapshots or custom source policies, supply the callback used in the standalone example. A chart’s aggregated data is never used as a substitute for missing source facts.

The request contains target, zero-based offset, limit and an AbortSignal. target carries the real category, series, value and semantic paths. Return records and optionally a consistent totalCount and a column whitelist. The shared view requests pages of 50 records. A response must not exceed the requested limit; known totals must agree with nonempty returned pages. Explicit columns need unique nonempty keys and labels and are limited to 100 columns.

Invalid responses show the localized error state. The package does not execute HTML from records: values and labels are displayed as text.

The record table has a labelled dialog, loading/error status, Previous/Next page controls and a close action. Escape closes it and returns focus to its opening action. Paging preserves usable keyboard focus when the last page disables Next. Closing, rerendering or destroying the chart aborts pending requests; superseded responses cannot overwrite the current view.

Providers are runtime callbacks and are not serialized into saved models. Reattach a standalone provider when recreating a chart. For Pivot restore:

const restored = await charts.restoreChart(savedModel, {
container,
underlyingRecords: true,
});

Use localeText.underlyingRecords to translate the shared view. Pivot’s UI policy actions.underlyingRecords can hide or disable its action.

Analysis · Chart tools