PivotDataViewModel

ViewModel for pivot grids with multi-level row and column facets and aggregated data cells.

PivotDataViewModel extends GridDataViewModel. It adds multi-level row facets for pivot grids where rows have hierarchical headers (e.g. region → country). Constructed from PivotDataViewModelParams.

What it adds

On top of the base class, PivotDataViewModel provides:

  • Row facets (rowFacets: FacetData) - multi-level row header values. Each level is an array of values across all rows.
  • numRowFacetLevels - the number of row facet levels. For hierarchy("region", "country") on the row axis, this returns 2.

Row facet merging

The layout merges row facet cells in two ways:

  • Vertical merge - when consecutive rows have the same value at a level (and all parent levels also match), those cells merge into one spanning cell. For example, "USA" appearing in 3 consecutive rows at level 0 renders as a single cell spanning 3 rows.
  • Horizontal merge - when a row has null at a deeper level, the parent level's cell spans across that level. For example, ["North America", null] means North America has no country-level value, so the region cell spans across the country column.

Consider a pivot with rows: hierarchy("continent", "country", "city") where only USA is expanded to the city level, Canada and the EU countries are not. The data has 3 facet levels:

// Viewmodel stores rowFacets as [level][rowIndex]:
viewModel.rowFacets;
// [
//   ["NA","NA","NA","NA",  "EU",    "EU",    "EU"],     // level 0: continent
//   ["USA","USA","USA","Canada","France","UK","Germany"],// level 1: country
//   ["SF","NY","Seattle",null,   null,   null, null],    // level 2: city
// ]

USA is expanded to show cities (SF, NY, Seattle). Canada, France, UK, and Germany have null at level 2 - they are not expanded to the city level. The layout renders this as:

NA
USA
SF
NY
Seattle
Canada
EU
France
UK
Germany
  • "NA" and "EU" repeat at level 0, so they merge vertically (spanning 4 and 3 rows)
  • "USA" repeats at level 1, so it merges vertically (spanning 3 rows)
  • Canada, France, UK, and Germany have null at level 2 (city), so they span horizontally across the city column

getSlice

getSlice returns a PivotSliceResult which extends BaseSliceResult with rowFacets: (string | null)[][].

The row facets are transposed from the viewmodel's storage: the viewmodel stores rowFacets[level][rowIndex], the slice returns rowFacets[rowIndex][level] (grouped per row).

const slice = viewModel.getSlice(0, 0, 4, 3);

slice.rowFacets;
// [
//   ["USA", "SF"],          // row 0: level 0 = USA, level 1 = SF
//   ["USA", "NY"],          // row 1: level 0 = USA, level 1 = NY
//   ["USA", "Seattle"],     // row 2: level 0 = USA, level 1 = Seattle
// ]

updateData

updateData(params: PivotDataViewModelParams): void

Swaps the internal data arrays and re-initializes options without constructing a new viewmodel instance. The renderer holds a reference to the viewmodel; updateData replaces data in place so the renderer picks up changes on its next render cycle without needing a new grid.data = ... assignment.

metaState is preserved across updateData calls - transient renderer state (scroll position, selections) survives data refreshes.

Typical wiring

PivotTableDataModel.getViewModelData() returns PivotDataViewModelParams. Pass it to the constructor on first load, then use updateData for subsequent refreshes:

import { PivotDataViewModel } from "grid";

// First load - construct the viewmodel
const params = await pivotDataModel.getViewModelData(pivotConfig);
const viewModel = new PivotDataViewModel(params);
grid.data = viewModel;

// On config change - update in place and reset on grid
const newParams = await pivotDataModel.getViewModelData(newConfig);
viewModel.updateData(newParams);
grid.data = viewModel;

API Reference.

Extends GridDataViewModel.

ViewModel for pivot grids. Adds multi-level row facets on top of GridDataViewModel. Consecutive rows with the same facet value at a level are merged vertically by the layout; null at a deeper level causes the parent level's cell to span horizontally.

Prop

Type

updateDatafunction

Swaps internal data arrays, row facets, and re-initializes rendering options without constructing a new instance. metaState is preserved.

Type

(params: PivotDataViewModelParams) => void

Parameters

numRowFacetLevelsnumber

Number of row facet levels. For hierarchy("region", "country") on the row axis, returns 2. Returns 0 when there are no row dimensions.

Type

number

rowFacetsFacetData

All row facet levels. rowFacets[level][rowIndex] is the facet value. Returns [] when there are no row dimensions.

Type

FacetData

getSlicefunction

Returns a PivotSliceResult for the given range. Extends the base slice with row facets transposed to rowFacets[rowIndex][level].

Type

(x0: number, y0: number, x1: number, y1: number) => PivotSliceResult

Parameters

x0 -

Start column index (inclusive).

y0 -

Start row index (inclusive).

x1 -

End column index (exclusive).

y1 -

End row index (exclusive).

Returns

Slice data with rowFacets grouped per row.

On this page