Skip to content

Drill-down and Interactions

Pivot Charts carry row and column hierarchy metadata into every compatible dataset. A mark can therefore identify the exact semantic category, series, paths, measure, aggregator, and child state that produced it.

Interactive example

Drill and selection

Create a chart using the analytical scope of a selected Pivot coordinate.

The example loads when visible.

With pivotChartsUi.contextMenu: true and ContextMenuPlugin installed, right-clicking a Pivot analytical body cell contributes Pivot Chart…. Creation resolves scope from committed Pivot metadata:

  • group values open their immediate children;
  • leaf values open siblings under the same parent;
  • subtotal and grand-total cells use the nearest valid breakdown;
  • the clicked column member and measure seed the series selection;
  • values-on-rows retain the clicked category measure.

The context action composes with other menu contributions. It does not replace application items or depend on visible DOM text.

With the default interaction.mode: 'drill', pointer click and keyboard activation first look for an automatic semantic drill target. When the category or series can drill, activation starts the appropriate row, column, or two-axis drill action and does not emit pivot-chart-node-click. The event is emitted only when no automatic drill target exists.

The chart ref supports row, column, and two-axis targets:

if (chart.canDrillDown({ axis: 'row', category })) {
await chart.drillDown({ axis: 'row', category });
}
await chart.drillDown({ axis: 'column', series });
await chart.drillDown({ axis: 'both', category, series });

Use canDrillDown before offering an application-owned drill control. It checks hierarchy identity, level, child state, and the current active scope.

Each successful frame is stored in PivotChartDrillState.frames. The compact breadcrumb shows the active row and column labels:

await chart.drillUp();
await chart.drillTo(1);
await chart.resetDrill();

Selecting All data resets to the root. Selecting an ancestor calls drillTo directly; it does not replay every intermediate click. After a successful UI drill, focus moves to the current breadcrumb item.

Drill loads are abortable and revision-checked:

  • the last successful frame stays visible while the next frame loads;
  • a newer action aborts or supersedes older work;
  • stale provider completions are ignored;
  • rendering failures roll back model and dataset state;
  • successful scopes are cached;
  • failed drill metadata is retained for retryDrill().

The dialog displays the pending target, failure message, and retry action without discarding the previous chart.

drillSyncMode controls the relationship between chart navigation and the Pivot frontier:

ModeBehavior
chartNavigate only in the chart.
pivotSynchronize the Pivot frontier and let the linked Pivot refresh drive the chart.
bothCommit the chart frame and synchronize the Pivot.
eventEmit pivot-chart-drill-sync; the application owns synchronization.

For pivot and both, the active PivotPlugin applies the semantic frontier unless pivotCharts.synchronizeDrill is provided. The custom adapter receives the event detail and an AbortSignal.

grid.pivotCharts = {
renderer: createPivotChartsRenderer(),
defaultDrillSyncMode: 'event',
async synchronizeDrill(detail, { signal }) {
await saveAnalyticsRoute(detail.to, { signal });
},
};

interaction.mode chooses what mark activation does. It is independent of drillSyncMode:

ModeBehavior
drillUse the existing automatic hierarchy navigation.
selectCommit a persistent semantic selection.
filterCommit selection and apply its member predicates through Pivot.
eventEmit a selection proposal for the application without committing or drilling.

These modes are supported by grouped columns/bars, line, column-line, area-line, pie/donut, annotated time series, and small multiples. Other chart families reject unsupported modes. Check the chart definition’s interactionModes before offering custom controls.

await chart.update({
interaction: {
mode: 'select',
selectionMode: 'multiple',
crossHighlight: true,
},
});

Ordinary activation replaces the selection, or clears an already selected single target. In multiple mode, Ctrl/Meta activation adds or removes a target. Pointer clicks and Enter/Space use the same rules. Selected marks have a visible outline and aria-pressed state. Use the clear action or Escape to clear selection. In Event mode, these user actions request clearing; the application commits the change.

