Lattice Grid

blog

One dashboard across several monitors, 1.120

An operations wall, a trading desk and an incident room all have the same shape. People run two or three monitors, and they want the chart on one, the grid on another and the board on a third. The usual answer is a second browser tab for each screen. Each tab opens its own socket, asks for its own login, and slowly drifts away from the others. You filter the grid on monitor one and the chart on monitor two has no idea.

This release makes the several-screens dashboard one dashboard. One window holds the live feed. Any panel can be popped out into its own browser window and dragged to another monitor. The other windows open no connection of their own: they join a shared channel, get the current rows at once, and follow every update.

What you get on the second screen

Type a filter in the grid on monitor one, and the chart, the key figures and the board on monitor two show only those rows. Tick rows and they narrow further. A second copy of the same grid follows the first one’s filter, sort and columns. Close a pop-out and the panel comes back where it was.

Any view that binds to a grid can be the popped-out panel: a chart, a KPI tile, a Kanban board, a map, a Gantt chart, a calendar or another grid.

The wiring

Routes are named by a label. Relations name those routes instead of grid objects, so either end of a relation can live in another window. The feed is loaded in one window only.

const router = createDataRouter({ key: 'id', rowKey: 'id' });
const isIncident = (row) => row.type === 'incident';

// One route per panel. A chart, KPI tile or board reads a grid of its own.
router.subscribe(isIncident, incidentGrid, { label: 'incidents' });
router.subscribe(isIncident, chartGrid, { label: 'incidents-chart' });

// Relations name routes, so either end can live in another window.
router.relate([
  { from: 'incidents', to: 'incidents-chart', on: { from: 'id', to: 'id' }, follow: 'filter' },
]);

// Every window joins the same channel.
router.broadcast({ channel: 'ops-wall', mirror: { state: true } });

// Only the window that holds the feed loads it.
if (isFeedWindow) router.load(rows);

follow: 'filter' makes a target follow the source grid’s filter as well as its selection. mirror: { state: true } carries a grid’s filter, sort and columns to its twin in another window. The pop-out itself is the browser’s own window.open, to the same page with a panel parameter that says which panel to show. Nothing else is involved.

Windows of the same site in the same browser on the same computer share the channel, because it uses the browser’s BroadcastChannel. That is exactly the multi-monitor case.

Dashboards that live on several screens

An operations or NOC wall. The incident grid sits on the desk monitor. The service chart and the status board are on the wall screens. When the on-call engineer filters to one region, all three agree at once, with no one reaching for a refresh button.

A trading or sales desk. Positions go in a grid on one monitor, the exposure chart and key figures on the next. Select a handful of instruments and every screen narrows to them. The desk logs in once and the feed is read once.

A logistics or dispatch control room. Shipments are a grid, jobs by status a Kanban board or a map, and the KPI tiles have a screen of their own. Filter to a depot and the board, the map and the tiles all show that depot.

A support or incident command room. Tickets, the severity chart and an SLA board each get a screen. Pop the SLA board out for the meeting room display, then bring it back when the meeting ends.

In every one of these, the moment that matters is the same: one filter and every screen agrees, one feed and one login, a panel popped out and brought back. What the team does not build is just as useful. There is no second socket or authentication per screen, no code that syncs tabs, and no “refresh the other screen” in the runbook.

Also in this release: a value list in the filter row

In the filter row, the operators Equals, Not equal and Is one of now open a list of the column’s values under the cell. The box names the operator you picked, so you choose from what is in the column instead of typing it from memory.

Try it on two screens

Open the live demo, pop out the chart, drag it to your second screen and type “high” in Severity. The code is on GitHub. The Data Router page covers routes, relations and the feed in full.

Read next

All posts RSS