Skip to content

Pivot

interface PivotConfigTotals {
/**
* Show a grand total row and, when column dimensions exist, grand-total value columns.
*/
grandTotal?: boolean;
/**
* Show subtotal rows and subtotal value columns for multi-level pivot hierarchies.
*/
subtotals?: boolean;
/**
* Disable generated subtotal rows or columns for specific axis fields or
* zero-based axis levels while keeping global subtotals enabled.
*/
disabledSubtotals?: {
rows?: PivotSubtotalDisableRule;
columns?: PivotSubtotalDisableRule;
};
/**
* Custom display label for the grand total row or value columns.
*/
grandTotalLabel?: string;
/**
* Custom display label for subtotal rows or value columns.
*/
subtotalLabel?: string;
/**
* Hide subtotal rows or columns when a branch contains only one
* source-backed leaf and the subtotal would duplicate that leaf.
*/
suppressSingleChildSubtotals?: boolean;
/**
* Hide the grand-total row when the pivot contains only one source-backed
* leaf and the total would duplicate that leaf.
*/
suppressGrandTotalWhenSingleLeaf?: boolean
}

interface PivotColumnLevelConfig {
/**
* Enable drill-down controls for generated groups at this zero-based level.
* Falls back to `columnCollapse.enabled`.
*/
collapsible?: boolean;
/**
* Start generated groups at this level collapsed.
* Falls back to `columnCollapse.collapsed`.
*/
collapsed?: boolean;
/**
* Show the parent subtotal column at this level while global subtotals are enabled.
* Explicit level settings take precedence over `totals.disabledSubtotals.columns`.
*/
subtotal?: boolean;
/** Override the subtotal label at this level. */
subtotalLabel?: string;
/**
* Place the subtotal before or after descendant columns.
* Defaults to `before`.
*/
subtotalPosition?: PivotColumnSubtotalPosition;
/**
* Ordered value fields to expose in this level's subtotal.
* Defaults to every configured Pivot value field.
*/
subtotalValues?: ColumnProp[];
/**
* Enable generated aggregate filters at this level.
* Falls back to the value dimension and `columnCollapse.filterable`.
*/
filterable?: boolean;
/**
* Enable generated aggregate sorting at this level.
* Falls back to the value dimension's `sortable` setting.
*/
sortable?: boolean
}

HTMLRevoGridElementEventMap (Extended from global)

Section titled “HTMLRevoGridElementEventMap (Extended from global)”
interface HTMLRevoGridElementEventMap {
[PIVOT_CONTEXT_MENU_COMMAND_EVENT]: PivotContextMenuCommandDetail
}

HTMLRevoGridElement (Extended from @revolist/revogrid)

Section titled “HTMLRevoGridElement (Extended from @revolist/revogrid)”
interface HTMLRevoGridElement {
/**
* Direct Pivot configuration.
*/
pivot?: Partial<PivotConfig>
}

AdditionalData (Extended from @revolist/revogrid)

Section titled “AdditionalData (Extended from @revolist/revogrid)”
interface AdditionalData {
/**
* Legacy additionalData property for Pivot.
* @deprecated Use `grid.pivot` instead.
*
* @example
* ```typescript
* const grid = document.createElement('revo-grid');
* grid.pivot = {
* dimensions: [
* { prop: 'name', aggregator: 'sum' },
* ],
* rows: ['name'],
* columns: ['age'],
* values: [{ prop: 'salary', aggregator: 'sum' }],
* };
* ```
*/
pivot?: PivotConfig
}

The PivotPlugin is a RevoGrid plugin that enables dynamic creation and manipulation of pivot table structures within the grid. It provides users with the ability to configure and apply pivot transformations on grid data for enhanced reporting and analysis.

Key Features:

  • Configurable Pivot Table – Allows users to define row, column, and value fields dynamically.
  • Interactive Configurator – Integrates a pivot configurator panel to modify pivot settings in real-time.
  • Drag-and-Drop Support – Enables users to rearrange fields via the configurator for a flexible pivot experience.
  • Efficient Data Transformation – Utilizes optimized data processing to group and aggregate large datasets.
  • Custom Aggregations – Supports multiple aggregation functions, including sum, count, avg, min, and max.
  • Dynamic Theme Adaptation – Adjusts automatically to the applied RevoGrid theme.
  • State Persistence – Observes direct grid.pivot and legacy additionalData.pivot configuration updates.

Usage:

  • Instantiate the PivotPlugin in a RevoGrid instance and define a pivot configuration.
  • Use applyPivot to generate a pivoted grid based on selected row, column, and value fields.
  • Modify the pivot structure using the interactive configurator.
  • Call clearPivot to restore the original grid state.
import { PivotPlugin } from '@revolist/revogrid-pro';
const grid = document.createElement('revo-grid');
grid.plugins = [PivotPlugin];
grid.pivot = {
dimensions: [{ prop: 'Age' }, { prop: 'City' }, { prop: 'Gender' }, { prop: 'Total Spend' }],
rows: ['City', 'Age'],
columns: ['Gender'],
values: [
{ prop: 'Total Spend', aggregator: 'sum' },
],
hasConfigurator: true,
};

This plugin is essential for users who require advanced pivot table functionalities within RevoGrid, offering comprehensive tools for data transformation and visualization.

  • Required CorePlugin, PIVOT_CFG_UPDATE_EVENT, LOADER_EVENT: Uses Pro plugin infrastructure and events for lifecycle and loading state.
  • Config integration direct-pivot-config: Reads direct pivot configuration from grid.pivot.
  • Config integration additionalData.pivot: Reads legacy pivot configuration from additionalData.pivot.
  • Optional sorting-capable-plugin: Integrates with sorting state when present for field panel and remote sorting.
  • Optional pagination-capable-plugin: Integrates with pagination when present for remote pivot paging.
  • Auto-installed ContextMenuPlugin, PivotContextMenuPlugin, TooltipPlugin: Installs the shared tooltip and context-menu infrastructure plus the Pivot-semantic menu workspace.
  • Event integration groupexpandclick, column-collapse, column-expand, beforefilterapply, beforefilteroptionsourcerow, beforesortingapply: Listens to grid events to synchronize drill-down, collapsed groups, filter option rows, and server-mode requests.
class PivotPlugin {
/**
* Returns the last successfully committed Pivot model.
*
* A pending or failed remote load never replaces the previous snapshot.
* Returned arrays and records are read-only references to the active Pivot
* model rather than defensive copies.
*/
getRuntimeSnapshot(): PivotRuntimeSnapshot | null;
/** Returns the unprojected source owned by the active client Pivot session. */
getPivotOriginalSource();
getPivotEngineCapabilities(): PivotEngineCapabilities;
async loadPivotFilterValues(input: {
field: ColumnProp;
search?: string;
offset: number;
limit: number;
signal?: AbortSignal;
}): Promise<PivotFilterValuesResponse>;
async loadPivotDrilldown(input: {
cell: PivotDrilldownCellRef;
customColumns?: string[];
offset: number;
limit: number;
signal?: AbortSignal;
}): Promise<PivotDrilldownResponse>;
/**
* Applies one immutable Pivot configuration update through the public,
* preventable config event used by configurator and context-menu actions.
*/
async updatePivotConfig(nextConfig: Partial<PivotConfig>): Promise<boolean>;
/** Applies an explicit menu sorting state for a field or generated value column. */
async setPivotSorting(
prop: ColumnProp,
order?: 'asc' | 'desc',
measure?: PivotMeasureMeta,
): Promise<void>;
/**
* Returns the immediate row-hierarchy children for one committed client
* Pivot scope. The query only reads the aggregate index built during apply.
*/
async querySemanticSlice(
request: PivotSemanticSliceRequest,
context: { signal?: AbortSignal } = {},
): Promise<PivotSemanticSlice>;
/**
* Applies a chart-owned semantic drill frontier to Pivot expansion state.
* The operation uses the same config path for client and server engines, so
* model revisions and cancellation remain observable through normal Pivot
* lifecycle events.
*/
async synchronizeChartDrill(
detail: {
from: {
active: { row: { path: PivotPath }; column: { path: PivotPath } };
};
to: {
active: { row: { path: PivotPath }; column: { path: PivotPath } };
};
},
context: { signal?: AbortSignal } = {},
): Promise<void>;
updateConfigurator(config?: Partial<PivotConfig>);
updateFieldPanel(config?: Partial<PivotConfig>, resizedColumns?: ColumnResizeDetail);
/**
* Applies either the client or remote Pivot engine based on configuration.
*/
applyPivot(config?: Partial<PivotConfig>);
/**
* Clears managed Pivot state and restores the original grid payload.
*/
clearPivot();
}

PIVOT_VALUES_AXIS_FIELD: string;

export type PivotAxisField = ColumnProp | typeof PIVOT_VALUES_AXIS_FIELD;

interface PivotConfigValue {
/** Optional stable identity when the same source field is configured more than once. */
id?: string;
/** Source field used as the measure carrier. */
prop: ColumnProp;
/** Aggregator id resolved from the matching dimension definition. */
aggregator: string;
/** Optional display label used for generated measure row and column labels. */
label?: string;
/** Optional display name used when label is not provided. */
name?: string;
/** Optional post-aggregation analytical calculation. */
calculation?: PivotValueCalculation;
/** Optional Intl-backed display formatting. */
format?: PivotValueFormatConfig;
/** Optional measure-wide conditional formatting. */
conditionalFormatting?: {
match?: 'first' | 'all';
rules: PivotConditionalFormatRule[];
}
}

interface PivotSubtotalDisableRule {
/** Axis fields whose generated subtotal should be skipped. */
fields?: ColumnProp[];
/** Zero-based axis levels whose generated subtotal should be skipped. */
levels?: number[]
}

interface PivotColumnCollapseConfig {
/**
* Enable collapse for generated Pivot column groups.
*/
enabled?: boolean;
/**
* Start all generated Pivot column groups collapsed or expanded by default.
* Defaults to `true` when column collapse is enabled.
* Persisted group-specific state in `collapsedColumns` still takes precedence.
*/
collapsed?: boolean;
/**
* Show aggregate filters on collapsed columns and their expanded group
* headers. Defaults to `true`.
*
* This does not affect ordinary filters on expanded leaf value columns.
*/
filterable?: boolean;
/**
* Override the aggregator used for collapsed placeholder buckets.
* A string applies to every value field, while a record can target a specific value prop.
*/
aggregator?: string | Partial<Record<string, string>>;
/**
* Override the generated placeholder header or cell template used for collapsed groups.
*/
placeholder?: string | ColumnTemplateFunc | ColumnCollapsePlaceholder
}

export type PivotColumnSubtotalPosition = 'before' | 'after';

interface PivotGroupLabelConfig {
/** Display label for empty-string row and column group members. */
empty?: string;
/** Display label for null or undefined row and column group members. */
null?: string
}

export type PivotGroupLabelColumnMode = 'grouped' | 'firstVisible';

export type PivotRowAxisLayout = 'compact' | 'tabular';

PivotFieldPanelTexts (Extended from index.ts)

Section titled “PivotFieldPanelTexts (Extended from index.ts)”
interface PivotFieldPanelTexts {
}

interface PivotFieldPanelConfig {
/** Shows the in-grid Pivot field panel. */
visible?: boolean;
/** Shows the Reset layout action in Pivot configuration UI. Hidden by default. */
showResetLayout?: boolean;
/** Enables drag-and-drop field movement between panel areas. */
allowFieldDragging?: boolean;
/** Enables removing fields from panel areas. Disabled by default to avoid losing recoverability in compact layout. */
allowFieldRemoving?: boolean;
/** Shows the Rows area. */
showRowFields?: boolean;
/** Shows the Columns area. */
showColumnFields?: boolean;
/** Shows the Values/Data area. */
showDataFields?: boolean;
/** Shows the Filters area. */
showFilterFields?: boolean;
/** UI strings for the field panel. */
texts?: PivotFieldPanelTexts
}

The type of the panel

/** The type of the panel */
export type PanelType = 'dimensions' | 'rows' | 'columns' | 'values' | 'filters';

export type PivotFilterScalar = string | number | boolean | null;

Selects every value except the explicitly excluded members.

interface PivotFilterExclusionSelection {
mode: 'exclude';
values: PivotFilterScalar[]
}

Arrays retain the original inclusive-selection contract.

/** Arrays retain the original inclusive-selection contract. */
export type PivotFilterSelection =
| PivotFilterScalar[]
| PivotFilterExclusionSelection;

export type PivotFilterSelectionMap =
Partial<Record<string, PivotFilterSelection>>;

PivotConfigDimension (Extended from index.ts)

Section titled “PivotConfigDimension (Extended from index.ts)”
interface PivotConfigDimension {
prop: ColumnProp;
/** Preferred destination when the field is enabled through configurator selection. */
selectionTarget?: 'rows' | 'columns' | 'values';
/** Optional group label or nested group path used to organize the configurator dimensions grid. */
fieldGroup?: string | string[];
/** Optional field description shown by Pivot configuration UI. */
description?: string;
/** Hides the field from Pivot field-list helpers unless show-hidden mode is enabled. */
hidden?: boolean;
/**
* Custom aggregators or use common aggregators
*/
aggregators?: { [name: string]: ((values: any[]) => any) };
/** Values offered by the inline selector when this field is in Filters. */
filterOptions?: PivotFilterScalar[];
/**
* Aggregator value for the column
* set automatically
*/
readonly aggregator?: string;
/**
* The type of the dimension: rows, values
* set automatically
*/
readonly dimension?: PanelType
}

