React Pivot Table Tutorial: Matrix Aggregation Without AG Grid Enterprise (2026)

React Pivot TableTutorialAnalytics

Build a React pivot table with row/column dimensions, aggregations, totals, and an in-table Pivot Panel—without AG Grid Enterprise. Code examples and pivot vs row grouping.

You have flat sales rows: region, product, quarter, revenue. Stakeholders want a matrix—regions down the left, quarters across the top, summed revenue in every cell. That reshape is a React pivot table: row dimensions, column dimensions, and aggregated measures in a data grid.

In many libraries, pivot mode is locked behind an Enterprise license. AG Grid's interactive Pivot Panel is powerful—and priced accordingly. Simple Table ships declarative matrix pivot plus an in-table Pivot Panel (enablePivotPanel) that drives the same config API.

This React pivot table tutorial covers how pivot tables work in a JavaScript data grid, when to choose pivot vs row grouping, and how to configure Simple Table for aggregations, nested dimensions, totals, and runtime updates.

What Is a React Pivot Table?

A pivot table in React turns fact rows into a cross-tab matrix:

  • Rows — fields that stay on the left (e.g. region, product)
  • Columns — fields whose distinct values become dynamic headers (e.g. quarter, channel)
  • Values — measures aggregated into each cell (sum, average, count, min, max, or custom)

Flat input like { region: 'West', quarter: 'Q1', sales: 1200 } becomes a West row with a Q1 sales cell. Multiple source rows that share the same dimensions collapse into one aggregated cell—classic spreadsheet-style pivoting inside your React data grid.

Common use cases: revenue by region × quarter, units by product × channel, tickets by team × status, and any analytics dashboard where columns must be generated from data—not hardcoded in your header config.

Pivot Table vs Row Grouping in React

Use a matrix pivot table when…

  • • You need dimensions as columns (quarters across the top)
  • • Cell values are aggregates, not detail rows
  • • Column headers should be generated from distinct field values
  • • You want row/column/grand totals in the matrix

Use row grouping when…

  • • You still need to see individual fact rows
  • • Hierarchy is expand/collapse down the left, not a cross-tab
  • • Columns stay fixed; you're organizing rows, not reshaping them
  • • See the row grouping docs and tree data guide

While pivot is active in Simple Table, consumer rowGrouping is ignored. Multi-level pivot.rows stay flat — one grid row per combination (e.g. region × product).

How to Build a React Pivot Table (Declarative Config)

Simple Table's matrix engine is declarative. Pass flat rows, a field catalog in columns, and a pivot config. End users can also arrange fields with enablePivotPanel, or your app can drive TableAPI.setPivot.

That gives teams a practical AG Grid pivot alternative: matrix pivoting and an in-table Pivot Panel without AG Grid Enterprise pricing.

React TSX
1import { SimpleTable } from "@simple-table/react";
2import type { ReactColumnDef, Row } from "@simple-table/react";
3import "@simple-table/react/styles.css";
4
5const headers: ReactColumnDef[] = [
6 { accessor: "region", label: "Region", width: 110, type: "string" },
7 { accessor: "quarter", label: "Quarter", width: 80, type: "string" },
8 { accessor: "sales", label: "Sales", width: 100, type: "number", align: "right" },
9];
10
11const rows: Row[] = [
12 { id: "r1", region: "West", quarter: "Q1", sales: 1200 },
13 { id: "r2", region: "West", quarter: "Q2", sales: 1500 },
14 { id: "r3", region: "East", quarter: "Q1", sales: 900 },
15 { id: "r4", region: "East", quarter: "Q2", sales: 1100 },
16];
17
18export default function RevenuePivot() {
19 return (
20 <SimpleTable
21 columns={headers}
22 rows={rows}
23 // Same shape as the docs / analytics "Region × Quarter" preset
24 pivot={{
25 rows: ["region"],
26 columns: ["quarter"],
27 values: [{ accessor: "sales", aggregation: { type: "sum" } }],
28 }}
29 columnResizing
30 height="400px"
31 />
32 );
33}

When pivot is active, the grid does not show the field catalog as columns. It shows generated row-dimension columns plus dynamic value columns from the pivot result. Full prop reference lives in the pivot table docs.

Nested Pivot Dimensions, Multiple Measures, and Totals

Multiple row fields

One or many row fields stay tabular: each distinct combination is its own grid row (docs/analytics "Region × Product" style presets). No expand/collapse hierarchy:

React TSX
1<SimpleTable
2 columns={headers}
3 rows={rows}
4 pivot={{
5 rows: ["region", "product"],
6 columns: ["quarter"],
7 values: [{ accessor: "sales", aggregation: { type: "sum" } }],
8 }}
9 height="400px"
10/>

Nested column groups

Multiple column fields produce nested headers (year → quarter):

React TSX
1// Docs / analytics preset: "Category × Year → Quarter"
2pivot={{
3 rows: ["category"],
4 columns: ["year", "quarter"],
5 values: [{ accessor: "sales", aggregation: { type: "sum" } }],
6}}

Multiple measures and totals

Add more value fields for side-by-side metrics—same pattern as the docs/analytics "Channel × Quarter" preset. Aggregation types match Simple Table's aggregate functions. Totals (showRowTotals, showColumnTotals, showGrandTotal) default to true:

