Pivot Grid
Multi-dimensional summaries over flat data: drop fields into the row, column, value and filter areas, expand headers on both axes, and read sub / grand totals — all computed by the pure engine in @oge-ui/core. Drag the field chips between areas to re-pivot instantly — or, without a drag, open a chip's menu (Enter or right-click) and pick an area, and reorder with Ctrl+Arrow keys.
oge-pivot-grid oge-pivot-field field panel totals
5.000 rows 3 row fields year columns
Click headers to expand / collapse.
FiltersDrag fields between the areas
Rows Region Country City
Columns Year
Values Amount
import { ChangeDetectionStrategy, Component, viewChild } from '@angular/core';
import { OgePivotField, OgePivotGrid } from '@oge-ui/pivot';
import type { OgePivotCellClickEvent } from '@oge-ui/pivot';
@Component({
selector: 'demo-root',
imports: [OgePivotField, OgePivotGrid],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<oge-pivot-grid #pivot [data]="sales" (cellDblClick)="onDrillDown($event)">
<!-- four areas: row / column / data / filter -->
<oge-pivot-field dataField="region" area="row" />
<oge-pivot-field dataField="country" area="row" />
<oge-pivot-field dataField="city" area="row" />
<oge-pivot-field dataField="date" area="column" groupInterval="year" />
<oge-pivot-field dataField="amount" area="data" summaryType="sum" [format]="money" />
</oge-pivot-grid>
`,
})
export class Demo {
protected readonly sales = [
{ region: 'EMEA', country: 'Germany', city: 'Berlin', date: '2026-02-11', amount: 1249 },
{ region: 'EMEA', country: 'Türkiye', city: 'İzmir', date: '2026-05-02', amount: 890 },
{ region: 'APAC', country: 'Japan', city: 'Tokyo', date: '2025-11-19', amount: 2140 },
];
private readonly pivot = viewChild.required(OgePivotGrid);
protected readonly money = (value: unknown): string =>
Number(value).toLocaleString('de-DE', { style: 'currency', currency: 'EUR' });
// every cell knows its coordinates — perfect for drill-down
protected onDrillDown(event: OgePivotCellClickEvent): void {
const rows = this.pivot().drillDown({
rowPath: event.rowPath,
columnPath: event.columnPath,
});
console.log(rows);
}
}Notes
- The engine interns axis paths and accumulates cells in a single pass; expanding or collapsing a header only re-materializes the visible matrix.
- An expanded group keeps its own line, which carries the subtotals — collapse it from the same line.
groupIntervalbuckets dates (year/quarter/month/…) or numbers (bucket size).summaryType: sum · count · avg · min · max · custom (withcalculateCustomSummary); display modes (percent-of, running totals, variations) ship in the engine.drillDown(rowPath, columnPath)returns the raw rows behind any cell — on the component, with the coordinates from(cellClick)/(cellDblClick).