In Customize, compose a selection in Select mode, then choose Apply selection as filter. The immediate Filter mode narrows the source chart as well as the linked Pivot. Choose Edit selection to release that chart’s filter while keeping its selection, revise the selected members, and apply again. Other charts’ contributions and user filters remain active.

Selection targets store row and column { field, value } members and an optional measure identity. They do not store visible indexes or display labels:

await chart.setSelection([
{
row: [{ field: 'region', value: 'North' }],
column: [{ field: 'year', value: 2026 }],
measure: { prop: 'sales', aggregator: 'sum' },
},
]);
await chart.clearSelection();

Linked projections supply their committed layout fields. Standalone datasets must provide hierarchy level fields or explicit selectionFields: { row: ['region'], column: ['year'] }, aligned with category and series paths. Missing or ambiguous mappings fail rather than interpreting labels as source fields. Measure carriers in values-on-rows layouts never become raw member predicates.

Strings, finite numbers, booleans, and null retain their typed identity. Missing/null source members share the canonical blank value null; negative zero is normalized to zero. Refresh, drill, reordering, and temporarily absent members preserve semantic selection. Rendering only matches current members; it does not replay a filter or emit activation events.

interaction updates replace the authored object: omit it to retain it or use {} to reset. selection: [] clears selection. Save/restore includes both fields. Unlinking releases that chart’s native filter; relinking or restoring a linked Filter chart applies its persisted contribution once.

Interactive example

Filters and navigation

Compare selection and highlighting across two charts linked to the same Pivot.

The example loads when visible.

A chart’s selected tuples combine with OR, and fields inside a tuple combine with AND. Selecting (North, 2026) and (South, 2027) therefore excludes (North, 2027) and (South, 2026). Independent chart owners, ordinary member filters, Core source filters, and result filters combine with AND.

Pivot owns these contributions. Clearing, editing, unlinking, or destroying a chart removes only its contribution. Contributions are ephemeral in Pivot configuration; the chart model owns their persistence. If a layout change removes a predicate field, Pivot drops the entire affected contribution after a successful commit rather than weakening its tuples. Prevented, failed, or superseded selection operations retain the committed chart model. If rendering fails after filtering and restoring the previous native contribution also fails, Pivot retires that owner and reports a selection error. Future queries omit the owner; the last committed remote view remains until a successful refresh.

Destroying a chart disposes its filter owner even when ordinary configuration updates are prevented. If the server cannot refresh during disposal, a selection error reports the cleanup failure and the last committed remote view remains visible. The disposed contribution is removed from future queries; it is not retained as a hidden filter after its chart is gone.

Native filtering requires a linked active Pivot and meaningful source member predicates. Dimensionless totals, synthetic Top/Bottom Other members, and ambiguous field mappings cannot be used as raw filters. A server adapter that explicitly advertises filter: false cannot apply a native chart filter.

Peer highlighting requires crossHighlight: true on both participating charts. It compares shared dimension fields across layouts and leaves unrelated charts unaffected. Measure identity distinguishes local selected cells; peer matching uses dimensions. Highlight updates are silent and are not copied into each peer’s persisted selection.

In Event mode, listen for pivot-chart-selection-request, inspect its semantic proposal, and explicitly call setSelection when the application accepts it:

grid.addEventListener('pivot-chart-selection-request', async event => {
const { chartId, proposed } = event.detail;
if (await acceptSelection(proposed)) {
await charts.setChartSelection(chartId, proposed);
}
});

pivot-chart-before-selection is preventable. Committed changes emit pivot-chart-selection-changed; failures emit pivot-chart-selection-error. Details include chart ID, operation ID, revision, origin, interaction mode, proposed selection, and current selection. Received highlighting and redraws never emit these selection actions.

Custom user Clear controls should call charts.requestChartSelectionClear(chartId, origin) so Event mode can delegate the request. chart.clearSelection() and charts.clearChartSelection(chartId) are explicit application commits, including in Event mode.

