Server Data and Performance
A remote Pivot viewport is only a window into the analytical result. Pivot
Charts never treat the visible rows or columns as the complete dataset.
Configure PivotChartDataProvider to return the complete immediate-child frame
for every requested semantic scope.
Configure a provider
Section titled “Configure a provider”grid.pivotCharts = { renderer: createPivotChartsRenderer(), dataProvider: { async load(request, { signal }) { const response = await fetch('/api/pivot/chart-data', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(request), signal, });
if (!response.ok) { throw new Error(`Chart data failed: ${response.status}`); } return response.json(); }, },};The provider is used for root projection, explicit scoped data, linked
refreshes, and drill frames. Local and server Pivots produce the same
PivotChartDataset contract after projection and validation.
Request contract
Section titled “Request contract”PivotChartDataRequest includes:
| Field | Purpose |
|---|---|
requestId | Unique request identity that the response must echo. |
viewId and fieldsVersion | Identify the remote analytical view and field registry. |
loadOptions | Committed Pivot filters, sorting, grouping, and engine options. |
uiState | Optional Pivot UI hints. |
axisState | Expanded row and column paths. |
chart.seriesIds | Requested series selection. |
chart.categoryMeasure | Values-on-rows measure selection. |
chart.totals | Requested totals mode. |
chart.limits | Effective category, series, and point limits. |
chart.bindings | Stable semantic field-to-channel bindings. |
chart.scope | Exact committed revision, row/column paths, and immediate-child depths. |
The semantic scope is absolute:
interface PivotChartSemanticScope { revision: number; rowPath: PivotPath; columnPath: PivotPath; rowDepth: number; columnDepth: number;}The response must contain every immediate child for that scope, not a viewport-sized subset.
Response contract
Section titled “Response contract”interface PivotChartDataResponse { requestId: string; scope: PivotChartSemanticScope; categories: PivotChartCategory[]; series: PivotChartSeries[]; values: Array<Array<number | null>>; displayValues?: Array<Array<string | null>>; hierarchies: { row?: PivotChartHierarchyDefinition; column?: PivotChartHierarchyDefinition; }; totalCategoryCount: number; totalSeriesCount: number;}categories.length and series.length describe the returned complete frame.
The total counts let the client prove that the response is complete and within
limits. Hierarchy definitions and member hierarchy metadata are required when
the response contains drillable members.
Strict validation
Section titled “Strict validation”The client rejects:
- a response whose
requestIddiffers from the request; - any change to revision, row/column paths, or requested depths;
- partial frames whose returned and total counts disagree;
- value/display matrices with wrong dimensions;
- duplicate or unstable category/series IDs;
- malformed hierarchy levels or member paths;
- incompatible bindings, selected series, or values-on-rows measures;
- categories, series, or point counts above the effective limits;
- data that violates the selected chart’s semantic constraints.
There is no visible-window fallback. A partial response would create a misleading chart and is treated as an error.
Cancellation and stale results
Section titled “Cancellation and stale results”Every provider call receives an AbortSignal. Abort underlying HTTP, query,
and decoding work when possible. Root loads, linked refreshes, and drill
transitions carry monotonically increasing revisions. The plugin ignores a
completion that is no longer current even if the provider did not stop after
abort.
During drill, the last successful frame remains rendered. During a linked refresh, the UI exposes a loading state and commits the replacement only after data validation and renderer update succeed.
Caching
Section titled “Caching”The plugin caches immutable datasets by committed Pivot revision, effective data options, bindings, and semantic scope. Concurrent equivalent requests share the same promise. Successful drill scopes are cached per chart so breadcrumb navigation does not repeatedly load unchanged data.
Replacing grid.pivotCharts, changing the Pivot model/source/filter/sort/group
state, or advancing the committed revision invalidates the relevant cache.
Application/server caches should use the same request identity inputs and must
still return the exact requested scope.
Dense-data behavior
Section titled “Dense-data behavior”Defaults are:
const DEFAULT_PIVOT_CHART_LIMITS = { maxCategories: 1_000, maxSeries: 250, maxDataPoints: 50_000,};Within those limits, the renderer degrades deliberately:
- every legend position reserves a valid plot rectangle;
- long legends show a deterministic subset and localized hidden count;
- category ticks and data labels are thinned without removing data;
- Cartesian marks retain exact values;
- density scatter, connected trends, small multiples, and timeline geometry aggregate or sample above their accessibility thresholds;
- the renderer avoids creating one focus target for every dense source point when that would make keyboard navigation unusable.
Sampling affects rendered geometry, not the persisted normalized dataset. Exceeding configured projection limits fails rather than silently truncating the model.
Renderer preview performance
Section titled “Renderer preview performance”The gallery uses the same chart definitions and renderer functions as full
charts, but with renderMode: 'preview'. Preview mode is decorative and omits
tooltips and interactive focus targets. Intersection-based mounting and cache
keys for type, renderer, theme, and locale prevent a 63-card gallery from
creating 63 active charts at once.
Geographic capability
Section titled “Geographic capability”Geographic views are opt-in because map geometry, projections, tiles, and licenses belong to the provider:
const pack = createPivotChartGeographicCapabilityPack(provider);
const host = await pack.render({ container, chartType: 'choropleth', dataset, bindings: { geographic: ['dimension:country'], value: ['measure:sales'] },});The pack exposes choropleth, proportionalSymbolMap, and
geographicHeatmap. These views are not built-in gallery types and do not
change PivotChartModel. Importing Pivot Charts alone loads no geographic
assets or map dependency.
Production checklist
Section titled “Production checklist”- Return complete immediate-child frames from the analytical engine.
- Preserve stable field, category, series, hierarchy, and path identities.
- Echo the request ID and semantic scope exactly.
- Forward abort signals to network and query work.
- Set limits that match renderer and server budgets.
- Include formatted display values when chart and Pivot formatting must match.
- Log provider errors with request/view IDs without exposing raw sensitive source rows.
- Exercise root, linked refresh, drill, retry, breadcrumb, and stale-response paths before release.
Previous: Headless API and persistence · Pivot Charts overview · Remote Pivot guide · API reference