Lattice Grid Buy a licence

demo D73

Pivot with several value columns in Angular

Generated column groups, and what the headings do

pivot.groupTotals

This grid pivots two measures at once, so 'Revenue' and 'Units' appear together under every distinct key, with generated column groups labelling them. It answers several questions per key in one table, so you compare related figures side by side.

Building…
Loading a live grid…

This is the Angular version. A standalone component takes the whole configuration through one config input, surfaces grid events as outputs, and exposes the live grid on a getter for anything the inputs do not cover.

The configuration

import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { createGrid } from '@toclocoinc/lattice-grid';
import '@toclocoinc/lattice-grid/css';
import { LatticeGridComponent, provideLattice } from '@toclocoinc/lattice-grid/angular';

const columns = [
  { field: 'account', title: 'Account', filter: { type: 'set' }, group: { enabled: true, index: 0 } },
  { field: 'environment', title: 'Env', filter: { type: 'set' },
    cell: { decoration: 'pill', variant: { map: {
      prod: 'danger', 'prod-2': 'danger', 'definitely-prod': 'danger',
      staging: 'warning', untagged: 'warning', test: 'info',
      dev: 'success', 'not-prod': 'neutral',
    } } },
    pivot: { enabled: true, index: 0 } },
  { field: 'cost', title: 'Monthly cost', type: 'number', layout: { width: 170 },
    format: { style: 'currency', currency: 'USD', decimals: 2 }, total: 'sum' },
  { field: 'change', title: 'Change', type: 'number',
    layout: { width: 140, min: 140 }, format: { style: 'percent', decimals: 1 }, total: 'avg' },
];

const rows = [/* cloud cost rows, one object per resource */];



@Component({
  selector: 'app-root',
  standalone: true,
  imports: [LatticeGridComponent],
  template: '<lattice-grid [config]="grid" style="display:block;height:540px"></lattice-grid>',
})
export class AppComponent {
  grid = {
    rowKey: 'id',
    pivot: { enabled: true, groupTotals: 'after', maxColumns: 40 },
    toolPanel: { side: 'left', panels: ['columns', 'filters', 'views', 'quick'],
          actions: ['undo', 'redo', 'export', 'restore', 'maximise'], exportName: 'lattice-demo' },
    columns: columns,
    rows: rows,
  };
}

bootstrapApplication(AppComponent, {
  providers: [provideLattice({ createGrid })],
});

Pivoting several value columns at once

A single-value pivot answers one question per distinct key: revenue by region, say. A multi-value pivot answers several at once, transposing “Revenue” and “Units” together across every status or region found in the data, so each distinct key produces its own generated column group rather than a single generated column. A developer reaches for this once a report needs more than one measure per pivoted key, such as a finance grid showing both an amount and a count for every quarter, without hand-building a separate pivot for each. Lattice Grid controls the heading structure for this case with pivot.groupTotals, which decides whether each generated group carries its own subtotal column alongside the per-value columns, or whether the totals stay out of the generated groups entirely. Because this is a JavaScript data grid that reduces incrementally rather than rescanning, a row arriving on a live feed updates only the pivoted cells its key and values touch, not the whole transposed table. The generated column groups behave like any other column group for sizing, visibility and export, so a wide pivot with many keys still virtualises horizontally and only renders the columns in the current viewport.

How do I pivot on more than one value column?

Pass more than one field to the value side of the pivot configuration and Lattice Grid generates a column group per distinct key, containing one column for each value alongside the pivoted dimension. Use pivot.groupTotals to decide whether each generated group also gets its own subtotal, matching how the equivalent single-value pivot handles totals.