Navigation controls share one persisted category/time viewport (viewport.x). They change the visible window while retaining the complete chart dataset, Pivot filters, and semantic selection. Payload limits still apply to the complete dataset.

The built-in renderer supports category navigation for line and area charts (including smooth, stepped, stacked, and 100% stacked variants), grouped, stacked, and 100% stacked columns and bars, plus annotated time series, small multiples, column-line, and area-line. Horizontal bars navigate along their vertical category axis; their navigator remains horizontal. Explicit zoom, navigator, or viewport settings replace automatic dense category scrolling while active. The ordinary line, area, column, and bar types retain a category axis; time navigation remains available on annotated time series, small multiples, and the two combination types. Check the chart definition’s navigation capability and the configured renderer’s capabilities.navigation before offering custom controls. Unsupported authored settings are rejected.

await chart.update({
navigation: {
enabled: true,
navigator: true,
crosshair: true,
tooltipMode: 'shared',
},
viewport: {
x: { scale: 'category', startId: firstCategory.id, endId: lastCategory.id },
},
});
// Restore the full X domain, retaining navigation controls.
await chart.update({ viewport: {} });

For a time axis, use absolute UTC epoch milliseconds within the supported date range:

await chart.update({
axes: { x: { scale: 'time' } },
viewport: { x: { scale: 'time', min: Date.UTC(2026, 0, 1), max: Date.UTC(2026, 2, 1) } },
});

The viewport scale must match the chart’s category/time axis policy. Both navigation and viewport use replacement updates: omit them to preserve their values, or pass {} to reset them. Navigation is opt-in; it does not change the default interaction mode.

With navigation enabled, wheel input zooms around the pointer, dragging pans the window, and touch supports category-axis pan and pinch zoom. Horizontal bars pan vertically and leave horizontal touch scrolling available; other charts pan horizontally and leave vertical touch scrolling available. A claimed drag suppresses its activation click; ordinary clicks keep the configured Drill, Select, Filter, or Event behavior. Escape cancels an active gesture.

The navigator’s start and end handles resize the same window; dragging its selected band pans it. Focus a handle or the band to use arrow keys, with Shift for a larger step and Home/End for a boundary. Separate zoom, pan, and reset buttons support keyboard operation without changing the arrow-key navigation of chart observations.

Category windows store semantic category IDs. Reordering resolves the inclusive interval between the current positions of both endpoints. If either endpoint disappears, the authored window remains dormant and the full domain is shown until both return. Time windows retain their absolute bounds; a window outside the current domain displays an empty plot with a reset action.

Refresh, unlink, relink, and saved-state restore retain the viewport when the semantic scope survives. Successful drill navigation or fallback to a valid ancestor scope resets it; failed navigation retains it. The automatic Y domain continues to use the full dataset, so panning does not change the apparent magnitude of values. Explicit Y bounds remain authoritative.

navigation.crosshair follows the nearest visible category. With tooltipMode: 'shared', the existing tooltip card shows the active series for that category, including missing values and their display formatting. Matching uses category identity, so identical labels do not merge distinct members. Crosshair and shared tooltip state is transient and does not select, filter, drill, or broadcast highlighting to another chart.

Shared cards show up to 20 series and announce the omitted count. Custom tooltip formatters retain the existing primary datum context and receive optional sharedItems and omittedSharedItemCount; each shared item includes its original category/series index, value, display value, color, and authored axis unit. Keyboard focus follows the focused member, including distinct categories with the same timestamp. Pointer lookup uses a deterministic member for tied times and can inspect a visible category omitted by dense mark sampling.

Series legends are keyboard-accessible guides. By default, activating a legend item focuses that series, emphasizes matching marks, and mutes the others. Activating it again or selecting the chart background clears the focus. When a dense legend cannot fit, it shows a deterministic subset and a localized overflow count.

