Skip to content

Single Column

Enterprise

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.

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 (index is 0 here, 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 to 18.
  • suppressCount — hide the (N) leaf-count suffix after each label.
  • groupCellRenderer(params) — draw the cell content yourself. Return an HTML string or an HTMLElement; it’s placed after the chevron, replacing the default label + count. params carries { 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>`,
});

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. singleColumn always returns exactly one column from getGroupColumns(), regardless of how many groupBy levels 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. groupCellRenderer only 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.