demo D101
Holding the feed: JavaScript Data Grid Demo
Pausing incoming data deliberately, with the backlog counted
grid.updates.pause()
This grid lets you pause an incoming feed deliberately while counting the backlog that builds up behind the pause. It gives a reader a moment to study the current state of a fast source, then release and catch up, without losing any updates.
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',
selection: 'multiple',
// Pause is a rail action. Holding the feed is deliberately a control rather
// than something inferred from whether the visitor looks busy: that guess
// is wrong in both directions.
toolPanel: {
side: 'left',
panels: ['columns', 'filters', 'views', 'quick'],
actions: ['pause', 'undo', 'redo', 'export', 'maximise'],
exportName: 'lattice-demo',
},
statusBar: { panels: ['rowCount', 'progress', 'updates', 'selectedCount'] },
highlightOnChange: { duration: 600 },
updates: { flush: 'frame' },
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: 'ticks', title: 'Ticks', type: 'number', layout: { width: 90 } },
{ field: 'volume', title: 'Volume', type: 'number', layout: { width: 120 },
format: { notation: 'compact' }, filter: { type: 'number' } },
{ field: 'status', title: 'Status', filter: { type: 'set' }, layout: { width: 110 },
cell: { decoration: 'pill', variant: { map: { open: 'success', halted: 'danger', settled: 'neutral' } } } },
],
rows, // 20,000 instruments
});
// Changes keep merging while the pause button holds the feed, so the backlog
// is rows of work rather than messages: forty updates to one row are one row
// to apply when play is pressed.
socket.onmessage = (event) => {
grid.rows.queue({ update: JSON.parse(event.data) });
};
</script>
Pausing a live feed without dropping what arrives while paused
A fast-moving source, whether a websocket tick stream or a polling endpoint, does not stop producing rows just because the user has stopped watching the screen. Holding the feed is the pattern for that gap: the grid keeps accepting updates from the source but withholds them from the render, so the view on screen stays exactly as the user left it, no rows resorting under the cursor, no cell flashing green while someone is trying to click it. Lattice Grid exposes this as grid.updates.pause(), paired with a resume call that flushes the backlog in one pass rather than replaying each update in sequence. While paused, the grid counts what has queued up, so a badge or status line can tell the user how much is waiting rather than leaving them guessing whether the feed has died. This matters most for a JavaScript data grid used against a genuinely high-frequency source: the 500-row-a-second feed on this page, left unpaused during, say, a multi-row selection, would make the selection unusable within a couple of seconds. Pausing costs nothing in memory beyond the queued diff itself, since the grid is not re-rendering during the pause, only accumulating, and resume applies the backlog as a single batched update rather than one DOM write per queued row.
How do I pause a live-updating grid without losing the updates that arrive in the meantime?
Call grid.updates.pause(). Lattice Grid keeps receiving updates from the source and queues them instead of rendering them, so the current view stays still. The queued count is available while paused, and calling resume applies the whole backlog in a single batched render rather than replaying each update individually.