demo D99
A bounded window
A never-ending feed as a sliding window
source.maxRows
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',
selection: 'multiple',
toolPanel: {
side: 'left',
panels: ['columns', 'filters', 'views', 'quick'],
actions: ['undo', 'redo', 'export', 'restore', 'maximise'],
exportName: 'lattice-demo',
},
statusBar: { panels: ['rowCount', 'progress', 'updates', 'selectedCount'] },
// The stream never ends, so without maxRows this grid would grow until the
// tab died overnight. The window drops the oldest rows as new ones arrive,
// and the physical index stays put while it does: a selection made ten
// thousand rows ago still points at its row.
source: {
mode: 'stream',
maxRows: 20000,
open: (req) => openEndlessStream({ signal: req.signal }), // a stream with no end
},
columns: [
{ field: 'symbol', title: 'Symbol', layout: { width: 130, pin: 'start' } },
{ field: 'desk', title: 'Desk', filter: { type: 'set' } },
{ field: 'region', title: 'Region', filter: { type: 'set' } },
{ field: 'price', title: 'Price', type: 'number', layout: { width: 120 },
format: { decimals: 4 }, filter: { type: 'number' } },
{ field: 'change', title: 'Change', type: 'number', layout: { width: 110 },
format: { style: 'percent', decimals: 2 } },
{ field: 'volume', title: 'Volume', type: 'number', layout: { width: 120 },
format: { notation: 'compact' }, filter: { type: 'number' } },
{ field: 'notional', title: 'Notional', type: 'number', layout: { width: 150 },
format: { style: 'currency', currency: 'USD', notation: 'compact' } },
{ field: 'status', title: 'Status', filter: { type: 'set' }, layout: { width: 110 },
cell: { decoration: 'pill', variant: { map: { open: 'success', halted: 'danger', settled: 'neutral' } } } },
],
// No rows: the window fills from the endless stream, capped at maxRows.
});
</script>
Capping a live feed to a fixed row count
A bounded window trims a continuously updating source down to a fixed number of the most recent rows, discarding the oldest entry each time a new one arrives. A developer reaches for it with any feed that has no natural end: a trade blotter, a log tail, a sensor reading queue, anywhere the source would otherwise grow without limit and eventually exhaust memory or slow the grid down. Lattice Grid controls the behaviour with source.maxRows, which sets the ceiling once and lets every subsequent insert evict the oldest row automatically, so the caller never has to track a count or issue a separate delete. Because this is a JavaScript data grid built on incremental row operations rather than full re-renders, an eviction and an insert are handled as a single paired update: the DOM node for the departing row is reused for the arriving one rather than torn down and rebuilt, which keeps the cost of each tick independent of how long the feed has been running. The row count stays constant, so scroll position, column widths and any active sort or filter remain stable across thousands of updates rather than drifting as the dataset grows. The window size is a plain number, tuned per feed to whatever span of history a given view actually needs.
How do I limit a live-updating grid to the last N rows?
Set source.maxRows to the row count you want to keep. Lattice Grid then evicts the oldest row automatically whenever a new one arrives, so the feed holds a constant, sliding window of the most recent entries rather than growing indefinitely, with no separate cleanup logic required from the calling code.