interface PivotConfig {
dimensions?: PivotConfigDimension[];
/** Ordered row dimensions used to build the pivot row hierarchy. */
rows: ColumnProp[];
/** Ordered column dimensions used to build generated pivot headers. */
columns?: ColumnProp[];
/** Measures rendered in the generated pivot cells. */
values: PivotConfigValue[];
/** Ordered filter fields shown in the Pivot field panel. */
filters?: ColumnProp[];
/**
* Canonical member selections for fields placed in Rows, Columns, or
* Filters. Missing/empty entries mean All.
*/
filterSelections?: PivotFilterSelectionMap;
/**
* Semantic post-aggregation filters for generated measures and totals.
*
* Member filters remain in `filterSelections` and execute before
* aggregation. Result filters execute after aggregation (SQL HAVING).
*/
resultFilters?: PivotAggregateFilterExpression;
/** Enables the configurator side panel. */
hasConfigurator?: boolean;
/** Configures the in-grid Pivot field panel. */
fieldPanel?: PivotFieldPanelConfig;
/** Advanced semantic Pivot context menu, enabled by default. */
contextMenu?: false | PivotContextMenuConfig;
/** Optional external mount target for the configurator. */
mountTo?: HTMLElement;
/** Flattens hierarchical column groups into single-label headers. */
flatHeaders?: boolean;
/** Merges generated value headers into the terminal Pivot column headers. */
mergeValueHeaders?: boolean;
/**
* Render Pivot value measures as row members instead of generated value columns.
*/
valuesOnRows?: boolean;
/**
* Advanced row hierarchy order. Use `$values` to place the measure pseudo-field
* at a specific position in the row tree.
*/
rowTree?: PivotAxisField[];
/**
* Controls how an active multi-level row hierarchy is rendered.
* `compact` uses one generated Rows column, while `tabular` keeps one
* visible column per row field. Active drill-down defaults to `compact`.
*/
rowAxisLayout?: PivotRowAxisLayout;
/** Shows the legacy configurator columns zone. */
showColumns?: boolean;
/** Shows the legacy configurator rows zone. */
showRows?: boolean;
/** Shows the legacy configurator values zone. */
showValues?: boolean;
/** Shows the legacy configurator filters zone. */
showFilters?: boolean;
/** Configures grand totals and subtotals. */
totals?: PivotConfigTotals;
/** Configures display labels for empty or null row and column group members. */
groupLabels?: PivotGroupLabelConfig;
/**
* Chooses which visible row cell renders the grouped-row label text.
* `grouped` keeps label text in the grouped field column.
* `firstVisible` renders label text in the first currently visible row cell.
*/
groupLabelColumn?: PivotGroupLabelColumnMode;
/**
* Enable Pivot drill-down based on the current row hierarchy.
* `true` starts collapsed, `false` starts expanded.
* The feature is only applied when at least two row fields are configured.
*/
collapsed?: boolean;
/**
* Persisted expand state for Pivot drill-down groups.
* Keys use the same grouped path format as RevoGrid grouping rows.
*/
expanded?: Record<string, boolean>;
/**
* Render aggregate values inside Pivot drill-down group rows.
* The initial implementation applies to the client-side Pivot path.
*/
groupAggregations?: boolean;
/**
* Configure built-in column drill-down on generated Pivot groups.
* Omit this option or use `true` to start collapsible groups collapsed.
* Use `false` or `{ enabled: false }` to disable column drill-down.
* `{ collapsed: false }` explicitly starts them expanded.
*/
columnCollapse?: boolean | PivotColumnCollapseConfig;
/**
* Per-level generated column behavior keyed by zero-based index in `columns`.
* Global collapse, totals, filter, and sorting settings remain the defaults.
*/
columnLevels?: Partial<Record<number, PivotColumnLevelConfig>>;
/**
* Initial or persisted collapsed state for generated pivot column groups.
* `true` collapses all generated groups by default.
*/
collapsedColumns?: boolean | Record<string, boolean>;
/** UI strings for the configurator. */
i18n?: typeof PIVOT_CONFIG_EN;
/**
* Optional engine selection. Omit it to keep the existing in-memory pivot behaviour.
* Server mode uses the same row/column/value configuration but delegates computation
* through an adapter or remote store.
*/
engine?: {
mode?: 'client' | 'server';
adapter?: PivotEngineAdapter;
remoteStore?: PivotRemoteStore;
/** Explicit feature advertisement used by analytical UI commands. */
capabilities?: PivotEngineCapabilities;
viewId?: string;
fieldsVersion?: string;
rowAxis?: Partial<PivotAxisViewport>;
columnAxis?: Partial<PivotAxisViewport>;
}
}

Creates a stable collision-safe id for a typed analytical path.

JSON contains tagged scalar tuples so equal display strings with different primitive types remain distinct.

export function createPivotPathId(
path: readonly (PivotAxisValue | undefined)[],
);

export function normalizePivotPath(
path: readonly (PivotAxisValue | undefined)[],
): PivotAxisValue[];

export function normalizePivotRuntimeConfig(
config: Partial<PivotConfig>,
): PivotConfig;

export function createPivotMeasureMeta(
value: Pick<PivotConfigValue, 'id' | 'prop' | 'aggregator' | 'label' | 'name'>,
valueIndex?: number,
): PivotMeasureMeta;

export function createPivotRowMeta(input: {
path: readonly (PivotAxisValue | undefined)[];
labels: readonly string[];
kind: PivotRowKind;
measure?: PivotMeasureMeta;
}): PivotRowMeta;

export function createPivotColumnMeta(input: {
path: readonly (PivotAxisValue | undefined)[];
labels: readonly string[];
kind: PivotColumnKind;
prop?: ColumnProp;
measure?: PivotMeasureMeta;
}): PivotColumnMeta;

export function getPivotRowMeta(row?: DataType): PivotRowMeta | undefined;

export function getPivotColumnMeta(
column?: ColumnGrouping | ColumnRegular,
): PivotColumnMeta | undefined;

PIVOT_MODEL_CHANGED_EVENT: string;

PIVOT_ROW_META: typeof PIVOT_ROW_META;

PIVOT_COLUMN_META: typeof PIVOT_COLUMN_META;

export type PivotEngineMode = 'client' | 'server';

export type PivotModelChangedReason = 'client-apply' | 'server-apply' | 'clear';

export type PivotAxisValue = string | number | boolean | null;

export type PivotRowKind = 'leaf' | 'subtotal' | 'grandTotal' | 'group';

export type PivotColumnKind =
| 'leaf'
| 'subtotal'
| 'grandTotal'
| 'collapsed'
| 'group';

interface PivotMeasureMeta {
readonly id?: string;
readonly valueIndex?: number;
readonly prop: ColumnProp;
readonly aggregator: string;
readonly label: string
}

interface PivotRowMeta {
readonly id: string;
readonly path: readonly PivotAxisValue[];
readonly labels: readonly string[];
readonly depth: number;
readonly kind: PivotRowKind;
readonly measure?: PivotMeasureMeta
}

interface PivotColumnMeta {
readonly id: string;
readonly path: readonly PivotAxisValue[];
readonly labels: readonly string[];
readonly depth: number;
readonly kind: PivotColumnKind;
/** Generated RevoGrid cell carrier property. Omitted for header groups. */
readonly prop?: ColumnProp;
/** Measure represented by a terminal value column. */
readonly measure?: PivotMeasureMeta
}

interface PivotModelChangedEventDetail {
readonly revision: number;
readonly reason: PivotModelChangedReason;
readonly engine: PivotEngineMode
}

interface PivotRuntimeSnapshot {
readonly revision: number;
readonly engine: PivotEngineMode;
/** Active config with row, column, value, dimension, and filter arrays present. */
readonly config: Readonly<PivotConfig>;
readonly source: readonly DataType[];
readonly columns: ReadonlyArray<ColumnGrouping | ColumnRegular>;
readonly pinnedBottomSource: readonly DataType[];
/** Group frontier aggregates keyed by collision-safe semantic row id. */
readonly groupAggregates: Readonly<Record<string, DataType>>;
/** Optional JSON-safe hierarchy metadata for semantic analytical slices. */
readonly hierarchies?: PivotRuntimeHierarchies;
readonly remoteRequest?: Readonly<PivotLoadRequest>
}

export type PivotRowWithMeta = DataType & {
[PIVOT_ROW_META]?: PivotRowMeta;
};

PivotColumnWithMeta (Extended from index.ts)

Section titled “PivotColumnWithMeta (Extended from index.ts)”
export type PivotColumnWithMeta = (ColumnGrouping | ColumnRegular) & {
[PIVOT_COLUMN_META]?: PivotColumnMeta;
};

Builds the full client-side Pivot result set from raw source rows.

export function createPivotData(
originalData: DataType[],
config: Partial<PivotConfig>,
);

Builds the full client-side Pivot result set together with grouped-row aggregate payloads keyed by RevoGrid grouped path values.

export function createPivotDataModel(
originalData: DataType[],
config: Partial<PivotConfig>,
options: PivotDataModelOptions = {},
): PivotDataModel;

export type PivotGroupAggregates = Record<string, DataType>;

interface PivotDataModel {
rows: DataType[];
groupAggregatesByPath: PivotGroupAggregates;
semanticGroupAggregatesById: PivotGroupAggregates;
/** @internal Shared path metadata used to project the same visible column frontier. */
columnAxis?: PivotColumnAxis;
/** Runtime-only hierarchy index used by semantic Pivot slice queries. */
semanticSliceIndex?: PivotSemanticSliceIndex
}

interface PivotDataModelOptions {
/**
* Collapsed aggregate paths that must remain materialized while their groups
* are expanded because an active filter still targets those aggregates.
*/
aggregateFilterPaths?: readonly (readonly PivotGroupValue[])[]
}

Builds the generated RevoGrid column model for the current Pivot config. The source is only used to discover unique analytical column paths.

export function pivotColumns(
config: Partial<PivotConfig>,
source: DataType[] = [],
columnAxis: PivotColumnAxis = createPivotColumnAxis(config, source),
);

export function withPivotTotalLabelTemplates(
columns: Array<ColumnGrouping | ColumnRegular>,
config: Partial<PivotConfig>,
columnTypes: ColumnTypes = {},
): Array<ColumnGrouping | ColumnRegular>;

Applies measure-owned number and conditional formatting to generated value columns after their semantic metadata has been materialized.

export function withPivotValuePresentation(
columns: Array<ColumnGrouping | ColumnRegular>,
config: Partial<PivotConfig>,
columnTypes: ColumnTypes = {},
): Array<ColumnGrouping | ColumnRegular>;

export function pivotColumnsFromPaths(
config: Partial<PivotConfig>,
paths: Array<Array<string | number | boolean | null>>,
);

PIVOT_TOTAL_CELL_CLASS: string;

PIVOT_ROW_FILTER_ACTIVE_HEADER_CLASS: string;

export type PivotSummaryType = 'sum' | 'min' | 'max' | 'avg' | 'count';

export type PivotFieldDataType = 'string' | 'number' | 'date' | 'boolean';

export type PivotLogicalOperator = 'and' | 'or';

export type PivotSortDirection = 'asc' | 'desc';

Stable result id of the summary used for analytical member sorting.

/** Stable result id of the summary used for analytical member sorting. */
export type PivotSortBySummaryType = string;

export type PivotDateGroupInterval = 'year' | 'quarter' | 'month' | 'day' | 'dayOfWeek';

export type PivotGroupInterval =
| PivotDateGroupInterval
| {
/** Numeric bucket grouping for OLAP-style measure banding. */
type: 'numericBucket';
/** Bucket width. A size of `100` yields buckets such as `0-99`, `100-199`, and so on. */
size: number;
};

export type PivotFilterOperation =
| '='
| '<>'
| '>'
| '>='
| '<'
| '<='
| 'contains'
| 'notcontains'
| 'startswith'
| 'endswith'
| 'in'
| 'notin';

export type PivotPath = Array<string | number | boolean | null>;

export type PivotFilterValue =
| string
| number
| boolean
| null
| Array<string | number | boolean | null>;

export type PivotFilterCondition = [selector: string, operation: PivotFilterOperation, value: PivotFilterValue];

export type PivotFilterExpression =
| PivotFilterCondition
| [left: PivotFilterExpression, operator: PivotLogicalOperator, right: PivotFilterExpression]
| ['!', PivotFilterExpression];

export type PivotAggregateColumnKind =
| 'leaf'
| 'subtotal'
| 'grandTotal'
| 'collapsed';

Post-aggregation predicate for one generated Pivot value column.

The semantic path and summary replace the grid’s synthetic carrier prop so remote stores can compile a stable HAVING expression.

interface PivotAggregateFilterDescriptor {
columnPath: PivotPath;
columnKind: PivotAggregateColumnKind;
summary: PivotSummaryDescriptor;
operation: PivotFilterOperation;
value: PivotFilterValue
}

Boolean post-aggregation filter tree.

Aggregate filters use semantic Pivot coordinates instead of generated grid properties so the expression survives projection, saved-view, and server round trips.

/**
* Boolean post-aggregation filter tree.
*
* Aggregate filters use semantic Pivot coordinates instead of generated grid
* properties so the expression survives projection, saved-view, and server
* round trips.
*/
export type PivotAggregateFilterExpression =
| PivotAggregateFilterDescriptor
| [
left: PivotAggregateFilterExpression,
operator: PivotLogicalOperator,
right: PivotAggregateFilterExpression,
]
| ['!', PivotAggregateFilterExpression];

interface PivotGroupDescriptor {
/** Public field id resolved through the server-side field registry. */
selector: string;
/** Descending sort flag for the grouped members on this axis level. */
desc?: boolean;
/** Optional date or numeric-bucket grouping strategy for this selector. */
groupInterval?: PivotGroupInterval
}

interface PivotSummaryDescriptor {
/** Optional stable measure id, required when one selector is used more than once. */
id?: string;
/** Public field id of the measure being aggregated. */
selector: string;
/** Stable summary function id returned by the analytical engine. */
summaryType: PivotSummaryType;
/** Optional post-aggregation calculation advertised by the engine. */
calculation?: PivotValueCalculation
}

Optional server feature advertisement. Context-menu analytical commands stay disabled until the backing engine explicitly opts into the corresponding operation.

interface PivotEngineCapabilities {
aggregation?: boolean;
calculations?: boolean | PivotValueCalculationType[];
filter?: boolean;
filterValues?: boolean;
sort?: boolean;
drilldown?: boolean
}

interface PivotSortDescriptor {
/** Public field id to sort by. */
selector: string;
/** Descending sort flag for the selector or summary. */
desc?: boolean;
/** Optional summary id used when the backend supports sort-by-summary semantics. */
bySummary?: PivotSortBySummaryType
}

interface PivotAxisViewport {
/** Zero-based analytical offset for this axis window. */
offset: number;
/** Requested analytical window size for this axis. */
limit: number;
/** Expanded analytical members represented as paths, never as UI indexes. */
expandedPaths?: PivotPath[];
/** Collapsed analytical members represented as paths, never as UI indexes. */
collapsedPaths?: PivotPath[]
}

