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.
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>