Skip to content

Overview

Enterprise

Row grouping buckets the grid’s rows by the value of one or more columns and draws a collapsible header row for each group. Instead of one long flat list, readers see the data organised — Region → 8 groups, each openable to reveal its rows — with an optional aggregate summary (sum, average, count…) in every header. Nest several columns and the groups nest too.

Grouping ships in @zengrid/enterprise. It’s built on the core full-width row mechanism: a group header is a single cell spanning every column, so it rides the grid’s virtualization and scrolls with the body like any other row.

Create a grouping manager with rowGrouping(), hand its provider to the grid’s fullWidthProvider option, then attach() the grid and give it the flat rows with setData():

import { rowGrouping } from '@zengrid/enterprise/grid';
// Group by the Region column (index 2), summing Revenue (3), averaging MRR (4).
const grouping = rowGrouping({
groupBy: [2],
aggregations: { 3: 'sum', 4: 'avg' },
});
const grid = new Zengrid(el, {
fullWidthProvider: grouping.provider,
columns: [/* … */],
});
grouping.attach(grid);
grouping.setData(rows); // the flat, ungrouped rows

The manager owns the displayed rows from here: it buckets rows into a tree, interleaves a header row before each group, and pushes the result to the grid. Clicking a header (or its chevron) collapses or expands that group — the manager recomputes which rows are visible and re-renders.

  • groupBy — the columns to group by, outermost first. Each entry is a source column index (positional data) or a { col, comparator } spec to control how sibling groups are ordered. Pass several to nest the groups.
  • aggregations — a map of column index → reducer ('sum', 'avg', 'min', 'max', 'count', 'first', or your own (values) => value). Each result is shown in the group header.
  • aggLabel(col, value, ctx) — format an aggregate for the header (e.g. as currency). Return '' to hide one.
  • groupLabel(ctx) — the header’s title text; defaults to the group value.
  • expandedByDefault — start groups collapsed by setting this to false.
  • onExpandedChanged({ path, expanded }) — notified on every expand/collapse.

The manager exposes expandAll(), collapseAll(), setExpanded(path, bool), toggle(path), isExpanded(path) and getGroupCount() — drive them from your own toolbar or keyboard shortcuts.

Each tab is a different facet of grouping. Edit the snippet — change groupBy, add an aggregate, or nest a second column — and the grid re-renders.

groupBy: [2] buckets by Region. Click a header to expand/collapse. Change the index (try 1 for Role or 5 for Status) and re-run.

  • The manager owns the displayed rows. It transforms your flat rows into header + leaf rows and calls setData for you. Keep the flat data as your source of truth and feed it in through grouping.setData() (re-call it when the data changes).
  • Grouping keys are positional. With array-backed rows, groupBy and aggregations index into the row array (region is column 2, revenue is 3), the same indices your columns map to.
  • Headers span the content width. A group header is a full-width row, so it scrolls with the body and its aggregate summary sits at the right edge.
  • Nesting is unbounded. Add more columns to groupBy; each header indents by its depth, and expandAll / collapseAll reach every level.