Row grouping and aggregation
Group by one or more value columns, choose how group labels are displayed, and calculate aggregates over each group's leaf descendants.
- React
- Angular
- Core TypeScript
<Grid
rowData={rows}
columnDefs={columns}
groupDefaultExpanded={1}
groupRowsSticky
toolbar={{ grouping: true }}
onGridReady={(api) => {
api.dispatch({ type: "rowGroupSet", colIds: ["region", "country"] });
}}
/>
<awb-grid
[rowData]="rows"
[columnDefs]="columns"
[groupDefaultExpanded]="1"
[groupRowsSticky]="true"
[toolbar]="{ grouping: true }"
(gridReady)="group($event)"
/>
group(api: IGridAPI) {
api.dispatch({ type: "rowGroupSet", colIds: ["region", "country"] });
}
const core = new GridCore(measurer, {
columnDefs,
groupDisplayType: "singleColumn",
groupDefaultExpanded: 1,
groupRowsSticky: true,
});
api.dispatch({ type: "rowGroupSet", colIds: ["region", "country"] });
api.setAllGroupsExpanded(true);
Multi-level row grouping
const options = {
groupDisplayType: "singleColumn",
groupDefaultExpanded: 1,
groupSortMode: "local",
columnDefs: [
{ colId: "region", key: "region", label: "Region", groupable: true },
{ colId: "country", key: "country", label: "Country", groupable: true },
{ key: "revenue", label: "Revenue", type: ColumnType.CURRENCY },
],
} satisfies GridOptions;
api.dispatch({ type: "rowGroupSet", colIds: ["region", "country"] });
api.setAllGroupsExpanded(true);
Use groupRowsSelectable: true when generated group rows should participate in
selection, navigation, and copying.
Display and expansion
groupDisplayType accepts singleColumn, multipleColumns, or groupRows.
groupDefaultExpanded sets the initial depth; later user expansion remains
stable across refreshes (when group values are unchanged). groupRowsSticky
docks the active ancestor chain while the body scrolls — see
pinned & sticky rows.
The toolbar provides a grouping picker, ordered chips, drag insertion, keyboard reordering, and clear-all behavior. The API can replace grouped columns and expand or collapse all groups in one update, or toggle a single group:
api.dispatch({
type: "groupToggleExpand",
groupId: "the-stable-group-node-id",
expanded: true,
});
Aggregates
Available functions are count, distinct count, sum, average, min, max, and median. The footer scope can be none, current page, or all rows. Grouped client-side rows also receive per-group aggregate values.
const revenue = api.getColumnModel().getByColId("revenue")!;
const orders = api.getColumnModel().getByColId("orders")!;
api.dispatch({
type: "aggregateModelSet",
aggregateModels: [
{ key: revenue.instanceID, type: AggregateType.SUM },
{ key: orders.instanceID, type: AggregateType.COUNT },
],
});
Server-side grouping and aggregation
Server-side grouping requests one parent listing at a time and sends aggregate definitions with the request:
const dataSource: IServerSideDataSource = {
async getRows({ request }) {
// request.groupBy: ["region", "country"]
// request.groupKeys: [{ key: "region", value: "EMEA" }, ...]
return queryOneGroupingLevel(request);
},
getAggregates: async ({ request }) => ({
values: await loadAggregateValues(request),
}),
};
const options = {
rowModelType: "serverSide",
serverSideDataSource: dataSource,
getGroupChildCount: (row) => row.childCount,
} satisfies GridOptions;
Each expanded group loads its own child listing lazily — see server-side data.
Row grouping is also one of pivot mode's three roles: pivoting reuses the group tree and crosses it with pivot columns and aggregates (client-side row model).