Column groups
Add column groups when several columns share a common category, like four quarters under one revenue header, and a single flat header row would be confusing.
| Region | H1 | |||
|---|---|---|---|---|
| Q1 | Q2 | |||
| Revenue | Margin | Revenue | Margin | |
| EMEA | $612,000 | 24.5% | $421,500 | 21.1% |
| APAC | $398,000 | 18.2% | $244,300 | 16.4% |
| AMER | $780,200 | 29.1% | $560,100 | 27.3% |
| LATAM | $198,100 | 12.7% | $176,400 | 13.9% |
What you can do
- A
ColumnGrouprequireslabeland takes eithercolumns(an array of field names) or nestedcolumnGroups, never both at once. - Nesting
columnGroupsinside aColumnGrouprenders an extra spanner header row above the leaf group’s own header, one level per level of nesting. - Columns inside one group should stay contiguous in the
columnsarray; a group spanning non-adjacent columns renders incorrectly. columnGroupslives onTableSpecalongsidecolumns; every field a group references still needs its own entry incolumns.- There is no limit on how many
ColumnGroupentries or nesting levelsTableSpec.columnGroupscan hold.
Set on TableSpec.columnGroups on a table panel; a chart:* panel has no multi-row header to group, since it has no columns.
Spec
View spec
{
"id": "quarterly-revenue-table",
"type": "table",
"title": "Revenue by quarter",
"data": {
"rows": [
{
"segment": "Enterprise",
"q1": 210000,
"q2": 230000,
"q3": 250000,
"q4": 270000
},
{
"segment": "SMB",
"q1": 90000,
"q2": 95000,
"q3": 101000,
"q4": 108000
}
]
},
"spec": {
"columns": [
{
"field": "segment",
"label": "Segment"
},
{
"field": "q1",
"label": "Q1",
"format": {
"type": "currency",
"currency": "USD",
"compact": true
},
"align": "right"
},
{
"field": "q2",
"label": "Q2",
"format": {
"type": "currency",
"currency": "USD",
"compact": true
},
"align": "right"
},
{
"field": "q3",
"label": "Q3",
"format": {
"type": "currency",
"currency": "USD",
"compact": true
},
"align": "right"
},
{
"field": "q4",
"label": "Q4",
"format": {
"type": "currency",
"currency": "USD",
"compact": true
},
"align": "right"
}
],
"columnGroups": [
{
"label": "Revenue by quarter",
"columnGroups": [
{
"label": "H1",
"columns": [
"q1",
"q2"
]
},
{
"label": "H2",
"columns": [
"q3",
"q4"
]
}
]
}
]
}
}The outer group "Revenue by quarter" has no columns of its own; it nests two child groups, "H1" and "H2", each with its own contiguous columns pair, producing two spanner header rows above the leaf headers.
Try it live
Open the collections-report template in the Builder
Open the collections-report template, panel cl-ledger for three columnGroups alongside bullet, sparkline, bar, winloss, and icon cells.
Build it in dvt
Every table capability on this site is a few lines of the same declarative JSON spec. Read the full spec format, or connect an AI agent to your warehouse and build one live in the quickstart.
Follow the build
dvt is in founding research. Leave your email and we'll reach out when there's something to see — no newsletters, no noise.