Single Column
Introduction
Section titled “Introduction”Group Display Types introduced the
three ways to surface a group hierarchy. This page is a deep dive on
displayType: 'singleColumn' — the whole hierarchy, however many levels deep,
collapsed into one leading column that indents with depth. Every other column
stays a normal data column, so aggregates render in their own column rather
than in a full-width header.
Ask the manager for that one column with getGroupColumns() and spread it
ahead of your data columns:
const grouping = rowGrouping({ groupBy: [2, 5], // Region -> Status, both in the one column displayType: 'singleColumn', aggregations: { 3: 'sum' }, // renders in the real Revenue column groupColumnLabel: () => 'Region / Status',});
new Zengrid(mount, { columns: [...grouping.getGroupColumns(), ...dataColumns], fullWidthProvider: grouping.provider,});Because the manager reshapes the rows to match the prepended column, keep your data columns contiguous from the first source index — the group column owns the leading slot.
Customising the group column
Section titled “Customising the group column”The single column is where every level lives, so it earns the most tuning. All of
these are options on rowGrouping():
groupColumnLabel(index, spec)— the column header text (indexis0here, since there’s one column).groupColumnWidth— its width in pixels.indentPerLevel— how far (px) each nesting level shifts right. Raise it to make a deep hierarchy read like an outline; lower it to keep the column narrow. Defaults to18.suppressCount— hide the(N)leaf-count suffix after each label.groupCellRenderer(params)— draw the cell content yourself. Return an HTML string or anHTMLElement; it’s placed after the chevron, replacing the default label + count.paramscarries{ key, label, col, count, level, expanded, aggs }, so you can render an icon, a badge, a formatted count, or an inline aggregate — while the cell keeps handling indentation and click-to-toggle.
rowGrouping({ groupBy: [2, 5], displayType: 'singleColumn', indentPerLevel: 28, suppressCount: true, groupCellRenderer: ({ label, count, level }) => `${level === 0 ? '🌐' : '•'} <strong>${label}</strong>` + ` <span style="opacity:.6">${count} rows</span>`,});Try it live
Section titled “Try it live”The default single-column layout. Region -> Status collapse into one indented column; the Revenue aggregate renders in the real Revenue column. Try changing groupColumnWidth.
- One column, every level.
singleColumnalways returns exactly one column fromgetGroupColumns(), regardless of how manygroupBylevels you have — the hierarchy is expressed by indentation, not extra columns. For a column per level, use Multiple Columns. - Aggregates render in their column. With no full-width header to host them,
each configured aggregate lands in its real data column and is formatted by that
column’s own
renderer(here,currency). - The custom renderer keeps the plumbing.
groupCellRendereronly replaces the label + count. The chevron, per-level indent (indentPerLevel) and click-to-toggle are still applied by the cell around your content. - Keep data columns contiguous. With positional array rows the group column takes the leading slot; your data columns must follow in source order so each cell lands under the right column.
- Multiple Columns — a column per level, with per-column control.
- Group Rows — the full-width header layout.