Grouping, spanners and pivots

Pivot tables

Use a pivot when you need to cross-tabulate one measure across two categorical fields instead of listing every row.

What you can do

  • pivot lives inside TableSpec alongside columns; when both are present, pivot wins, since the schema has no oneOf between them.
  • rows and columns are each a non-empty array of field names that become the pivot’s row and column axes.
  • values holds 1-20 PivotValue entries, each a field plus an optional agg (sum, avg, min, max, count) that becomes one generated data column per column-axis combination.
  • weightField on a PivotValue computes a weighted aggregate instead of a plain one; label, format, align, colorScale, cell, and conditionalFormat all apply per value the same as on a regular column.
  • totals turns on row, column, and/or grand summary rows/columns; maxColumns (1-200, default 50) caps how many generated columns the pivot can produce.

pivot only appears inside a table panel’s spec; there is no pivot equivalent on any chart:* panel.

Spec

View spec
{
  "id": "regional-pivot",
  "type": "table",
  "title": "Revenue by category and region",
  "data": {
    "rows": [
      {
        "category": "Hardware",
        "region": "West",
        "revenue": 420000,
        "units": 1200
      },
      {
        "category": "Hardware",
        "region": "East",
        "revenue": 310000,
        "units": 900
      },
      {
        "category": "Software",
        "region": "West",
        "revenue": 560000,
        "units": 2100
      },
      {
        "category": "Software",
        "region": "East",
        "revenue": 480000,
        "units": 1800
      }
    ]
  },
  "spec": {
    "pivot": {
      "rows": [
        "category"
      ],
      "columns": [
        "region"
      ],
      "values": [
        {
          "field": "revenue",
          "agg": "sum",
          "weightField": "units",
          "format": {
            "type": "currency",
            "currency": "USD",
            "compact": true
          }
        }
      ],
      "totals": {
        "row": true,
        "column": true,
        "grand": true
      },
      "maxColumns": 50
    }
  }
}

weightField on the revenue value computes a units-weighted sum instead of a plain sum, and totals adds row, column, and grand summary cells.

Try it live

Open the rich-tables template in the Builder

Open the rich-tables template, page p4-pivot, panel p4-cat-region for a category-by-region pivot, and panel p4-region-quarter for a region-by-quarter one with a colorScale on the values.

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.

No spam. We use this to reach out directly, nothing else.