On charts supporting independent series visibility, set presentation.legendAction: 'toggleVisibility' to persist show/hide changes instead. Enter, Space, and pointer activation share the same action. Hidden series remain available for restoration; the canonical dataset and shared Pivot remain unchanged. The Customize controls provide the full series list when the SVG legend overflows.

Interactive example

Tooltips and keyboard access

Inspect a chart mark's formatted value and analytical context in its tooltip.

The example loads when visible.

Interactive marks use an application-owned tooltip card rather than native SVG title text. The default tooltip includes:

  • the complete category path;
  • series identity and formatted value;
  • the resolved mark color;
  • X, Y, and size rows for relationship charts;
  • a drill hint when the datum has children.

Pointer tooltips stay inside the viewport. Keyboard focus opens the same card immediately and connects it with aria-describedby. Escape closes the tooltip without closing the chart dialog; selection modes also clear the selection, or request clearing in application-controlled Event mode. Gallery previews intentionally do not create tooltips.

  • The modeless dialog has a stable accessible name and restores focus when it closes. Tab can leave the chart to reach the grid. A menu or chart control that handles Escape keeps the outer dialog open.
  • Gallery tabs, cards, breadcrumbs, legend items, chart marks, export actions, and the data table are keyboard operable.
  • Marks have localized accessible names built from category, series, formatted value, relationship channels, and drillability.
  • View data uses a read-only RevoGrid with a descriptive label, keyboard sorting, cell selection, and sort announcements.
  • Status regions announce loading, drill success, failure, and data-table sort changes without replacing visible content.

Keyboard navigation counts actual inspection targets. Charts with more than 240 targets use one Tab stop: arrow keys move between displayed targets, Home and End reach the first and last, and Enter or Space activate the focused datum. Smaller charts use Tab between targets. Aggregate bins expose their count and bounds for inspection; activating a bin never selects or drills into a representative observation. Aggregate tooltips use localized inspection text. They do not call the datum tooltip formatter, whose context requires an individual category and series. The range-interval chart’s mean across several measure values is also an inspection target, rather than a cell belonging to one of those measures. Box and violin descriptions include their distribution statistics and retain drill hints where applicable. A precomputed summary without a mean does not announce an estimated mean.

Every chart provides a localized description of its data dimensions and actual inspection targets. Annotated time series and small multiples also describe finite source and displayed observations and sampling omissions. Navigation visits displayed targets; sampling never creates additional observations. Redraws preserve the focused semantic datum where possible, use a nearby displayed datum when it disappears, and leave focus outside the chart untouched. Empty charts have no observation navigation instructions, and gallery previews remain decorative.

Provide additional context with presentation.description, a plain-text string of up to 4096 UTF-16 code units. It is saved with the chart and linked to the chart’s accessible description. An empty string clears it; an omitted or undefined update preserves it. Description edits do not reload provider data.

The existing highContrast and highContrastDark themes are available alongside the other chart themes. Forced-color styling preserves focus and selected-control boundaries. Use supported marker shapes, line dashes, or member patterns when series need differentiation beyond color, and View data to inspect exact values in a table.

EventPurpose
pivot-chart-node-clickReports the activated semantic datum and its paths/measure when no automatic drill target exists.
pivot-chart-before-selectionCancelable proposal before a selection commit.
pivot-chart-selection-changedReports committed semantic selection.
pivot-chart-selection-requestDelegates Event-mode selection to the application.
pivot-chart-selection-errorReports a failed selection/filter transition.
pivot-chart-before-drillCancelable event before a drill is committed.
pivot-chart-drill-startAnnounces a pending drill frame.
pivot-chart-drilledSupplies the committed model and dataset.
pivot-chart-drill-errorReports the failed transition and error.
pivot-chart-drill-resetReports a successful reset to root.
pivot-chart-drill-syncDelegates pivot, both, or event synchronization.

Event payloads clone JSON-safe semantic state. See Headless API and persistence for the full lifecycle event list.

Previous: Data and bindings · Next: Customization and export · API reference