Skip to content

Provider Data Contract

Read Server-Side Data first. This reference explains the message your application sends and the complete chart result your backend returns. You need it when implementing a provider, rather than when drawing an ordinary local chart.

Use the same Region/Product/Sales field identities in your report and response. Labels are for display; IDs keep filtering, drill and saved charts connected to the right values.

Use this contract for PivotChartDataProvider.load. The backend returns a complete frame for the requested semantic scope, not a page of whichever Pivot rows happen to be loaded.

A scope contains the committed revision, row/column paths and requested depths. At root it might mean every region; after drilling into North it means every requested child of North. The client validates that boundary before accepting or caching a response.

PivotChartDataRequest includes:

FieldPurpose
requestIdUnique request identity that the response must echo.
viewId and fieldsVersionIdentify the remote analytical view and field registry.
loadOptionsCommitted Pivot filters, sorting, grouping, and engine options.
uiStateOptional Pivot UI hints.
axisStateExpanded row and column paths.
chart.seriesIdsRequested series selection.
chart.categoryMeasureValues-on-rows measure selection.
chart.totalsRequested totals mode.
chart.limitsEffective category, series, and point limits.
chart.bindingsStable semantic field-to-channel bindings.
chart.scopeExact committed revision, row/column paths, and immediate-child depths.
chart.queryOptional normalized chart-local slice, member filters, sort, and ranking.

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.

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.

The client rejects:

  • a response whose requestId differs 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.

A provider that executes chart-local analytical queries must opt in with capabilities: { query: true }. Existing providers continue serving charts without an authored query.

dataProvider: {
capabilities: { query: true },
async load(request, { signal }) {
// Execute the complete analytical query on the backend.
return loadCompleteChartFrame(request, signal);
},
}

For shaped requests, the response must include query matching the normalized request.chart.query, alongside the existing request and semantic scope identities. Missing or different query echoes are rejected. Nonempty frames must include each requested measure for every semantic member, including null values, unless an explicit series or category-measure selection narrows them. The inherited loadOptions remain part of the request; chart-local filters intersect them.

The provider executes ranking globally within the requested semantic scope before returning complete counts. It builds Other from source transactions and reaggregates the configured measures. Ranking a remote page or adding its displayed averages and distinct counts cannot satisfy this contract. Statistical distributions must describe the same shaped source.

charts.getDataShapingCapabilities() reports current support and reasons. Provider opt-in establishes an integration contract; the frontend cannot independently prove backend aggregation correctness.

Return source distributions in response.analyticalFrame.derived.distributions when serving box plots or violin charts. Each entry is keyed by returned categoryId and seriesId and contains either finite kind: 'samples' observations or a kind: 'summary' with ordered quartiles and whiskers. Violin summaries additionally require ordered nonnegative density points. Raw sample arrays, summary points, outliers, and density allocations are checked against the chart’s maxDataPoints budget. The provider must supply the complete requested frame; it must not substitute aggregated Pivot cells for raw observations.

See Source distributions for the public data shape and statistical conventions.

request.chart.query describes the analytical result to compute. It is distinct from dataProvider.query, which configures the transport’s cache/refetch policy. See Query and Lifecycle.

See your first chart, data and measures and the API reference.