interface PivotUiStateHints {
/** Preferred row-header presentation for engines that can shape tree metadata. */
rowHeaderLayout?: 'tree' | 'flat';
/** Preferred totals placement hint for the analytical engine. */
showTotalsPrior?: 'rows' | 'columns' | 'none';
/** Hint that the UI currently expects collapsed-by-default hierarchies. */
collapsedByDefault?: boolean;
/** Hint that generated column groups are collapsed by default. */
columnGroupsCollapsedByDefault?: boolean
}

interface PivotLoadOptions {
/** Registry-backed filter expression tree. */
filter?: PivotFilterExpression;
/** Post-aggregation expression for generated Pivot value columns. */
having?:
| PivotAggregateFilterExpression
| PivotAggregateFilterDescriptor[];
/** Row-axis grouping descriptors. */
rows?: PivotGroupDescriptor[];
/** Column-axis grouping descriptors. */
columns?: PivotGroupDescriptor[];
/** Grand-total summary descriptors. */
totalSummary?: PivotSummaryDescriptor[];
/** Group-level summary descriptors. */
groupSummary?: PivotSummaryDescriptor[];
/** Analytical sorting directives. */
sort?: PivotSortDescriptor[]
}

interface PivotLoadRequest {
/** Client-generated correlation id for logs, tracing, and stale-response protection. */
requestId: string;
/** Dataset or semantic view identifier understood by the backend. */
viewId: string;
/** Version or checksum of the published field registry for this view. */
fieldsVersion: string;
/** Analytical layout, filters, summaries, and sort instructions. */
loadOptions: PivotLoadOptions;
/** Independent analytical windows for the row and column axes. */
viewport: {
rowAxis: PivotAxisViewport;
columnAxis: PivotAxisViewport;
};
/** Optional UI hints that let a backend align with current Pivot presentation preferences. */
uiState?: PivotUiStateHints
}

interface PivotAxisWindowMeta {
/** Total number of analytical members available on this axis. */
totalCount?: number;
/** Optional analytical paths used to materialize generated Pivot columns. */
paths?: PivotPath[];
/** Zero-based analytical offset for this axis window. */
offset?: number;
/** Requested analytical window size for this axis. */
limit?: number;
/** Expanded analytical members represented as paths. */
expandedPaths?: PivotPath[];
/** Collapsed analytical members represented as paths. */
collapsedPaths?: PivotPath[];
/** Actual number of members returned in this window. */
returned?: number
}

interface PivotLoadResponseMeta {
/** Cache outcome for observability and UI diagnostics. */
cacheStatus: 'hit' | 'miss' | 'warm' | 'bypass';
/** Correlation cache key. */
cacheKey?: string;
/** Server-side generation timestamp. */
generatedAt?: string;
/** Elapsed processing time in milliseconds. */
elapsedMs?: number;
/** Optional warnings or diagnostic messages. */
warnings?: string[]
}

interface PivotLoadResponse {
/** Visible analytical payload or already materialized row records. */
data: PivotMaterializedRow[];
/** Total or pinned summary rows for the current analytical request. */
summary: unknown[];
/** Row-axis window metadata. */
rowAxis: PivotAxisWindowMeta;
/** Column-axis window metadata. */
columnAxis: PivotAxisWindowMeta;
/** Optional grouped-row aggregate payloads keyed by grouped path values. */
groupAggregates?: Record<string, DataType>;
/** Cache and timing metadata for diagnostics. */
meta: PivotLoadResponseMeta;
/** Correlation id. */
requestId?: string;
/** Response format version. */
version?: number
}

Hidden stable measure identity accepted on already materialized values-on-rows response records. It disambiguates measures that intentionally share labels.

PIVOT_MEASURE_ID_PROP: string;

PivotMaterializedRow (Extended from index.ts)

Section titled “PivotMaterializedRow (Extended from index.ts)”
export type PivotMaterializedRow = DataType & {
[PIVOT_MEASURE_ID_PROP]?: string;
};

interface PivotDrilldownCellRef {
/** Row-axis path for the visible summary cell. */
rowPath: PivotPath;
/** Column-axis path for the visible summary cell. */
columnPath: PivotPath;
/** Optional measure index when multiple values are present. */
dataIndex?: number
}

interface PivotDrilldownRequest {
/** Client-generated correlation id for the drilldown request. */
requestId: string;
/** Dataset or semantic view identifier understood by the backend. */
viewId: string;
/** Version or checksum of the published field registry for this view. */
fieldsVersion: string;
/** Visible pivot cell that defines the drilldown scope. */
cell: PivotDrilldownCellRef;
/** Optional whitelist-validated columns to expose in the fact page. */
customColumns?: string[];
/** Zero-based fact-page offset. */
offset: number;
/** Requested fact-page size. */
limit: number
}

interface PivotDrilldownResponse {
/** Matching fact rows for the requested summary cell. */
data: DataType[];
/** Total number of matching facts. */
totalCount: number;
/** Optional cache metadata for drilldown responses. */
meta?: Partial<PivotLoadResponseMeta>;
/** Correlation id. */
requestId?: string
}

interface PivotFilterValuesRequest {
/** Client-generated correlation id for cancellation and tracing. */
requestId: string;
/** Dataset or semantic view identifier understood by the backend. */
viewId: string;
/** Version or checksum of the published field registry. */
fieldsVersion: string;
/** Public field id whose distinct values are requested. */
selector: string;
/** Active report filters excluding the requested selector. */
filter?: PivotFilterExpression;
/** Optional search text applied by the engine before paging. */
search?: string;
/** Zero-based distinct-value page offset. */
offset: number;
/** Requested distinct-value page size. */
limit: number
}

interface PivotFilterValuesResponse {
requestId?: string;
values: Array<string | number | boolean | null>;
totalCount: number
}

interface PivotStateSaveRequest {
/** Client-generated correlation id for persistence. */
requestId: string;
/** View identifier whose UI state is being persisted. */
viewId: string;
/** User identifier that owns the saved state. */
userId: string;
/** Arbitrary persisted Pivot UI state payload. */
state: Record<string, unknown>
}

interface PivotStateResponse {
/** Optional echoed correlation id from the request. */
requestId?: string;
/** User identifier that owns the state. */
userId: string;
/** View identifier for the saved state. */
viewId: string;
/** Persisted Pivot UI state payload. */
state: Record<string, unknown>;
/** Optional schema version for persisted state. */
version?: number
}

interface PivotCacheInvalidationRequest {
/** Client-generated correlation id for invalidation requests. */
requestId: string;
/** Tenant scope to invalidate. */
tenantId?: string;
/** Optional view scope within the tenant. */
viewId?: string;
/** Dataset watermark to invalidate. */
datasetWatermark?: string;
/** Optional field-registry version scope. */
fieldsVersion?: string
}

interface PivotLimits {
/** Hard cap for row-axis windows. */
maxRowWindowSize: number;
/** Hard cap for column-axis windows. */
maxColumnWindowSize: number;
/** Hard cap for expanded analytical members. */
maxExpandedPaths: number;
/** Hard cap for analytical hierarchy depth. */
maxExpansionDepth: number;
/** Hard cap for drilldown page size. */
maxDrilldownLimit: number;
/** Hard cap for requested summary descriptors. */
maxSummaryDescriptors: number;
/** Hard cap for row or column grouping descriptors. */
maxGroupDescriptors: number;
/** Hard cap for nested filter-expression depth. */
maxFilterDepth: number
}

interface PivotGridModel {
/** Generated RevoGrid columns for the visible Pivot window. */
columns: Array<ColumnGrouping | ColumnRegular>;
/** Visible body rows to render in the grid viewport. */
source: DataType[];
/** Optional pinned grand-total rows. */
pinnedBottomSource?: DataType[];
/** Optional grouped-row metadata for Pivot drill-down. */
grouping?: GroupingOptions;
/** Response metadata forwarded to UI diagnostics if needed. */
meta?: Partial<PivotLoadResponseMeta>
}

Analytical engine boundary used by PivotPlugin.

Use this when your application wants to translate Pivot requests directly into OLAP, warehouse, or semantic-layer queries without going through HttpPivotRemoteStore.

interface PivotEngineAdapter {
readonly capabilities?: PivotEngineCapabilities;
load(request: PivotLoadRequest, signal?: AbortSignal): Promise<PivotLoadResponse>;
drilldown?(request: PivotDrilldownRequest, signal?: AbortSignal): Promise<PivotDrilldownResponse>;
filterValues?(
request: PivotFilterValuesRequest,
signal?: AbortSignal,
): Promise<PivotFilterValuesResponse>
}

Async auth-header resolver used by HTTP-backed remote stores.

/** Async auth-header resolver used by HTTP-backed remote stores. */
export type PivotAuthProvider = () => Promise<Record<string, string>>;

Framework-agnostic client contract for server-side Pivot operations.

In production this should usually talk to an application API that owns auth, tenancy, selector validation, and query translation. It is not intended for direct browser-to-database connections.

interface PivotRemoteStore {
readonly capabilities?: PivotEngineCapabilities;
load(request: PivotLoadRequest, signal?: AbortSignal): Promise<PivotLoadResponse>;
drilldown(
request: PivotDrilldownRequest,
signal?: AbortSignal,
): Promise<PivotDrilldownResponse>;
filterValues?(
request: PivotFilterValuesRequest,
signal?: AbortSignal,
): Promise<PivotFilterValuesResponse>;
saveState(request: PivotStateSaveRequest, signal?: AbortSignal): Promise<void>;
loadState(userId: string, viewId: string, signal?: AbortSignal): Promise<PivotStateResponse>
}

interface PivotRemoteStoreHooks {
requestStarted?: (event: { key: string; type: 'load' | 'drilldown' | 'saveState' | 'loadState' }) => void;
requestSucceeded?: (
event: { key: string; type: 'load' | 'drilldown' | 'saveState' | 'loadState'; cacheStatus?: string },
) => void;
requestFailed?: (
event: { key: string; type: 'load' | 'drilldown' | 'saveState' | 'loadState'; error: unknown },
) => void;
cacheStatusChanged?: (event: { key: string; cacheStatus: string }) => void
}

interface PivotRemoteStoreOptions {
/** Base URL of the application API that exposes `/api/pivot/*` endpoints. */
baseUrl?: string;
/** Tenant scope used for cache keys and backend request routing. */
tenantId?: string;
/** Dataset or cube watermark used to separate stale and fresh cached results. */
datasetWatermark?: string;
/** Async auth-header provider, typically used for bearer tokens or session headers. */
authProvider?: PivotAuthProvider;
/** Custom fetch implementation for frameworks, SSR, tests, or mocked transports. */
fetchImpl?: typeof fetch;
/** Optional lifecycle hooks for request telemetry and cache diagnostics. */
hooks?: PivotRemoteStoreHooks
}

Default remote store backed by fetch and the public Pivot HTTP contract.

class HttpPivotRemoteStore {
load(request: PivotLoadRequest, signal?: AbortSignal): Promise<PivotLoadResponse>;
drilldown(request: PivotDrilldownRequest, signal?: AbortSignal): Promise<PivotDrilldownResponse>;
async saveState(request: PivotStateSaveRequest, signal?: AbortSignal): Promise<void>;
loadState(userId: string, viewId: string, signal?: AbortSignal): Promise<PivotStateResponse>;
}

export function createPivotDrilldownRequest(
input: PivotDrilldownRequestInput,
createRequestId: () => string = createDefaultDrilldownRequestId,
): PivotDrilldownRequest;

export function createPivotDrilldownTableModel(
response: PivotDrilldownResponse,
request?: PivotDrilldownRequest,
): PivotDrilldownTableModel;

export function createPivotDrilldownColumns(
rows: DataType[],
customColumns?: string[],
): ColumnRegular[];

export type PivotDrilldownStatus = 'idle' | 'loading' | 'success' | 'error';

interface PivotDrilldownRequestInput {
/** Dataset or semantic view identifier understood by the adapter/backend. */
viewId: string;
/** Version or checksum of the field registry for this view. */
fieldsVersion: string;
/** Visible pivot cell that defines the source-row scope. */
cell: PivotDrilldownCellRef;
/** Optional whitelist-validated columns to expose in the fact page. */
customColumns?: string[];
/** Zero-based fact-page offset. Defaults to 0. */
offset?: number;
/** Requested fact-page size. Defaults to 100. */
limit?: number;
/** Optional caller-provided correlation id. */
requestId?: string
}

interface PivotDrilldownTableModel {
/** RevoGrid/table-ready fact columns. */
columns: ColumnRegular[];
/** Fact rows returned by the adapter. */
rows: DataType[];
/** Total matching facts across all pages. */
totalCount: number
}

PivotDrilldownState (Extended from index.ts)

Section titled “PivotDrilldownState (Extended from index.ts)”
interface PivotDrilldownState {
status: PivotDrilldownStatus;
loading: boolean;
error?: unknown;
request?: PivotDrilldownRequest;
response?: PivotDrilldownResponse
}

interface PivotDrilldownControllerOptions {
/** Default page size used when `load` does not specify a limit. */
defaultLimit?: number;
/** Correlation id generator used by the request builder. */
createRequestId?: () => string
}

export type PivotDrilldownStateListener = (state: PivotDrilldownState) => void;

class PivotDrilldownController {
getState();
subscribe(listener: PivotDrilldownStateListener);
async load(input: PivotDrilldownRequestInput, signal?: AbortSignal);
abort();
reset();
}

export async function savePivotView(
store: PivotRemoteStore,
options: PivotSaveViewOptions,
): Promise<PivotSavedView>;

export async function loadPivotView(
store: PivotRemoteStore,
options: PivotLoadViewOptions,
): Promise<PivotSavedView>;

export function createPivotSavedViewState(
config: Partial<PivotConfig>,
metadata: { name?: string; savedAt?: string } = {},
): PivotSavedViewState;

export function serializePivotConfig(config: Partial<PivotConfig>): Partial<PivotConfig>;

export function pivotSavedViewFromState(response: PivotStateResponse): PivotSavedView;

export function renamePivotSavedView(
views: readonly PivotSavedViewRecord[],
options: PivotRenameViewOptions,
): PivotSavedViewRecord[];

export function duplicatePivotSavedView(
views: readonly PivotSavedViewRecord[],
options: PivotDuplicateViewOptions,
): PivotSavedViewRecord[];

export function deletePivotSavedView(
views: readonly PivotSavedViewRecord[],
options: PivotDeleteViewOptions,
): PivotSavedViewRecord[];

PIVOT_SAVED_VIEW_STATE_KIND: string;

