Lattice Grid Buy a licence

demo D59

Cross-filtering, done properly: JavaScript Data Grid Demo

Live column charts that cross-filter, where a filtered column keeps its own bars

facets

This grid draws a live bar chart in every column heading, so the shape of each column reads at a glance and a taller, fuller bar means more rows. Picking values narrows every chart together, while a filtered column keeps its own full chart so you can still switch, and pointing at any bar shows its exact row count.

Building…
Loading a live grid…

The configuration

<link rel="stylesheet" href="https://cdn.latticegrid.dev/lattice-grid@1.103.2/lattice-grid.min.css">
<script src="https://cdn.latticegrid.dev/lattice-grid@1.103.2/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' },
    facets: { enabled: true, collapsed: false, height: 46 },
    // Service and Created are left out: neither makes a readable histogram here.
    columns: [
      { field: 'team', title: 'Team', filter: { type: 'set' } },
      { field: 'tier', title: 'Tier', filter: { type: 'set' } },
      { field: 'state', title: 'State', filter: { type: 'set' } },
      { field: 'region', title: 'Region', filter: { type: 'set' } },
      { field: 'errorRate', title: 'Error rate', type: 'number', format: { style: 'percent', decimals: 2 }, filter: { type: 'number' } },
      { field: 'monthlyCost', title: 'Monthly cost', type: 'number', layout: { width: 160 },
        format: { style: 'currency', currency: 'USD' }, total: 'sum', filter: { type: 'number' } },
      { field: 'lastDeploy', title: 'Last deploy', type: 'dateString', filter: { type: 'date' } },
    ],
    // Opens with Tier filtered: a column is counted against every filter
    // except its own, so the Tier chart still shows silver and bronze while
    // every other chart shows only what survives.
    state: { version: 1, filters: { col: 'tier', op: 'in', value: ['gold'] } },
    rows,  // 20,000 service records
  });
</script>

Cross-filtering without a column excluding itself

Cross-filtering is the pattern behind faceted browsing: each column heading carries a small bar chart of that column’s values, and as filters narrow the rows, every chart narrows with them, so the bars always show how the current selection is distributed. The defect a naive version falls into is counting a column against its own filter, so narrowing “region” to a single value collapses that same column’s chart to one bar and leaves no way to see the other regions or widen the selection. Lattice Grid’s facets avoid this automatically: a column is never counted against its own active filter, so a user who has filtered “tier” to gold still sees silver and bronze in the tier chart and can switch at any time, while every other column shows only the rows that survive. Each bar reads two things at once: its full height is the value’s share of the whole column, and the solid fill inside is how much of that survives the current filters, so a value that has been mostly filtered out still shows where it sits in the column. Point at any bar and its tooltip gives the exact figure, as “surviving of total rows”, and the same reading is written into the bar’s accessible name for a screen reader. A developer reaches for this whenever a JavaScript data grid exposes faceted filtering across several related columns and the charts need to stay honest as each filter narrows the rows further. The recomputation runs against the column’s dictionary-encoded values rather than rescanning raw cell text, so refreshing the charts across a handful of filtered columns on a grid with hundreds of thousands of rows stays within a frame budget.

Why do my filter counts drop to zero when I select a value?

That happens when a column is counted against its own active filter: selecting one value leaves only rows matching it, so every other value in that same column’s chart falls to zero and the chart becomes a single bar. Lattice Grid’s facets exclude a column’s own filter from its own chart automatically, which is what lets a filtered column keep its full set of bars while every other column cross-filters down to what survives.