Lattice Grid Buy a licence

demo D98

Streaming

Rows arriving over time, first paint on the first chunk

source: { mode: 'stream' }

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',
    toolPanel: {
      side: 'left',
      panels: ['columns', 'filters', 'views', 'quick'],
      actions: ['undo', 'redo', 'export', 'restore', 'maximise'],
      exportName: 'lattice-demo',
    },
    statusBar: { panels: ['rowCount', 'progress', 'updates', 'selectedCount'] },
    // The first chunk paints immediately and the rest merge in behind it, so
    // sorting part-way through the load keeps working: arriving rows are
    // merge-inserted, not re-sorted. open returns an async iterable of chunks,
    // each { rows, progress?, done? }; the last chunk carries done: true.
    source: {
      mode: 'stream',
      open: (req) => openStream({ signal: req.signal }),  // your source of chunks
    },
    columns: [
      { field: 'symbol', title: 'Symbol', layout: { width: 130, pin: 'start' } },
      { field: 'name', title: 'Instrument', layout: { flex: 1, min: 170, max: 280 } },
      { 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: they arrive chunk by chunk from the stream.
  });
</script>

Rendering rows as they arrive, without waiting for the full response

A streaming source is for data that does not exist as a single payload: a websocket feed, a chunked HTTP response, a backend that resolves rows in batches rather than all at once. Rather than blocking the grid until the last row lands, Lattice Grid paints the first chunk the moment it arrives and appends each subsequent chunk to the existing render, so a feed of ten thousand rows produces a usable grid within the time it takes the first few hundred to arrive. The mode is set with source: { mode: 'stream' }, and from that point the grid treats incoming rows as an open-ended sequence rather than a fixed table, which matters for anything built around a server-side row model where the client never holds a definitive row count up front. Because the grid is a JavaScript data grid working directly against the DOM rather than a virtual document layer, each batch is appended without a full reflow of rows already on screen, so scroll position and any active selection stay put as new rows land underneath. This suits dashboards, log viewers and trading tickets: any surface where the value of a row is highest the moment it is available, and where waiting for completeness would mean showing nothing during the interval that matters most.

How do I show grid rows as they stream in rather than waiting for all the data?

Set source: { mode: 'stream' } on the grid configuration. Lattice Grid then renders each batch of rows as it is received instead of buffering until the source signals completion, so the first paint happens on the first chunk. Existing rows, scroll position and selection are preserved as later batches are appended.