PIVOT_SAVED_VIEW_STATE_VERSION: 2;

interface PivotSavedViewRef {
/** User identifier that owns the saved view. */
userId: string;
/** View identifier used by the remote state store. */
viewId: string
}

interface PivotSavedView {
/** Serializable Pivot configuration restored from the saved view payload. */
config: Partial<PivotConfig>;
/** Optional display name supplied by the application. */
name?: string;
/** Optional ISO timestamp supplied by the application or backend. */
savedAt?: string;
/** Persisted state schema version. */
version: number;
/** Optional echoed correlation id from the remote state response. */
requestId?: string
}

PivotSavedViewDeleteIntent (Extended from index.ts)

Section titled “PivotSavedViewDeleteIntent (Extended from index.ts)”
interface PivotSavedViewDeleteIntent {
/** Marks a saved view for deletion by the application or remote state sync layer. */
deleted: true;
/** Optional ISO timestamp supplied by the application. */
deletedAt?: string;
/** Optional client-generated correlation id. */
requestId?: string
}

export type PivotSavedViewRecord = PivotSavedView | PivotSavedViewDeleteIntent;

PivotSaveViewOptions (Extended from index.ts)

Section titled “PivotSaveViewOptions (Extended from index.ts)”
interface PivotSaveViewOptions {
/** Active Pivot config to serialize into the remote state payload. */
config: Partial<PivotConfig>;
/** Optional display name supplied by the application. */
name?: string;
/** Optional client-generated correlation id. */
requestId?: string;
/** Optional ISO timestamp. Defaults to the current time. */
savedAt?: string;
/** Optional abort signal forwarded to the remote store. */
signal?: AbortSignal
}

PivotRenameViewOptions (Extended from index.ts)

Section titled “PivotRenameViewOptions (Extended from index.ts)”
interface PivotRenameViewOptions {
/** Next display name for the saved view. */
name: string
}

PivotDuplicateViewOptions (Extended from index.ts)

Section titled “PivotDuplicateViewOptions (Extended from index.ts)”
interface PivotDuplicateViewOptions {
/** Optional explicit identifier for the duplicated view. */
newViewId?: string;
/** Optional duplicated view name. Defaults to "<source name> Copy". */
name?: string;
/** Optional ISO timestamp copied into the duplicated view. */
savedAt?: string;
/** Optional client-generated correlation id. */
requestId?: string;
/** Stable id factory for deterministic tests and app-owned id schemes. */
generateId?: (view: PivotSavedView, views: readonly PivotSavedViewRecord[]) => string
}

PivotDeleteViewOptions (Extended from index.ts)

Section titled “PivotDeleteViewOptions (Extended from index.ts)”
interface PivotDeleteViewOptions {
/** Optional ISO timestamp supplied by the application. */
deletedAt?: string;
/** Optional client-generated correlation id. */
requestId?: string
}

PivotLoadViewOptions (Extended from index.ts)

Section titled “PivotLoadViewOptions (Extended from index.ts)”
interface PivotLoadViewOptions {
/** Optional abort signal forwarded to the remote store. */
signal?: AbortSignal
}

PivotSavedViewState (Extended from index.ts)

Section titled “PivotSavedViewState (Extended from index.ts)”
interface PivotSavedViewState {
kind: typeof PIVOT_SAVED_VIEW_STATE_KIND;
version: typeof PIVOT_SAVED_VIEW_STATE_VERSION;
config: Partial<PivotConfig>;
name?: string;
savedAt?: string
}

Converts a field entry list into an id-addressable registry map.

export function createFieldRegistry(entries: FieldRegistryEntry[]): PivotFieldRegistry;

Resolves a public selector or throws the stable invalid-selector error.

export function getFieldRegistryEntry(
registry: PivotFieldRegistry,
selector: string,
): FieldRegistryEntry;

Validates that a requested summary is allowed for the selector.

export function assertSummaryAllowed(
registry: PivotFieldRegistry,
descriptor: PivotSummaryDescriptor,
);

Validates that a requested grouping interval is allowed for the selector.

export function assertGroupIntervalAllowed(
registry: PivotFieldRegistry,
descriptor: PivotGroupDescriptor,
);

Validates that requested drill-down columns are safe to expose.

export function assertDrilldownColumnsAllowed(
registry: PivotFieldRegistry,
columns: string[] = [],
);

interface BackendExpression {
kind: 'column' | 'sql';
value: string
}

interface FieldRegistryEntry {
id: string;
label: string;
dataType: PivotFieldDataType;
expression: BackendExpression;
allowedOperations: PivotFilterOperation[];
allowedSummaries?: PivotSummaryType[];
allowedGroupIntervals?: PivotGroupInterval[];
drilldownVisible?: boolean
}

export type PivotFieldRegistry = Record<string, FieldRegistryEntry>;

Serializes either a PivotError or a raw payload into the wire format.

export function createPivotErrorResponse(
requestId: string,
error: PivotError | PivotErrorPayload,
): PivotErrorResponse;

Pivot errors define the stable, serializable error contract shared by local validation and remote endpoint implementations.

/**
* Pivot errors define the stable, serializable error contract shared by local
* validation and remote endpoint implementations.
*/
export type PivotErrorCode =
| 'PIVOT_NOT_ACTIVE'
| 'REVISION_MISMATCH'
| 'INVALID_HIERARCHY_PATH'
| 'HIERARCHY_UNAVAILABLE'
| 'INVALID_SELECTOR'
| 'INVALID_FILTER_OPERATION'
| 'INVALID_SUMMARY_TYPE'
| 'INVALID_GROUP_INTERVAL'
| 'WINDOW_LIMIT_EXCEEDED'
| 'EXPANSION_LIMIT_EXCEEDED'
| 'AUTH_REQUIRED'
| 'FORBIDDEN'
| 'STATE_NOT_FOUND'
| 'CACHE_INVALIDATION_FORBIDDEN'
| 'INTERNAL_ERROR';

interface PivotErrorPayload {
code: PivotErrorCode;
message: string;
details?: Record<string, unknown>
}

interface PivotErrorResponse {
requestId: string;
error: PivotErrorPayload
}

Error class carrying the public Pivot error code and optional details.

class PivotError {}

Normalizes and validates a pivot load request.

export function normalizePivotLoadRequest(
request: PivotLoadRequest,
registry: PivotFieldRegistry,
limits: PivotLimits = DEFAULT_PIVOT_LIMITS,
): NormalizedPivotLoadRequest;

Validates both the semantic HAVING tree and the legacy flat descriptor list.

export function normalizeAggregateFilterExpression(
expression:
| PivotAggregateFilterExpression
| PivotAggregateFilterDescriptor[]
| undefined,
registry: PivotFieldRegistry,
limits: Pick<
PivotLimits,
'maxSummaryDescriptors' | 'maxExpansionDepth' | 'maxFilterDepth'
> = DEFAULT_PIVOT_LIMITS,
):
| PivotAggregateFilterExpression
| PivotAggregateFilterDescriptor[]
| undefined;

Validates post-aggregation filters without treating generated props as fields.

export function normalizeAggregateFilters(
filters: PivotAggregateFilterDescriptor[],
registry: PivotFieldRegistry,
limits: Pick<PivotLimits, 'maxSummaryDescriptors' | 'maxExpansionDepth'> = DEFAULT_PIVOT_LIMITS,
): PivotAggregateFilterDescriptor[] | undefined;

Normalizes and validates a drill-down request.

export function normalizePivotDrilldownRequest(
request: PivotDrilldownRequest,
registry: PivotFieldRegistry,
limits: PivotLimits = DEFAULT_PIVOT_LIMITS,
): NormalizedPivotDrilldownRequest;

Validates and normalizes nested filter expressions recursively.

export function normalizeFilterExpression(
filter: PivotFilterExpression,
registry: PivotFieldRegistry,
maxDepth: number,
depth = 1,
): PivotFilterExpression;

Sorts and validates analytical expansion paths.

export function normalizeExpandedPaths(
expandedPaths: PivotPath[] = [],
limits: Pick<PivotLimits, 'maxExpandedPaths' | 'maxExpansionDepth'> = DEFAULT_PIVOT_LIMITS,
);

Enforces viewport limits and normalized expansion state for one axis.

export function normalizeViewportAxis(
viewport: PivotAxisViewport,
maxWindowSize: number,
limits: Pick<PivotLimits, 'maxExpandedPaths' | 'maxExpansionDepth'> = DEFAULT_PIVOT_LIMITS,
): PivotAxisViewport;

Validates and canonicalizes summary descriptors.

export function normalizeSummaries(
descriptors: PivotSummaryDescriptor[],
registry: PivotFieldRegistry,
limits: Pick<PivotLimits, 'maxSummaryDescriptors'> = DEFAULT_PIVOT_LIMITS,
);

Validates and canonicalizes grouping descriptors.

export function normalizeGroups(
descriptors: PivotGroupDescriptor[],
registry: PivotFieldRegistry,
limits: Pick<PivotLimits, 'maxGroupDescriptors'> = DEFAULT_PIVOT_LIMITS,
);

Builds the stable result-field name for a summary descriptor.

export function getSummaryResultId(summary: PivotSummaryDescriptor);

export type NormalizedPivotLoadRequest = PivotLoadRequest;

export type NormalizedPivotDrilldownRequest = PivotDrilldownRequest;

DEFAULT_PIVOT_LIMITS: {
maxRowWindowSize: number;
maxColumnWindowSize: number;
maxExpandedPaths: number;
maxExpansionDepth: number;
maxDrilldownLimit: number;
maxSummaryDescriptors: number;
maxGroupDescriptors: number;
maxFilterDepth: number;
};

Stringifies nested values with stable object key ordering.

export function stableStringify(value: unknown): string;

Builds the canonical cache key for a pivot load window.

export function createPivotCacheKey(context: PivotCacheKeyContext): string;

interface PivotCacheKeyContext {
tenantId: string;
viewId: string;
fieldsVersion: string;
datasetWatermark?: string;
request: Omit<PivotLoadRequest, 'requestId' | 'viewId' | 'fieldsVersion'>
}

PlannedPivotSummary (Extended from index.ts)

Section titled “PlannedPivotSummary (Extended from index.ts)”
interface PlannedPivotSummary {
resultId: string;
execution:
| {
type: 'direct';
field: FieldRegistryEntry;
}
| {
type: 'composite';
components: Array<{
selector: string;
summaryType: 'sum' | 'count';
}>;
}
}

interface PivotQueryPlan {
request: PivotLoadRequest;
filteredBaseDataset: {
viewId: string;
fieldsVersion: string;
filter?: PivotLoadRequest['loadOptions']['filter'];
};
rowAxis: {
groups: PivotGroupDescriptor[];
viewport: PivotLoadRequest['viewport']['rowAxis'];
};
columnAxis: {
groups: PivotGroupDescriptor[];
viewport: PivotLoadRequest['viewport']['columnAxis'];
};
summaries: PlannedPivotSummary[];
/** Post-aggregation predicates compiled by the backend as HAVING clauses. */
having: PivotLoadRequest['loadOptions']['having'];
orderBy: PivotLoadRequest['loadOptions']['sort']
}

interface DrilldownQueryPlan {
request: PivotDrilldownRequest;
visibleFields: FieldRegistryEntry[]
}

interface PivotQueryPlanner {
planLoad(request: PivotLoadRequest): PivotQueryPlan;
planDrilldown(request: PivotDrilldownRequest): DrilldownQueryPlan
}

SQL-oriented logical planner that resolves field metadata and summaries.

class SqlPivotQueryPlanner {
planLoad(request: PivotLoadRequest): PivotQueryPlan;
planDrilldown(request: PivotDrilldownRequest): DrilldownQueryPlan;
}

Derives the visible analytical column paths used by the client adapter.

export function getPivotColumnPaths(
source: DataType[],
config: Partial<PivotConfig>,
);

Client adapter keeps the existing client-side pivot behaviour behind the same engine interface used by the remote path.

class ClientPivotEngineAdapter {
async load(request: PivotLoadRequest): Promise<PivotLoadResponse>;
async drilldown(request: PivotDrilldownRequest): Promise<PivotDrilldownResponse>;
async filterValues(
request: PivotFilterValuesRequest,
): Promise<PivotFilterValuesResponse>;
}

Remote adapter forwards requests to a framework-agnostic PivotRemoteStore.

class ServerPivotEngineAdapter {
load(request: PivotLoadRequest, signal?: AbortSignal);
drilldown(request: PivotDrilldownRequest, signal?: AbortSignal);
filterValues(request: PivotFilterValuesRequest, signal?: AbortSignal);
}

Converts a pivot response into the visible source/columns payload consumed by the plugin.

export function createGridModelFromPivotResponse(
config: Partial<PivotConfig>,
response: PivotLoadResponse,
): PivotGridModel;

Materializes cell-level remote responses into row records keyed by row path. Pre-materialized row records are shallow-copied to attach semantic metadata.

export function materializePivotRows(
config: Partial<PivotConfig>,
response: PivotLoadResponse,
materializedColumnPaths?: PivotGroupValue[][],
);

Adds semantic group-path metadata to remote aggregate payloads without changing their legacy grouped-path keys.

export function materializePivotGroupAggregates(
config: Partial<PivotConfig>,
groupAggregates: Record<string, DataType> = {},
);

Builds a collision-safe semantic aggregate index for analytical consumers. The legacy keyed record above remains dedicated to RevoGrid’s grouping UI.

export function materializePivotSemanticGroupAggregates(
config: Partial<PivotConfig>,
groupAggregates: Record<string, DataType> = {},
);

Exports the currently visible Pivot grid model to CSV.

export function exportVisiblePivotToCsv(input: PivotCsvExportInput): string;

Flattens grouped Pivot headers into one leaf entry per visible value column.

export function flattenPivotCsvColumns(
columns: Array<ColumnGrouping | ColumnRegular>,
headerPathDelimiter = DEFAULT_HEADER_PATH_DELIMITER,
): PivotCsvLeafColumn[];

export function encodeDelimitedCell(
value: unknown,
options: PivotDelimitedFormatOptions,
force = false,
);

interface PivotCsvExportOptions {
/** Cell delimiter. Defaults to comma. */
columnDelimiter?: string;
/** Row delimiter. Defaults to CRLF. */
rowDelimiter?: string;
/** Prefix the CSV with a UTF-8 BOM. Defaults to false. */
bom?: boolean;
/** Separator used when flattening grouped headers. Defaults to ` / `. */
headerPathDelimiter?: string
}

