demo D146
Pinned rows in Angular
A grand total pinned below the scrolling body
grandTotalRow: 'bottom'
This grid fixes a grand total row below the scrolling body so it stays visible wherever the reader has scrolled. It keeps the figure a reader is really after in view at all times, rather than at the far end of a long table.
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' } },
{ field: 'service', title: 'Service', filter: { type: 'set' } },
{ field: 'resource', title: 'Resource', layout: { flex: 1, min: 200, max: 320 } },
{ field: 'region', title: 'Region', filter: { type: 'set' } },
{ 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',
} } } },
{ field: 'change', title: 'Change', type: 'number',
layout: { width: 140, min: 140 }, format: { style: 'percent', decimals: 1 } },
{ field: 'cost', title: 'Monthly cost', type: 'number', layout: { width: 170 },
format: { style: 'currency', currency: 'USD', decimals: 2 }, total: 'sum' },
];
const rows = [/* 200,000 cloud cost records */];
@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',
selection: 'multiple',
grandTotalRow: 'bottom',
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 })],
});
Pinning a totals row below the scrolling body
Pinned rows fix a row, or a small set of rows, outside the scrolling body of a JavaScript data grid so it stays visible regardless of where the reader has scrolled the rest of the data. A grand total is the common case: a reader scans a few thousand line items, and the sum, average or count at the foot of the column needs to sit in view the whole time rather than requiring a scroll to the bottom to check it. Lattice Grid controls this through grandTotalRow: 'bottom', which renders an aggregated row anchored beneath the scrolling body; the same mechanism accepts 'top' to anchor the row above the body instead, ahead of the first data row. The same idea extends to a row of your own choosing rather than an aggregated total: pinnedTopRows and pinnedBottomRows pin whatever objects you pass, rendered through the ordinary column pipeline but excluded from counting, sorting, filtering and export. See the step-by-step how to pin rows to the top of a grid guide for a runnable example and the source.
The pinned row shares column widths, alignment and pinned-column regions with the scrolling body, so a total lines up under its column without separate configuration, including when that column itself is pinned to the left or right edge. It sits outside the virtualised row set, so it does not shift position as the body is scrolled, resized or filtered. For screen reader users, the pinned row keeps its place in the grid’s row and column model, so assistive technology reports it by its actual row role rather than as a detached decoration outside the data.
How do you pin a totals row to the bottom of a data grid?
Set grandTotalRow: 'bottom' in the grid configuration. Lattice Grid renders the aggregated row outside the scrolling body, anchored to the bottom edge, sharing the same column widths and pinned regions as the rows above it. Use 'top' to anchor the row above the body instead.