Lattice Grid Buy a licence

demo D101

Holding the feed

Pausing incoming data deliberately, with the backlog counted

grid.updates.pause()

Building…
Loading a live grid…

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',
    // 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: a ten-thousand-update-a-second feed left unpaused during, say, a multi-row selection would make the selection unusable within a second. 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.