PivotCsvExportInput (Extended from index.ts)

Section titled “PivotCsvExportInput (Extended from index.ts)”
interface PivotCsvExportInput {
/** Current visible Pivot columns. Grouped columns are flattened to leaves. */
columns: Array<ColumnGrouping | ColumnRegular>;
/** Current visible body rows. */
source?: DataType[];
/** Current visible pinned bottom rows, appended after body rows. */
pinnedBottomSource?: DataType[]
}

interface PivotDelimitedFormatOptions {
columnDelimiter: string;
rowDelimiter: string
}

Builds clipboard-ready TSV for the visible Pivot model.

export function buildPivotCopyTsv(input: PivotTsvCopyInput): string;

export function flattenPivotCopyColumns(
columns: Array<ColumnGrouping | ColumnRegular>,
): PivotCopyLeafColumn[];

interface PivotTsvCopyInput {
/** Current visible Pivot columns. Grouped columns are treated as header levels. */
columns: Array<ColumnGrouping | ColumnRegular>;
/** Current visible body rows. */
source?: DataType[];
/** Current visible pinned bottom rows, appended after body rows. */
pinnedBottomSource?: DataType[];
/** Optional leaf props to include, in the requested order. */
selectedProps?: ColumnProp[];
/** Optional absolute row indexes from source + pinnedBottomSource to include. */
selectedRowIndexes?: number[];
/** Optional rows to include instead of source + pinnedBottomSource. */
selectedRows?: DataType[];
/** Cell delimiter. Defaults to tab. */
columnDelimiter?: string;
/** Row delimiter. Defaults to LF, matching clipboard text conventions. */
rowDelimiter?: string;
/** Optional display transformation applied before TSV escaping. */
formatValue?: (
value: unknown,
column: PivotCopyLeafColumn,
row: DataType,
) => unknown
}

interface PivotCopyLeafColumn {
prop: ColumnProp;
headers: string[];
rowAxis: boolean
}

Converts RevoGrid and/or Pivot expression filters into render-ready chip models.

export function createPivotFilterChips(
input: PivotFilterChipInput,
options: PivotFilterChipOptions = {},
): PivotFilterChip[];

Converts a RevoGrid filter collection into render-ready chip models.

export function createPivotFilterChipsFromCollection(
collection?: Record<ColumnProp, FilterCollectionItem>,
options: PivotFilterChipOptions = {},
): PivotFilterChip[];

Converts a Pivot remote filter expression into render-ready chip models.

export function createPivotFilterChipsFromExpression(
expression?: PivotFilterExpression,
options: PivotFilterChipOptions = {},
): PivotFilterChip[];

Builds an intent payload for clearing a single visible filter chip.

export function createPivotFilterClearOneIntent(chip: PivotFilterChip): PivotFilterClearOneIntent;

Builds an intent payload for clearing every visible filter chip.

export function createPivotFilterClearAllIntent(chips: readonly PivotFilterChip[] = []): PivotFilterClearAllIntent;

Applies clear intents to a RevoGrid filter collection without mutating caller state.

export function applyPivotFilterClearIntentToCollection(
collection: Record<ColumnProp, FilterCollectionItem> | undefined,
intent: PivotFilterClearIntent,
): Record<ColumnProp, FilterCollectionItem> | undefined;

export type PivotFilterChipSource = 'revo-grid' | 'pivot-expression';

interface PivotFilterChipLabelResolver {
/** Optional field-label lookup used instead of raw field selectors. */
fieldLabel?: (selector: string) => string | undefined;
/** Optional operation-label lookup used instead of built-in operation labels. */
operationLabel?: (operation: string) => string | undefined;
/** Optional value formatter used instead of built-in value labels. */
valueLabel?: (value: unknown, selector: string, operation: string) => string | undefined
}

interface PivotFilterChip {
/** Stable id for rendering and clear-one actions. */
id: string;
/** Original field selector. */
selector: string;
/** Human-readable field label. */
fieldLabel: string;
/** Filter operation id from RevoGrid or Pivot remote filters. */
operation: string;
/** Human-readable operation label. */
operationLabel: string;
/** Raw filter value, kept for caller-owned editor or telemetry needs. */
value: unknown;
/** Human-readable value label. */
valueLabel: string;
/** Complete visible chip label. */
label: string;
/** Source filter model used to build the chip. */
source: PivotFilterChipSource;
/** Path of the condition inside a Pivot filter expression tree. */
expressionPath?: readonly number[]
}

PivotFilterChipOptions (Extended from index.ts)

Section titled “PivotFilterChipOptions (Extended from index.ts)”
interface PivotFilterChipOptions {
/** Prefix included in generated chip ids when multiple Pivot views share UI. */
idPrefix?: string
}

interface PivotFilterChipInput {
/** RevoGrid filter collection from `beforefilterapply`. */
collection?: Record<ColumnProp, FilterCollectionItem>;
/** Remote Pivot filter expression tree. */
expression?: PivotFilterExpression
}

interface PivotFilterClearOneIntent {
type: 'clear-one';
chipId: string;
selector: string;
source: PivotFilterChipSource;
expressionPath?: readonly number[]
}

interface PivotFilterClearAllIntent {
type: 'clear-all';
selectors: string[];
sources: PivotFilterChipSource[]
}

export type PivotFilterClearIntent = PivotFilterClearOneIntent | PivotFilterClearAllIntent;

export function getInclusivePivotFilterValues(
selection: PivotFilterSelection | undefined,
): PivotFilterScalar[];

export function isPivotFilterExclusionSelection(
selection: PivotFilterSelection | undefined,
): selection is Exclude<PivotFilterSelection, unknown[]>;

export function hasActivePivotFilterSelection(
selection: PivotFilterSelection | undefined,
): boolean;

export function clonePivotFilterSelectionMap(
selections: PivotFilterSelectionMap,
): PivotFilterSelectionMap;

Fields whose member predicates participate in the current Pivot layout.

export function getPivotMemberFilterProps(
config: PivotMemberFilterConfig,
): ColumnProp[];

Drops hidden predicates after a field leaves every filterable layout role.

export function prunePivotFilterSelections(
config: PivotMemberFilterConfig,
): PivotFilterSelectionMap;

Filters raw client-side rows before Pivot grouping and aggregation. Inclusive arrays use OR within a field; exclusion selections invert that field predicate. Independent fields retain AND semantics.

export function filterPivotSource<T extends DataType>(
source: T[],
config: PivotMemberFilterConfig,
): T[];

export type PivotMemberFilterConfig = Pick<
Partial<PivotConfig>,
'rows' | 'columns' | 'filters' | 'filterSelections'
>;

Converts remote Pivot response metadata into render-ready diagnostics rows and chips.

export function createPivotDiagnosticsModel(
response: PivotDiagnosticsResponseInput,
options: PivotDiagnosticsFormatterOptions = {},
): PivotDiagnosticsModel;

export type PivotDiagnosticTone = 'neutral' | 'success' | 'warning';

interface PivotDiagnosticRow {
/** Stable id for row rendering and tests. */
id: 'elapsed' | 'generatedAt' | 'visibleRows' | 'visibleColumns';
/** Human-readable row label. */
label: string;
/** Human-readable row value. */
value: string;
/** Raw value kept for sorting, telemetry, or custom formatting. */
rawValue?: string | number
}

interface PivotDiagnosticChip {
/** Stable id for chip rendering and tests. */
id: string;
/** Human-readable chip label. */
label: string;
/** Chip visual tone hint. */
tone: PivotDiagnosticTone;
/** Raw value kept for telemetry or custom rendering. */
rawValue?: string
}

interface PivotDiagnosticsModel {
rows: PivotDiagnosticRow[];
chips: PivotDiagnosticChip[];
warnings: string[];
hasWarnings: boolean
}

interface PivotDiagnosticsFormatterLabels {
elapsed: string;
cache: string;
generatedAt: string;
visibleRows: string;
visibleColumns: string;
warning: string
}

interface PivotDiagnosticsFormatterOptions {
labels?: Partial<PivotDiagnosticsFormatterLabels>;
formatGeneratedAt?: (generatedAt: string) => string
}

Creates a reusable formatter for Pivot aggregate and axis values.

export function createPivotValueFormatter(config: PivotValueFormatConfig): PivotValueFormatter;

Formats one Pivot value without keeping formatter state between calls.

export function formatPivotValue(value: unknown, config: PivotValueFormatConfig): string;

export type PivotValueFormatPreset = 'number' | 'currency' | 'percent' | 'date' | 'datetime';

interface PivotValueFormatBase {
/** Locale forwarded to the matching Intl formatter. */
locale?: Intl.LocalesArgument;
/** Display value for null or undefined input. Defaults to an empty string. */
nullDisplay?: string;
/** Display value for values that cannot be formatted by the selected preset. Defaults to an empty string. */
invalidDisplay?: string
}

PivotNumberFormatConfig (Extended from index.ts)

Section titled “PivotNumberFormatConfig (Extended from index.ts)”
interface PivotNumberFormatConfig {
preset: 'number';
options?: Intl.NumberFormatOptions
}

PivotCurrencyFormatConfig (Extended from index.ts)

Section titled “PivotCurrencyFormatConfig (Extended from index.ts)”
interface PivotCurrencyFormatConfig {
preset: 'currency';
currency: string;
options?: Omit<Intl.NumberFormatOptions, 'style' | 'currency'>
}

PivotPercentFormatConfig (Extended from index.ts)

Section titled “PivotPercentFormatConfig (Extended from index.ts)”
interface PivotPercentFormatConfig {
preset: 'percent';
options?: Omit<Intl.NumberFormatOptions, 'style'>
}

PivotDateFormatConfig (Extended from index.ts)

Section titled “PivotDateFormatConfig (Extended from index.ts)”
interface PivotDateFormatConfig {
preset: 'date';
options?: Intl.DateTimeFormatOptions
}

PivotDateTimeFormatConfig (Extended from index.ts)

Section titled “PivotDateTimeFormatConfig (Extended from index.ts)”
interface PivotDateTimeFormatConfig {
preset: 'datetime';
options?: Intl.DateTimeFormatOptions
}

export type PivotValueFormatConfig =
| PivotNumberFormatConfig
| PivotCurrencyFormatConfig
| PivotPercentFormatConfig
| PivotDateFormatConfig
| PivotDateTimeFormatConfig;

export type PivotValueFormatter = (value: unknown) => string;

export function serializePivotStateJson(
config: Partial<PivotConfig>,
options: PivotStateJsonOptions = {},
): string;

Removes runtime-only values before persisting Pivot state.

export function createSerializablePivotConfig(
config: Partial<PivotConfig>,
): Partial<PivotConfig>;

export function createPivotStateJsonEnvelope(
config: Partial<PivotConfig>,
options: PivotStateJsonOptions = {},
): PivotStateJsonEnvelope;

export function parsePivotStateJson(json: string): Partial<PivotConfig>;

export function parsePivotStateJsonEnvelope(json: string): PivotStateJsonEnvelope;

export function stableJsonStringify(value: unknown): string;

PIVOT_STATE_JSON_KIND: string;

PIVOT_STATE_JSON_VERSION: 1;

interface PivotStateJsonEnvelope {
kind: typeof PIVOT_STATE_JSON_KIND;
version: typeof PIVOT_STATE_JSON_VERSION;
config: Partial<PivotConfig>;
exportedAt?: string
}

interface PivotStateJsonOptions {
/**
* Timestamp to include in the exported state. Omit it for deterministic JSON
* without a time field.
*/
exportedAt?: string | Date;
/**
* Adds an export timestamp generated by this callback when `exportedAt` is
* not provided. This keeps tests deterministic without mocking Date.
*/
now?: () => string | Date
}

export function createPivotConditionalCellProperties(
rules: PivotConditionalFormatRule[],
options: PivotConditionalCellPropertiesOptions = {},
): PropertiesFunc;

export function getPivotConditionalCellProperties(
params: CellTemplateProp,
rules: PivotConditionalFormatRule[],
options: PivotConditionalCellPropertiesOptions = {},
): CellProps | undefined;

export function evaluatePivotConditionalFormatRule(
value: unknown,
rule: PivotConditionalFormatRule,
): boolean;

export function isPivotAnalyticalCell(params: Pick<CellTemplateProp, 'column'>): boolean;

export type PivotConditionalFormatOperator =
| 'gt'
| 'lt'
| 'between'
| 'equal'
| 'contains';

interface PivotConditionalFormatRule {
/** Comparison operation used against the rendered analytical cell value. */
operator: PivotConditionalFormatOperator;
/** Comparison value for `gt`, `lt`, `equal`, and `contains`; tuple bounds for `between`. */
value?: unknown;
/** Inclusive lower bound for `between` when `value` is not a tuple. */
min?: unknown;
/** Inclusive upper bound for `between` when `value` is not a tuple. */
max?: unknown;
/** Optional generated value field selector. Omit to target every analytical cell. */
field?: ColumnProp | ColumnProp[];
/** Optional class value merged into the returned RevoGrid cell props. */
class?: CellClassValue;
/** Optional style value merged into the returned RevoGrid cell props. */
style?: CellStyleValue;
/** Additional RevoGrid cell props to return when the rule matches. */
props?: CellProps;
/** Makes `equal` and `contains` string comparisons case-sensitive. */
caseSensitive?: boolean
}

interface PivotConditionalCellPropertiesOptions {
/**
* Return only the first matching rule or merge all matching rules.
* Defaults to `first` for predictable conditional-formatting priority.
*/
match?: 'first' | 'all';
/** Allows applying rules to non-generated row fields. Defaults to false. */
includeNonAnalytical?: boolean
}

pivotConditionalFormattingPresets: {
gt: (value: unknown, props?: PivotConditionalFormatPresetProps) => PivotConditionalFormatRule;
lt: (value: unknown, props?: PivotConditionalFormatPresetProps) => PivotConditionalFormatRule;
between: (min: unknown, max: unknown, props?: PivotConditionalFormatPresetProps) => PivotConditionalFormatRule;
equal: (value: unknown, props?: PivotConditionalFormatPresetProps) => PivotConditionalFormatRule;
textContains: (value: unknown, props?: PivotConditionalFormatPresetProps) => PivotConditionalFormatRule;
};

Builds the runtime lookup from hierarchy membership discovered during the original Pivot aggregation pass. Only hierarchy is committed publicly; the Maps remain bound to the successful runtime revision.

