demo D58
Header histograms
A distribution in every heading that is also the filter control
facets: { enabled: true }
The configuration
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.13.0/lattice-grid.min.css">
<script src="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.13.0/lattice-grid.min.js"></script>
<div id="grid" style="height: 540px"></div>
<script>
const grid = LatticeGrid.createGrid(document.getElementById('grid'), {
rowKey: 'id',
toolPanel: { side: 'left', panels: ['filters', 'columns'], actions: ['restore'], exportName: 'lattice-demo' },
// Open rather than the default one-line strip: the band is the subject here.
facets: { enabled: true, collapsed: false, height: 46 },
columns: [
{ field: 'account', title: 'Account', filter: { type: 'set' } },
{ field: 'service', title: 'Service', filter: { type: 'set' } },
{ 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',
} } } },
// Quantile buckets on both money columns: cloud spend has a long tail,
// and equal-width buckets would put nearly every row in the first bar.
{ field: 'change', title: 'Change', type: 'number',
layout: { width: 140, min: 140 }, format: { style: 'percent', decimals: 1 },
facet: { strategy: 'quantile' } },
{ field: 'cost', title: 'Monthly cost', type: 'number', layout: { width: 170 },
format: { style: 'currency', currency: 'USD', decimals: 2 }, total: 'sum',
facet: { strategy: 'quantile' } },
],
rows, // 25,000 cloud cost rows
});
</script>
Filtering a numeric column from a histogram in the header
A header histogram draws the distribution of a column’s values as a small bar chart inside the header, then lets a click or drag on that chart set the filter for the column below it. A developer reaches for it when a numeric or date column has enough spread that a plain min/max input leaves the shape of the data invisible: a price column with most rows clustered low and a handful of outliers, or a duration column where the useful cutoff is not obvious until the distribution is visible. Lattice Grid turns this on with facets: { enabled: true }, a grid-level option that builds bucketed counts for each eligible column and keeps them current as rows are added, removed or edited, so the bars never lag an applied filter elsewhere in the grid. Bucketing runs once per column on data change, not per render, so in a JavaScript data grid holding a hundred thousand rows a histogram costs a single pass rather than one per scroll frame. Each bar carries its count and range in an accessible label, so a screen reader announces the bucket a keyboard user has focused rather than requiring the chart’s shape to be seen. The same facet data backs the filter menu, so a histogram selection and a typed range stay in sync.
How do I let users filter a column by clicking its value distribution?
Set facets: { enabled: true } on the grid. Lattice Grid computes bucketed counts for each eligible numeric or date column and renders them as a small histogram in the column header; clicking or dragging across the bars sets the column filter to that range. The buckets recompute as the underlying data changes, so the chart and the active filter stay consistent with each other.