Lattice Grid Buy a licence

demo D260

Real-Time Operations Dashboard: One Feed, Many Grids in ESM

One feed drives orders, shipments and incidents grids and a throughput chart, with no backend

createDataRouter · MockWebSocket · opsFeed

This is a ready-made operations console: one feed drives an orders grid, a shipments grid and an incidents grid plus a throughput chart, all with no backend. It is a working starting point you can lift and point at real data, showing several live views sharing one source.

Building…
Loading a live grid…

This is the ES module version. The grid is imported straight from a CDN as a module, the same configuration as the vanilla tab without a global script tag, so it drops into any bundler or a bare module script.

The configuration

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@toclocoinc/lattice-grid@1.71.0/lattice-grid.min.css">

<div id="orders" style="height: 300px"></div>
<div id="shipments" style="height: 300px"></div>
<div id="incidents" style="height: 300px"></div>
<div id="chart" style="height: 200px"></div>

<script type="module">
  import { createDataRouter } from '@toclocoinc/lattice-grid/modules/data-router';
  import { createChart } from '@toclocoinc/lattice-grid/modules/charts';
  import { MockWebSocket, opsFeed } from '@toclocoinc/lattice-grid/modules/mock-socket';

  const money = { style: 'currency', currency: 'USD', decimals: 0 };
  const orders = createGrid(document.getElementById('orders'), {
    rowKey: 'id', selection: { mode: 'multiple', checkbox: true },
    columns: [
      { field: 'id', title: 'Order', layout: { width: 96 } },
      { field: 'region', title: 'Region', filter: { type: 'set' } },
      { field: 'customer', title: 'Customer' },
      { field: 'value', title: 'Value', type: 'number', format: money, total: 'sum' },
    ],
  });
  const shipments = createGrid(document.getElementById('shipments'), {
    rowKey: 'id', columns: [
      { field: 'id', title: 'Shipment', layout: { width: 96 } },
      { field: 'region', title: 'Region', filter: { type: 'set' } },
      { field: 'carrier', title: 'Carrier' },
      { field: 'units', title: 'Units', type: 'number', total: 'sum' },
    ],
  });
  const incidents = createGrid(document.getElementById('incidents'), {
    rowKey: 'id', columns: [
      { field: 'id', title: 'Incident', layout: { width: 96 } },
      { field: 'region', title: 'Region', filter: { type: 'set' } },
      { field: 'service', title: 'Service' },
      { field: 'severity', title: 'Severity' },
    ],
  });
  const metrics = createHeadlessGrid({
    rowKey: 't', columns: [{ field: 't', type: 'number' }, { field: 'events', type: 'number' }],
  });

  // One partition key, four routes. link narrows Incidents to the regions of the
  // orders you select, re-pushed through the same keyed-diff path.
  const router = createDataRouter({ key: 'type', rowKey: 'id' });
  router.attach(orders, 'order');
  router.attach(shipments, 'shipment');
  router.attach(incidents, 'incident');
  router.attach(metrics, 'metric', { rowKey: 't' });
  router.link(orders, incidents, { from: 'region', to: 'region' });

  createChart({ grid: metrics, container: document.getElementById('chart'), type: 'line', x: 't', y: 'events', title: 'Throughput per tick' });

  // The mock socket runs it with no backend; one line swaps in a real WebSocket.
  const socket = new MockWebSocket({ feed: opsFeed({ seed: 7 }), rate: 900, jitter: 300 });
  socket.onmessage = (event) => {
    const message = JSON.parse(event.data);
    if (message.kind === 'snapshot') router.load(message.rows);
    else router.apply(message.changes);
  };
</script>