export function createPivotSemanticSliceIndex({
axis,
fields,
fieldLabels,
nodes,
rows,
}: CreatePivotSemanticSliceIndexOptions): PivotSemanticSliceIndex;

Resolves one immediate-child row slice without scanning or repivoting data.

export function queryPivotSemanticSlice(
index: PivotSemanticSliceIndex,
request: PivotSemanticSliceRequest,
): PivotSemanticSlice;

export type PivotHierarchyAxis = 'row' | 'column';

interface PivotHierarchyLevel {
readonly id: string;
readonly axis: PivotHierarchyAxis;
readonly index: number;
readonly prop: ColumnProp;
readonly label: string
}

interface PivotHierarchyMember {
readonly id: string;
readonly axis: PivotHierarchyAxis;
readonly hierarchyId: string;
readonly levelId: string;
readonly levelIndex: number;
readonly path: readonly PivotAxisValue[];
readonly labels: readonly string[];
readonly parentId?: string;
readonly hasChildren: boolean;
readonly childCount: number
}

interface PivotHierarchyDescriptor {
readonly id: string;
readonly axis: PivotHierarchyAxis;
readonly levels: readonly PivotHierarchyLevel[];
readonly members: readonly PivotHierarchyMember[]
}

interface PivotRuntimeHierarchies {
readonly row?: PivotHierarchyDescriptor;
readonly column?: PivotHierarchyDescriptor
}

interface PivotSemanticSliceRequest {
readonly revision: number;
/** Parent row path. The result contains its immediate children. */
readonly rowPath: readonly PivotAxisValue[]
}

interface PivotSemanticSliceMember {
readonly member: PivotHierarchyMember;
/** Values-on-rows layouts return one aggregate row per measure. */
readonly rows: readonly DataType[]
}

interface PivotSemanticSlice {
readonly revision: number;
readonly rowPath: readonly PivotAxisValue[];
readonly members: readonly PivotSemanticSliceMember[]
}

interface PivotSemanticHierarchyNodeInput {
readonly path: readonly (PivotAxisValue | undefined)[];
readonly labels: readonly string[];
readonly childCount: number
}

interface PivotSemanticSliceIndex {
readonly hierarchy: PivotHierarchyDescriptor;
readonly membersByPathId: ReadonlyMap<string, PivotHierarchyMember>;
readonly childrenByParentPathId: ReadonlyMap<string, readonly PivotHierarchyMember[]>;
readonly rowsByPathId: ReadonlyMap<string, readonly DataType[]>
}

interface CreatePivotSemanticSliceIndexOptions {
readonly axis: PivotHierarchyAxis;
readonly fields: readonly ColumnProp[];
readonly fieldLabels: readonly string[];
readonly nodes: readonly PivotSemanticHierarchyNodeInput[];
readonly rows: readonly DataType[]
}

Applies configured show-values calculations to a fully aggregated client cube. Callers may project hidden totals after this pass.

export function applyPivotValueCalculations(input: {
rows: DataType[];
config: Partial<PivotConfig>;
columnAxis: PivotColumnAxis;
}): DataType[];

export function getPivotRawValue(
row: DataType | undefined,
prop: ColumnProp,
): unknown;

export type PivotValueCalculationType =
| 'percentOfGrandTotal'
| 'percentOfRowTotal'
| 'percentOfColumnTotal'
| 'percentOfParentRowTotal'
| 'percentOfParentColumnTotal'
| 'index'
| 'differenceFrom'
| 'percentDifferenceFrom'
| 'runningTotal'
| 'percentRunningTotal'
| 'rank';

export type PivotValueCalculation =
| {
type:
| 'percentOfGrandTotal'
| 'percentOfRowTotal'
| 'percentOfColumnTotal'
| 'percentOfParentRowTotal'
| 'percentOfParentColumnTotal'
| 'index';
}
| {
type: 'differenceFrom' | 'percentDifferenceFrom';
axis: 'rows' | 'columns';
field: ColumnProp;
base: 'previous' | 'next' | PivotFilterScalar;
}
| {
type: 'runningTotal' | 'percentRunningTotal';
axis: 'rows' | 'columns';
field: ColumnProp;
}
| {
type: 'rank';
axis: 'rows' | 'columns';
field: ColumnProp;
order?: 'asc' | 'desc';
};

Raw aggregate values retained when calculated display values replace them.

PIVOT_RAW_VALUES: typeof PIVOT_RAW_VALUES;

PivotRowWithRawValues (Extended from index.ts)

Section titled “PivotRowWithRawValues (Extended from index.ts)”
export type PivotRowWithRawValues = DataType & {
[PIVOT_RAW_VALUES]?: Readonly<Record<string, unknown>>;
};

  • Auto-installed ContextMenuPlugin: Contributes semantic Pivot commands to the shared Pro context menu.
  • Auto-installed DialogPlugin, ConditionalFormattingDialogPlugin, ValueSelectionDialogPlugin: Uses shared Pro dialog plugins for Pivot context-menu workflows.
class PivotContextMenuPlugin {
handleHeaderClick(
event: CustomEvent<ColumnRegular & { originalEvent?: MouseEvent }>,
): boolean;
attach(host: PivotContextMenuHost): void;
detach(host?: PivotContextMenuHost): void;
}

interface PivotContextMenuActionHost {
updatePivotConfig(config: Partial<PivotConfig>): Promise<boolean>;
setPivotSorting(
prop: ColumnProp,
order?: 'asc' | 'desc',
measure?: PivotMeasureMeta,
): Promise<void>
}

class PivotContextMenuActions {
moveField(
context: PivotContextMenuContext,
target: Exclude<PivotContextMenuFieldRole, 'filters'> | 'filters',
);
removeField(context: PivotContextMenuContext);
setAggregation(context: PivotContextMenuContext, aggregator: string);
setCalculation(
context: PivotContextMenuContext,
calculation?: PivotValueCalculation,
);
setFormat(
context: PivotContextMenuContext,
format?: PivotValueFormatConfig,
);
setValuesOnRows(context: PivotContextMenuContext, valuesOnRows: boolean);
keepOnly(context: PivotContextMenuContext);
clearFilter(context: PivotContextMenuContext);
setFilterSelection(
context: PivotContextMenuContext,
selection: PivotFilterSelection,
);
setResultFilters(
context: PivotContextMenuContext,
resultFilters?: PivotAggregateFilterExpression,
);
setConditionalFormatting(
context: PivotContextMenuContext,
rules: PivotConditionalFormatRule[],
match: 'first' | 'all' = 'first',
);
toggleGrandTotal(context: PivotContextMenuContext);
toggleSubtotals(context: PivotContextMenuContext);
setColumnCollapsed(
context: PivotContextMenuContext,
collapsed: boolean,
all = false,
);
setRowsExpanded(
context: PivotContextMenuContext,
expanded: boolean,
all = false,
);
sort(context: PivotContextMenuContext, order?: 'asc' | 'desc');
}

export function resolvePivotContextMenuContext(
menu: ContextMenuOpenContext,
snapshot: PivotRuntimeSnapshot,
): PivotContextMenuContext | undefined;

PivotContextMenuHost (Extended from index.ts)

Section titled “PivotContextMenuHost (Extended from index.ts)”
interface PivotContextMenuHost {
getRuntimeSnapshot(): PivotRuntimeSnapshot | null;
getPivotOriginalSource(): readonly DataType[];
getPivotEngineCapabilities(): PivotEngineCapabilities;
loadPivotFilterValues(input: {
field: ColumnProp;
search?: string;
offset: number;
limit: number;
signal?: AbortSignal;
}): Promise<PivotFilterValuesResponse>;
loadPivotDrilldown(input: {
cell: PivotDrilldownCellRef;
customColumns?: string[];
offset: number;
limit: number;
signal?: AbortSignal;
}): Promise<PivotDrilldownResponse>
}

export function createPivotContextMenuLocaleText(
overrides?: Partial<PivotContextMenuLocaleText>,
): PivotContextMenuLocaleText;

export function formatPivotContextMenuText(
template: string,
values: Record<string, string | number>,
): string;

export function resolvePivotCopyShortcut(
translatedShortcut?: string,
platform = globalThis.navigator?.platform ?? '',
): string;

PIVOT_CONTEXT_MENU_EN: {
contextMenuAriaLabel: string;
moveField: string;
valuesAxis: string;
rows: string;
columns: string;
sort: string;
sortAscending: string;
sortDescending: string;
clearSort: string;
filter: string;
keepOnly: string;
clearFilter: string;
moveToRows: string;
moveToColumns: string;
moveToValues: string;
moveToFilters: string;
removeField: string;
removeUnavailable: string;
expand: string;
collapse: string;
expandAll: string;
collapseAll: string;
totals: string;
grandTotal: string;
subtotals: string;
aggregation: string;
aggregatorLabels: { sum: string; count: string; avg: string; min: string; max: string; median: string; mode: string; range: string; variance: string; stdDev: string; first: string; last: string; distinct: string; };
showValuesAs: string;
noCalculation: string;
percentOfGrandTotal: string;
percentOfRowTotal: string;
percentOfColumnTotal: string;
percentOfParentRowTotal: string;
percentOfParentColumnTotal: string;
index: string;
runningTotal: string;
rank: string;
rankDescending: string;
differenceFromPrevious: string;
rowCalculationGroup: string;
columnCalculationGroup: string;
numberFormat: string;
number: string;
currency: string;
percent: string;
clearFormat: string;
conditionalFormatting: string;
conditionalFormattingDescription: string;
rule: string;
appearance: string;
preview: string;
sampleValue: string;
drillThrough: string;
drillThroughUnavailable: string;
copy: string;
copyWithHeaders: string;
copyWithPivotHeaders: string;
export: string;
exportVisibleCsv: string;
exportStateJson: string;
valuesOnRows: string;
valuesOnColumns: string;
copyShortcut: string;
clipboardError: string;
filterValuesUnavailable: string;
filterUnavailable: string;
sortUnavailable: string;
aggregationUnavailable: string;
calculationUnavailable: string;
filterDescription: string;
resultFilter: string;
resultFilterDescription: string;
resultFilterAddCondition: string;
resultFilterAnd: string;
resultFilterOr: string;
resultFilterValueRequired: string;
searchValues: string;
selectAllVisible: string;
filterValuesLabel: string;
selectedValues: string;
noValues: string;
blankValue: string;
showingValues: string;
valueCount: string;
clear: string;
cancel: string;
apply: string;
loadingValues: string;
loadValuesError: string;
greaterThan: string;
lessThan: string;
greaterThanOrEqual: string;
lessThanOrEqual: string;
notEqualTo: string;
between: string;
equalTo: string;
contains: string;
condition: string;
value: string;
secondValue: string;
background: string;
text: string;
valuePlaceholder: string;
maximumPlaceholder: string;
clearRules: string;
loadingRows: string;
loadRowsError: string;
close: string;
closeDialog: string;
rowCount: string;
};

interface PivotContextMenuConfig {
areas?: Partial<Record<PivotContextMenuSurface, boolean>>;
items?: Partial<Record<PivotContextMenuItemId, boolean>>;
allowFieldRemoving?: boolean;
drillThrough?: false | {
pageSize?: number;
columns?: ColumnProp[];
};
filter?: false | {
pageSize?: number;
};
clipboard?: false | {
formatted?: boolean;
};
export?: false | {
fileName?: string;
};
localeText?: Partial<PivotContextMenuLocaleText>
}

export type PivotContextMenuItemId =
| 'sort'
| 'filter'
| 'move'
| 'remove'
| 'expand'
| 'collapse'
| 'totals'
| 'aggregation'
| 'calculation'
| 'numberFormat'
| 'conditionalFormatting'
| 'drillThrough'
| 'copy'
| 'export';

interface PivotContextMenuLocaleText {
contextMenuAriaLabel: string;
moveField: string;
valuesAxis: string;
rows: string;
columns: string;
sort: string;
sortAscending: string;
sortDescending: string;
clearSort: string;
filter: string;
keepOnly: string;
clearFilter: string;
moveToRows: string;
moveToColumns: string;
moveToValues: string;
moveToFilters: string;
removeField: string;
removeUnavailable: string;
expand: string;
collapse: string;
expandAll: string;
collapseAll: string;
totals: string;
grandTotal: string;
subtotals: string;
aggregation: string;
aggregatorLabels: Record<string, string>;
showValuesAs: string;
noCalculation: string;
percentOfGrandTotal: string;
percentOfRowTotal: string;
percentOfColumnTotal: string;
percentOfParentRowTotal: string;
percentOfParentColumnTotal: string;
index: string;
runningTotal: string;
rank: string;
rankDescending: string;
differenceFromPrevious: string;
rowCalculationGroup: string;
columnCalculationGroup: string;
numberFormat: string;
number: string;
currency: string;
percent: string;
clearFormat: string;
conditionalFormatting: string;
conditionalFormattingDescription: string;
rule: string;
appearance: string;
preview: string;
sampleValue: string;
drillThrough: string;
drillThroughUnavailable: string;
copy: string;
copyWithHeaders: string;
copyWithPivotHeaders: string;
export: string;
exportVisibleCsv: string;
exportStateJson: string;
valuesOnRows: string;
valuesOnColumns: string;
copyShortcut: string;
clipboardError: string;
filterValuesUnavailable: string;
filterUnavailable: string;
sortUnavailable: string;
aggregationUnavailable: string;
calculationUnavailable: string;
filterDescription: string;
resultFilter: string;
resultFilterDescription: string;
resultFilterAddCondition: string;
resultFilterAnd: string;
resultFilterOr: string;
resultFilterValueRequired: string;
searchValues: string;
selectAllVisible: string;
filterValuesLabel: string;
selectedValues: string;
noValues: string;
blankValue: string;
showingValues: string;
valueCount: string;
clear: string;
cancel: string;
apply: string;
loadingValues: string;
loadValuesError: string;
greaterThan: string;
lessThan: string;
greaterThanOrEqual: string;
lessThanOrEqual: string;
notEqualTo: string;
between: string;
equalTo: string;
contains: string;
condition: string;
value: string;
secondValue: string;
background: string;
text: string;
valuePlaceholder: string;
maximumPlaceholder: string;
clearRules: string;
loadingRows: string;
loadRowsError: string;
close: string;
closeDialog: string;
rowCount: string
}