React TSX
1pivot={{
2 rows: ["channel"],
3 columns: ["quarter"],
4 values: [
5 { accessor: "sales", aggregation: { type: "sum" }, label: "Sales" },
6 { accessor: "units", aggregation: { type: "sum" }, label: "Units" },
7 ],
8}}

Value-only layout (no column dimensions)

Pass an empty columns array to group and aggregate without generating a matrix of dynamic headers—same idea as the docs "Values only" preset:

React TSX
1pivot={{
2 rows: ["region", "category"],
3 columns: [],
4 values: [
5 { accessor: "sales", aggregation: { type: "sum" } },
6 { accessor: "cost", aggregation: { type: "sum" } },
7 ],
8}}

Update a React Pivot Table at Runtime (TableAPI)

The analytics demo and docs pivot demo swap presets by updating the controlled pivot prop (not setPivot):

React TSX
1import { useState } from "react";
2import { SimpleTable } from "@simple-table/react";
3import type { PivotConfig } from "@simple-table/react";
4
5const presets: { id: string; label: string; pivot: PivotConfig | null }[] = [
6 { id: "source", label: "Source data", pivot: null },
7 {
8 id: "region-quarter",
9 label: "Region × Quarter",
10 pivot: {
11 rows: ["region"],
12 columns: ["quarter"],
13 values: [{ accessor: "sales", aggregation: { type: "sum" } }],
14 },
15 },
16 {
17 id: "multi-rows",
18 label: "Region × Product",
19 pivot: {
20 rows: ["region", "product"],
21 columns: ["quarter"],
22 values: [{ accessor: "sales", aggregation: { type: "sum" } }],
23 },
24 },
25];
26
27export default function AnalyticsPivot() {
28 const [activeId, setActiveId] = useState(presets[0].id);
29 const active = presets.find((p) => p.id === activeId) ?? presets[0];
30
31 return (
32 <>
33 {presets.map((preset) => (
34 <button key={preset.id} type="button" onClick={() => setActiveId(preset.id)}>
35 {preset.label}
36 </button>
37 ))}
38 <SimpleTable
39 columns={headers}
40 rows={rows}
41 pivot={active.pivot}
42 height="480px"
43 />
44 </>
45 );
46}

Prefer imperative control? TableAPI.setPivot (documented on the pivot docs) updates the same config without remounting:

React TSX
1const tableRef = useRef<TableAPI>(null);
2
3tableRef.current?.setPivot({
4 rows: ["region"],
5 columns: ["quarter"],
6 values: [{ accessor: "sales", aggregation: { type: "sum" } }],
7});
8tableRef.current?.setPivot(null); // back to source rows
  • setPivot(config | null) — enable, update, or clear pivot
  • getPivot() — current config
  • getPivotHeaders() / getPivotedRows() — inspect the generated matrix

React Pivot Table Behavior Notes

  • Filters run on source rows before pivoting. Row-dimension columns keep their source accessors, so filtering by region still works. Generated measure columns are not filterable.
  • Sort and quick filter apply to the pivoted view.
  • CSV export exports the pivoted matrix, not the original fact table.
  • Pivoted measure cells are aggregated summaries—not meant for cell editing.
  • High column cardinality (many distinct column-field values) creates many leaf columns. Watch horizontal scroll and performance.

Pivot Panel: Enable enablePivotPanel with the column editor so end users place fields into Rows, Columns, and Values. Declarative pivot stays the foundation; the panel drives the same config.

React Pivot Table FAQ

What is a React pivot table?

A React pivot table reshapes flat rows into a matrix: row dimensions stay on the left, column dimensions become dynamic headers, and value fields are aggregated (sum, average, count, min, max, or custom) into each cell.

Is there a free alternative to AG Grid pivot mode?

Yes. Simple Table provides declarative matrix pivot without AG Grid Enterprise. You configure rows, columns, and values via props or TableAPI, or use enablePivotPanel in the column editor for an in-table Pivot Panel.

When should I use pivot vs row grouping in a React data grid?

Use matrix pivot when you need cross-tab columns generated from data and aggregated cells. Use row grouping when you still need individual fact rows in an expand/collapse hierarchy with fixed columns.

Does Simple Table include a Pivot Panel?

Yes. Set enablePivotPanel (with enableColumnEditor) to place fields into Rows, Columns, and Values from the column editor. The panel drives the same pivot config API as props and setPivot.

Can I update a React pivot table at runtime?

Yes. Swap a controlled pivot prop, use the Pivot Panel, or call TableAPI.setPivot to enable, change, or clear pivot. getPivot, getPivotHeaders, and getPivotedRows inspect the active matrix.

Ship a React Pivot Table Without Waiting on Enterprise

You can ship a React pivot table today without AG Grid Enterprise or hand-rolled matrix math. With a declarative pivot config you get:

  • Row / column / value dimensions with sum, average, count, and more
  • Nested dimensions and row/column/grand totals
  • Runtime updates via TableAPI for analytics presets
  • An in-table Pivot Panel (enablePivotPanel) on the same config model

Ready to add a React pivot table to your data grid?

Simple Table ships declarative pivot with aggregations, totals, and an in-table Pivot Panel. Configure rows, columns, and values in TypeScript—or let users compose them with enablePivotPanel.