export type PivotContextMenuSurface =
| 'rowFieldHeader'
| 'compactRowFieldHeader'
| 'columnMemberHeader'
| 'measureHeader'
| 'rowMemberCell'
| 'rowGroupCell'
| 'valueCell'
| 'subtotalCell'
| 'grandTotalCell'
| 'collapsedColumn';

export type PivotContextMenuFieldRole =
| 'rows'
| 'columns'
| 'values'
| 'filters';

interface PivotContextMenuContext {
readonly surface: PivotContextMenuSurface;
readonly menu: ContextMenuOpenContext;
readonly snapshot: PivotRuntimeSnapshot;
readonly field?: ColumnProp;
readonly fields?: readonly ColumnProp[];
readonly fieldRole?: PivotContextMenuFieldRole;
readonly valueIndex?: number;
readonly measure?: PivotMeasureMeta;
readonly row?: DataType;
readonly rowMeta?: PivotRowMeta;
readonly columnMeta?: PivotColumnMeta;
/** Semantic row property used when the clicked surface has no sortable column. */
readonly sortProp?: ColumnProp;
/** Generated value column used to sort aggregated Pivot rows. */
readonly sortColumnMeta?: PivotColumnMeta;
readonly groupKey?: string;
readonly member?: string | number | boolean | null
}

interface PivotContextMenuCommandDetail {
readonly id: PivotContextMenuItemId | string;
readonly context: PivotContextMenuContext
}

PIVOT_CONTEXT_MENU_COMMAND_EVENT: string;

Wires grid/plugin events to Pivot orchestration without owning UI rendering, request mapping, or grid mutations.

@param host - Controller facade used to react to RevoGrid events while keeping UI lifecycle, grid mutation, and remote request state isolated.

export function bindPivotPluginEvents(host: PivotEventBindingHost);

Builds lightweight column-path metadata without generating hidden columns.

export function createPivotColumnAxis(
config: Partial<PivotConfig>,
source: DataType[],
): PivotColumnAxis;

interface PivotColumnAxisNode {
readonly path: readonly PivotGroupValue[];
readonly depth: number;
readonly key: string;
readonly children: ReadonlyMap<string, PivotColumnAxisNode>;
readonly sourceCount: number
}

interface PivotVisibleColumnBucket {
readonly kind: 'leaf' | 'collapsed';
readonly path: readonly PivotGroupValue[];
readonly key: string;
/**
* Subtotals are visible only for expanded ancestors shallower than this
* depth. A leaf frontier uses the full analytical path depth.
*/
readonly depth: number
}

interface PivotColumnAxis {
readonly root: PivotColumnAxisNode;
readonly keyResolver: PivotColumnPathKeyResolver;
getNode(path: readonly PivotGroupValue[]): PivotColumnAxisNode | undefined;
isEffectivelyCollapsed(path: readonly PivotGroupValue[]): boolean;
getHiddenLeafCount(path: readonly PivotGroupValue[]): number;
resolveVisibleBucket(path: readonly PivotGroupValue[]): PivotVisibleColumnBucket
}

Applies one column-group transition to the analytical frontier sent to a Pivot server.

Expanded and collapsed paths are both explicit because either state can be the configured default. Collapsing a parent removes descendant exceptions, keeping request size proportional to the visible expansion frontier rather than the hidden hierarchy.

export function updatePivotColumnServerState({
axis,
path,
collapsed,
}: UpdatePivotColumnServerStateOptions): Partial<PivotAxisViewport>;

Synchronizes a column drill frontier, collapsing paths left behind by the previous frontier and expanding every prefix required by the next one.

export function synchronizePivotColumnServerState({
axis,
from,
to,
}: SynchronizePivotColumnServerStateOptions): Partial<PivotAxisViewport>;

Marks a generated Pivot column group as eligible for the compact, single-row collapsed-header projection owned by ColumnCollapsePlugin.

Pivot owns this policy because its visible-frontier column generator omits hidden descendants while a parent is collapsed. The Pro plugin owns only the reusable rendering mechanism: when every marked top-level group is collapsible and collapsed, it projects the group headers into their visible carrier leaves and sets the reactive grouping depth to zero.

Keeping the marker at group creation time avoids a second traversal of the Pivot hierarchy. The later compact-state check is bounded by the rendered top-level groups and never materializes or aggregates hidden descendants.

export function withPivotCompactCollapsedHeader<
T extends PivotColumnGroupShape,
>(
group: T,
config?: Partial<PivotConfig> | null,
): PivotCompactCollapsedHeaderGroup<T>;

Returns the effective leading row props, including values-on-rows metadata.

export function getPivotRowProps(config?: Partial<PivotConfig> | null): ColumnProp[];

Checks whether Pivot should enable grouped row expansion metadata.

export function isPivotRowDrillDownEnabled(config?: Partial<PivotConfig> | null);

Converts Pivot row configuration into RevoGrid grouping options.

export function getPivotGrouping(config?: Partial<PivotConfig> | null): GroupingOptions | undefined;

Returns whether generated Pivot column groups should be collapsible.

export function isPivotColumnCollapseEnabled(
config?: Partial<PivotConfig> | null,
level?: number,
);

Returns whether generated collapsed aggregates expose group-level filters.

export function isPivotColumnGroupFilteringEnabled(
config?: Partial<PivotConfig> | null,
level?: number,
);

Returns the default collapsed state for enabled generated Pivot column groups.

export function getPivotColumnCollapsedDefault(
config?: Partial<PivotConfig> | null,
level?: number,
);

Resolves whether a generated Pivot column group should currently be collapsed.

export function getPivotColumnCollapsed(
config: Partial<PivotConfig> | null | undefined,
key: string,
level?: number,
);

Marks synthetic Pivot rows so the plugin can distinguish managed source.

export function markPivotRowGenerated(row: DataType);

Checks whether a source row was generated by Pivot rather than provided by the caller.

export function isPivotGeneratedSourceRow(row?: DataType);

Checks whether a Pivot row is the synthetic grand total row.

export function isPivotGrandTotalRow(row?: DataType);

Checks whether a Pivot row is a generated subtotal row.

export function isPivotSubtotalRow(row?: DataType);

Checks whether a Pivot row is a generated subtotal or grand-total row.

export function isPivotTotalRow(row?: DataType);

Checks whether a Pivot leaf row belongs under a subtotal row.

export function isPivotLeafInSubtotal(row: DataType | undefined, subtotalRow: DataType | undefined);

Marks all generated Pivot columns recursively.

export function markPivotColumnsGenerated(
columns: Array<ColumnGrouping | ColumnRegular>,
): Array<ColumnGrouping | ColumnRegular>;

Checks whether an entire column tree was generated by Pivot.

export function arePivotGeneratedColumns(
columns: Array<ColumnGrouping | ColumnRegular> = [],
): boolean;

Adds column-collapse metadata to a generated Pivot group when it is useful.

export function createPivotColumnGroupMeta<T extends Record<string, any>>(
group: T,
key: ColumnProp,
config?: Partial<PivotConfig> | null,
collapsed = false,
options: {
force?: boolean;
collapsedBucketKey?: ColumnProp;
filterColumn?: ColumnRegular;
level?: number;
} = {},
);

Resolves the measure aggregator used for collapsed placeholder cells.

export function getPivotCollapsedAggregator(
config: Partial<PivotConfig> | null | undefined,
prop: ColumnProp,
fallback: string,
);

export function hasPivotMergeBoundary(
items: number[],
visibleIndex: number,
source: DataType[],
currentModel: DataType | undefined,
prop: ColumnProp,
);

PIVOT_GENERATED: string;

PIVOT_GROUP_KEY: string;

PIVOT_COLLAPSE_HIDDEN_COUNT: string;

PIVOT_GRAND_TOTAL_ROW_KEY: string;

PIVOT_VALUE_LABEL: string;

PIVOT_VALUE_PROP: string;

export function resolvePivotGroupLabels(
config?: Partial<PivotConfig> | null,
): ResolvedPivotGroupLabels;

export function getPivotGroupKey(value: PivotGroupValue);

export function getPivotGroupLabel(
value: PivotGroupValue,
labels: ResolvedPivotGroupLabels,
);

export function getPivotGroupDisplayValue(
value: PivotGroupValue,
labels: ResolvedPivotGroupLabels,
);

export function createColumnLabelProp(prop: ColumnProp);

export type PivotGroupValue = string | number | boolean | null | undefined;

DEFAULT_EMPTY_GROUP_LABEL: string;

DEFAULT_NULL_GROUP_LABEL: string;

interface ResolvedPivotGroupLabels {
empty: string;
null: string
}

export function resolvePivotRowLayout(
config?: Partial<PivotConfig> | null,
): PivotRowLayout;

export function getPivotValueLabel({ prop, aggregator, label, name }: PivotConfigValue);

Resolves the visible row-axis presentation without changing the analytical row fields used for aggregation, grouping, and remote requests.

export function resolvePivotRowAxisLayout(
config?: Partial<PivotConfig> | null,
): PivotRowAxisLayout;

Returns whether Pivot has enough row metadata to render a drill-down hierarchy.

export function isPivotRowHierarchyEnabled(
config?: Partial<PivotConfig> | null,
);

export function getPivotCompactRowAxisColumn(
config?: Partial<PivotConfig> | null,
);

Adds the generated compact row label while retaining every analytical row field on the row record.

export function materializePivotRowAxisLabels(
rows: DataType[],
config?: Partial<PivotConfig> | null,
): DataType[];

PIVOT_ROW_LABEL_PROP: string;

PIVOT_ROW_DEPTH_PADDING: 10;

Expand button width (25px), margin (2px), and label gap (4px).

PIVOT_ROW_GROUP_CONTROL_INDENT: 31;

PIVOT_ROW_AXIS_INSET: string;

interface PivotRowLayout {
/** Source row fields used to aggregate the analytical row path. */
rowFields: ColumnProp[];
/** Visible row props rendered in RevoGrid, including the value pseudo-field. */
props: ColumnProp[];
/** Whether value measures are materialized as synthetic row members. */
valuesOnRows: boolean;
/** True when the advanced rowTree API is controlling placement. */
explicitRowTree: boolean
}

Resolves totals config into a complete object with defaults applied.

export function resolvePivotTotals(
totals?: Partial<PivotConfig['totals']>,
): ResolvedPivotTotals;

export function isPivotSubtotalEnabled(
totals: ResolvedPivotTotals,
axis: keyof ResolvedPivotTotals['disabledSubtotals'],
field: ColumnProp | undefined,
level: number,
);

Returns the explicit configuration for a zero-based Pivot column level.

export function getPivotColumnLevelConfig(
config: Partial<PivotConfig> | null | undefined,
level: number | undefined,
): PivotColumnLevelConfig | undefined;

Resolves column subtotal visibility while preserving the global subtotal gate and legacy field/level disable rules.

export function isPivotColumnSubtotalEnabled(
config: Partial<PivotConfig> | null | undefined,
totals: ResolvedPivotTotals,
field: ColumnProp | undefined,
level: number,
);

export function getPivotColumnSubtotalLabel(
config: Partial<PivotConfig> | null | undefined,
totals: ResolvedPivotTotals,
level: number,
);

export function getPivotColumnSubtotalPosition(
config: Partial<PivotConfig> | null | undefined,
level: number,
): PivotColumnSubtotalPosition;

Keeps every non-colliding legacy column key unchanged while assigning a deterministic typed suffix when distinct analytical paths share that key.

export function createPivotColumnPathKeyResolver(
paths: ReadonlyArray<readonly PivotGroupValue[]>,
): PivotColumnPathKeyResolver;

Builds the synthetic column key for a leaf analytical path.

export function buildLeafColumnKey(
path: readonly PivotGroupValue[],
resolver?: PivotColumnPathKeyResolver,
);

Builds the subtotal key for an intermediate analytical path.

export function buildSubtotalColumnKey(
path: readonly PivotGroupValue[],
resolver?: PivotColumnPathKeyResolver,
);

Builds the collapsed placeholder key for an intermediate analytical path.

export function buildCollapsedColumnKey(
path: readonly PivotGroupValue[],
resolver?: PivotColumnPathKeyResolver,
);

PIVOT_GRAND_TOTAL: string;

PIVOT_SUBTOTAL: string;

PIVOT_COLLAPSE: string;

PIVOT_SEMANTIC_PATH: string;

DEFAULT_GRAND_TOTAL_LABEL: string;

DEFAULT_SUBTOTAL_LABEL: string;

interface ResolvedPivotTotals {
grandTotal: boolean;
subtotals: boolean;
disabledSubtotals: {
rows: ResolvedPivotSubtotalDisableRule;
columns: ResolvedPivotSubtotalDisableRule;
};
grandTotalLabel: string;
subtotalLabel: string;
suppressSingleChildSubtotals: boolean;
suppressGrandTotalWhenSingleLeaf: boolean
}

interface ResolvedPivotSubtotalDisableRule {
fields: Set<ColumnProp>;
levels: Set<number>
}

interface PivotColumnPathKeyResolver {
resolve(path: readonly PivotGroupValue[]): string
}

Pivot compatibility adapter around the shared Pro dialog runtime.

Pivot-specific dialogs keep their established classes while focus, backdrop, keyboard, and lifecycle behavior remain shared.

class PivotContextMenuDialog {
open(title: string, closeLabel: string);
close(): void;
createButton(
label: string,
action: () => void,
primary = false,
): HTMLButtonElement;
createElement<K extends keyof HTMLElementTagNameMap>(
tag: K,
): HTMLElementTagNameMap[K];
createTextNode(text: string): Text;
}

class PivotContextMenuDialogs {
setRevision(revision: number): void;
destroy(): void;
openFilter(
context: PivotContextMenuContext,
config: PivotContextMenuConfig,
locale: PivotContextMenuLocaleText,
): void;
openResultFilter(
context: PivotContextMenuContext,
locale: PivotContextMenuLocaleText,
): boolean;
openFilterFieldChooser(
context: PivotContextMenuContext,
fields: readonly ColumnProp[],
config: PivotContextMenuConfig,
locale: PivotContextMenuLocaleText,
): void;
openConditionalFormatting(
context: PivotContextMenuContext,
locale: PivotContextMenuLocaleText,
): void;
openError(
title: string,
message: string,
closeLabel: string,
closeDialogLabel: string,
): void;
openDrillThrough(
context: PivotContextMenuContext,
config: PivotContextMenuConfig,
locale: PivotContextMenuLocaleText,
): void;
close(): void;
closePivotDialog(): void;
}

export function getPivotRootMenuPresentation(
kind: PivotRootMenuKind,
): PivotRootMenuPresentation;

export function getPivotActionIcon(
id: PivotContextMenuItemId,
semanticKey: string,
): string | undefined;

export type PivotRootMenuKind =
| PivotContextMenuItemId
| 'field'
| 'hierarchy'
| 'valuesAxis';

export type PivotRootMenuGroup =
| 'query'
| 'analysis'
| 'structure'
| 'clipboard'
| 'destructive';

export function createPivotItemId(
...parts: Array<string | number>
): string;

PIVOT_CONTEXT_MENU_SEPARATOR: {
kind: string;
name: string;
};

class PivotContextMenuItemFactory {
root(item: ContextMenuItem, kind: PivotRootMenuKind): ContextMenuItem;
command(options: PivotCommandOptions): ContextMenuItem;
radio(options: PivotRadioCommandOptions): ContextMenuItem;
checkbox(options: PivotCheckboxCommandOptions): ContextMenuItem;
present(items: ContextMenuItem[]): ContextMenuItem[];
}

class PivotContextMenuItems {
build(
context: PivotContextMenuContext,
config: PivotContextMenuConfig,
locale: PivotContextMenuLocaleText,
): ContextMenuItem[];
}

export async function copyPivotSelection(
context: PivotContextMenuContext,
mode: PivotCopyMode,
formatted = false,
): Promise<void>;

export function resolveClientDrillThrough(
source: DataType[],
context: PivotContextMenuContext,
): DataType[];

export function uniquePivotFilterValues(
values: unknown[],
): Array<string | number | boolean | null>;

export function serializePivotScalar(value: unknown): string;

export function parsePivotDialogValue(value: string): string | number;

export function getPivotExportFileName(config: PivotContextMenuConfig): string;

export function createPivotFilterValuesCacheKey(
context: PivotContextMenuContext,
field: ColumnProp,
limit: number,
): string;

export function samePivotCalculation(
left: PivotValueCalculation | undefined,
right: PivotValueCalculation | undefined,
): boolean;

export type PivotCopyMode = 'values' | 'headers' | 'pivotHeaders';

Reusable condition-list editor used by Pivot result-filter dialogs.

export function createPivotResultFilterEditor({
document,
initialItems,
locale,
}: ResultFilterEditorOptions): PivotResultFilterEditor;

interface PivotResultFilterEditor {
element: HTMLElement;
read(): FilterData[]
}

Owns server/client-adapter Pivot loads: request state, cancellation, stale-response checks, and pagination synchronization.

  • Config integration additionalData.pagination: Reads and writes legacy pagination config to synchronize remote pivot paging.
  • Config integration direct-pagination-config: Reads and writes direct grid.pagination config to synchronize remote pivot paging.
  • Optional pagination-capable-plugin: Calls setPage on a pagination-capable plugin when present.
class PivotRemoteController {
setFilterCollection(collection?: Record<ColumnProp, FilterCollectionItem>);
setFilterItems(filterItems?: MultiFilterItem);
setResultFilters(filters?: PivotAggregateFilterExpression);
setSorting(sorting?: SortingOrder, summaryResultId?: string);
getDisplaySorting(localSorting?: SortingOrder, isRemote = false);
createLoadRequest(config: Partial<PivotConfig>): PivotLoadRequest;
getCapabilities(config: Partial<PivotConfig>): PivotEngineCapabilities;
async loadFilterValues(
config: Partial<PivotConfig>,
request: PivotFilterValuesRequest,
signal?: AbortSignal,
): Promise<PivotFilterValuesResponse>;
async loadDrilldown(
config: Partial<PivotConfig>,
request: PivotDrilldownRequest,
signal?: AbortSignal,
): Promise<PivotDrilldownResponse>;
async apply(config: Partial<PivotConfig>, rowOffset?: number);
resetPagination();
invalidateLoad(clearDiagnostics = true);
clearState();
getPageRowOffset(detail: PageChangeEvent, config: Partial<PivotConfig>);
createGridModel(
config: Partial<PivotConfig>,
response: PivotLoadResponse,
): PivotGridModel;
}

export function createPivotLoadRequest(overrides: Partial<PivotLoadRequest> = {}): PivotLoadRequest;

pivotFieldRegistry: PivotFieldRegistry;

Flattens semantic result-filter state for projection and editor adapters.

export function flattenPivotAggregateFilterExpression(
expression:
| PivotAggregateFilterExpression
| PivotAggregateFilterDescriptor[]
| undefined,
): FlattenedPivotAggregateFilter[];

Returns every analytical descriptor referenced by a result-filter tree.

export function getPivotAggregateFilterDescriptors(
expression:
| PivotAggregateFilterExpression
| PivotAggregateFilterDescriptor[]
| undefined,
): PivotAggregateFilterDescriptor[];

export function isSamePivotAggregateFilterTarget(
descriptor: PivotAggregateFilterDescriptor,
target: PivotAggregateFilterTarget,
): boolean;

export function pivotFilterOperationToCoreType(
operation: PivotFilterOperation,
negated = false,
): FilterData['type'];

Validates serializable semantic HAVING state at persistence boundaries.

export function assertPivotAggregateFilterExpression(
value: unknown,
path = 'resultFilters',
depth = 0,
): asserts value is PivotAggregateFilterExpression;

interface PivotAggregateFilterTarget {
columnPath: PivotAggregateFilterDescriptor['columnPath'];
columnKind: PivotAggregateColumnKind;
summary: PivotAggregateFilterDescriptor['summary']
}

interface FlattenedPivotAggregateFilter {
descriptor: PivotAggregateFilterDescriptor;
relation?: PivotLogicalOperator;
negated?: boolean
}

Separates ordinary field filters from generated Pivot aggregate filters.

The returned having descriptors remain valid independently of the generated carrier prop used by the current expanded/collapsed projection.

export function partitionPivotColumnFilters(
collection: Record<ColumnProp, FilterCollectionItem> | undefined,
columns: readonly (ColumnGrouping | ColumnRegular)[] = [],
): PartitionedPivotColumnFilters;

Partitions the complete Core multi-filter model without reducing a column to its first condition.

Conditions within one column retain their visible AND/OR connector chain. Independent columns are joined with AND, matching Core and SQL semantics.

export function partitionPivotColumnFilterItems(
filterItems: MultiFilterItem | undefined,
columns: readonly (ColumnGrouping | ColumnRegular)[] = [],
): PartitionedPivotColumnFilterItems;

Converts Core condition rows for one generated column into a HAVING tree.

export function createPivotAggregateFilterExpression(
prop: string,
items: FilterData[],
target: PivotAggregateFilterTarget,
): {
expression?: PivotAggregateFilterExpression;
unsupported: UnsupportedPivotColumnFilter[];
};

Rebuilds the transient Core filter adapter for the current Pivot columns.

export function createCoreFilterItemsFromResultFilters(
expression:
| PivotAggregateFilterExpression
| PivotAggregateFilterDescriptor[]
| undefined,
columns: readonly (ColumnGrouping | ColumnRegular)[],
): MultiFilterItem;

interface PartitionedPivotColumnFilters {
baseFilters?: Record<ColumnProp, FilterCollectionItem>;
having?: PivotAggregateFilterDescriptor[]
}

interface UnsupportedPivotColumnFilter {
prop: string;
type: string
}

interface PartitionedPivotColumnFilterItems {
/** Full Core filter rows for ordinary source fields. */
baseFilterItems?: MultiFilterItem;
/** Semantic HAVING expression for generated aggregate columns. */
having?: PivotAggregateFilterExpression;
/** Filters that cannot be represented by the analytical contract. */
unsupported: UnsupportedPivotColumnFilter[]
}

export function getPivotDimensionAggregators(
dimension?: PivotConfigDimension,
);

export function createPivotConfigValue(
prop: ColumnProp,
dimension?: PivotConfigDimension,
): PivotConfigValue;

Places one source field using Excel-compatible Pivot roles. Rows and Columns are exclusive axis placements. Filters and Values are independent roles, so a field can filter source data without disappearing from an axis or the summarized values.

export function movePivotField(
state: PivotFieldLayoutState,
_source: PanelType,
target: Exclude<PanelType, 'dimensions'>,
prop: ColumnProp,
options: {
index?: number;
createValue: (prop: ColumnProp) => PivotConfigValue;
},
): PivotFieldLayoutState;

interface PivotFieldLayoutState {
rows: ColumnProp[];
columns: ColumnProp[];
values: PivotConfigValue[];
filters: ColumnProp[]
}

interface PivotFilterCoordinatorSnapshot {
baseFilterItems?: MultiFilterItem;
resultFilters?: PivotAggregateFilterExpression;
unsupported: UnsupportedPivotColumnFilter[]
}

Single Pivot-facing owner for Core filter adapters and semantic result filters. Member selections stay in PivotConfig.filterSelections.

class PivotFilterCoordinator {
captureCoreFilters(
filterItems: MultiFilterItem | undefined,
columns: readonly (ColumnGrouping | ColumnRegular)[],
): PivotFilterCoordinatorSnapshot;
restoreResultFilters(resultFilters?: PivotAggregateFilterExpression): void;
replaceResultTarget(
prop: string,
target: PivotAggregateFilterTarget,
items: FilterData[],
): PivotFilterCoordinatorSnapshot;
clearResultTarget(
target: PivotAggregateFilterTarget,
): PivotFilterCoordinatorSnapshot;
getResultItems(target: PivotAggregateFilterTarget): FilterData[];
getSnapshot(): PivotFilterCoordinatorSnapshot;
}

Owns the RevoGrid-facing state transitions for Pivot mode.

This class deliberately avoids event wiring, remote request construction, and panel rendering so grid mutation stays isolated from orchestration code.

class PivotGridController {
setOriginalData(source: DataType[]);
setOriginalColumns(columns: (ColumnRegular | ColumnGrouping)[]);
isPivotManagedSource(source: DataType[] = []);
isPivotManagedColumns(columns: (ColumnRegular | ColumnGrouping)[] = []);
activate(config: Partial<PivotConfig>);
clearGroupAggregates();
setFilterCollection(
collection?: Record<ColumnProp, FilterCollectionItem>,
);
setResultFilters(filters: PivotConfig['resultFilters']);
setFilterItems(items?: MultiFilterItem);
applyClientPivot(config: Partial<PivotConfig>);
applyRemotePivotModel(
config: Partial<PivotConfig>,
gridModel: PivotGridModel,
groupAggregates: PivotGroupAggregates = {},
semanticGroupAggregates: PivotGroupAggregates = {},
);
clearPivot();
renderOriginalGrid(
columns: (ColumnRegular | ColumnGrouping)[] = [],
);
}

export function getPivotMeasureCarrier(
values: PivotConfig['values'],
valueIndex: number,
): ColumnProp;

export function getPivotMeasureResultId(
value: Pick<PivotConfigValue, 'id' | 'prop' | 'aggregator'>,
): string;

Builds a complete remote Pivot load request from config plus current UI state.

export function createPivotLoadRequestFromConfig({
config,
rowOffset = config.engine?.rowAxis?.offset ?? 0,
rowLimit = config.engine?.rowAxis?.limit ?? 100,
columnOffset = config.engine?.columnAxis?.offset ?? 0,
columnLimit = config.engine?.columnAxis?.limit ?? 24,
filters,
filterItems,
sorting,
summaryResultId,
having,
requestId = `pivot-${Date.now()}`,
}: PivotLoadRequestMapperOptions): PivotLoadRequest;

Converts the complete Core filter model to a server expression tree.

export function toPivotFilterExpressionFromItems(
filterItems?: MultiFilterItem,
): PivotFilterExpression | undefined;

Removes empty filter entries so server requests only include active predicates.

export function normalizePivotFilterCollection(collection?: Record<ColumnProp, FilterCollectionItem>);

Removes unset sort entries and returns undefined when no remote sorting remains.

export function normalizePivotSorting(sorting?: SortingOrder);

Converts public Pivot aggregator ids into the server-supported summary enum.

export function toPivotSummaryType(aggregator: string): PivotSummaryType;

Converts one RevoGrid filter item into transport-neutral predicates. Both base-field filters and generated aggregate filters use this mapping.

export function toPivotFilterPredicates(
filter: FilterCollectionItem,
): PivotFilterPredicate[];

interface PivotLoadRequestMapperOptions {
/** Pivot configuration from direct `grid.pivot` or the active plugin state. */
config: Partial<PivotConfig>;
/** Current row-axis offset, usually derived from pagination. */
rowOffset?: number;
/** Current row-axis window size, usually pagination `itemsPerPage`. */
rowLimit?: number;
/** Current column-axis offset for server-side column virtualization. */
columnOffset?: number;
/** Current column-axis window size for server-side column virtualization. */
columnLimit?: number;
/** Normalized RevoGrid filter collection to forward as a Pivot filter tree. */
filters?: Record<ColumnProp, FilterCollectionItem>;
/** Complete Core filter rows, including every condition and connector. */
filterItems?: MultiFilterItem;
/** Normalized RevoGrid sorting state to forward as Pivot sort descriptors. */
sorting?: SortingOrder;
/** Stable result id when the active value-field sort targets one summary. */
summaryResultId?: string;
/** Semantic post-aggregation filters for generated Pivot value columns. */
having?:
| PivotAggregateFilterExpression
| PivotAggregateFilterDescriptor[];
/** Optional stable request id for tests, tracing, or caller-managed correlation. */
requestId?: string
}

interface PivotFilterPredicate {
operation: PivotFilterOperation;
value: PivotFilterValue
}

export function createPivotGroupLabelTemplate(
groupAggregatesByPath: PivotGroupAggregates,
options: { subtotalLabel?: string; labelColumnMode?: PivotGroupLabelColumnMode } = {},
): GroupLabelTemplateFunc;

PV_PARENT_CL: string;

PV_PARENT_CFG_CL: string;

PV_PARENT_FIELD_PANEL_CL: string;

Owns the optional Pivot configurator and compact field-panel DOM lifecycle.

class PivotUiController {
attachRootClass();
detachRootClass();
setTheme(theme: GridTheme = 'default');
clear();
setDiagnostics(diagnostics?: PivotUiDiagnostics);
updateConfigurator(config?: Partial<PivotConfig>);
updateFieldPanel(
config?: Partial<PivotConfig>,
resizedColumns?: ColumnResizeDetail,
);
}