demo D300
The health of the rows you are looking at
A grid of hosts with a health rail beside it reading the very same rows: readings grouped under headings that collapse, a heading carrying the worst state beneath it, and every figure moving the moment you narrow the grid
createKPI(el, { grid, tree })
One set of rows, two ways of reading it: the grid holds the fleet, and the rail beside it is the health of those very rows. Narrow the grid to a region, or to something with no hosts in it at all, and every reading moves with it.
The figures are of the rows in front of you
The usual dashboard keeps its figures apart from its data. One query fills the table, another fills the summary, and the two agree only until somebody touches a filter. Narrow the table to one region and the numbers beside it are still answering a question about a set that is no longer on screen, which is how a green dashboard ends up sitting next to a screen full of trouble.
Here they are one thing. The rail reads the grid, so it is not a second copy of the data with its own arithmetic, it is the same rows counted a different way. Narrow the grid to a region, or set a filter from the grid’s own menus, and every reading in the rail recomputes over exactly what is left. Edit a processor figure in the grid, which you can do in place, and the rail moves as you commit it. There is nothing to keep in step because there is only one set of rows.
That is worth more than it sounds. It means the summary cannot quietly go stale, it means a figure and the rows behind it can always be reconciled by eye, and it means the same feed that fills your grid fills the health of it for free.
Readings grouped under headings, and a heading that knows
A dozen readings need structure, so they sit under headings you can open and close. Every heading carries the worst state anywhere beneath it, however deep the branch runs. Collapse the rail and Compute still reads critical, because one processor is running at ninety four per cent underneath it: nothing red is on the screen, and the screen tells you something is wrong anyway. That is the part a folded-away figure usually gets wrong, and it is why folding them away is safe here.
Give a number the point where it stops being fine and the point where it becomes serious, and say which way is better, and the tile grades itself. Push the busiest processor through its bands with the buttons and watch the heading above it change without being opened.
What rolls up is the state, not the number. A heading shows how things are, not a total: adding up an average, a maximum and a running count would produce a figure that is right for one of them and wrong for the others, and a wrong number on a status board is worse than no number at all.
A figure with nothing behind it is not a healthy figure
Filter the grid to the hosts in maintenance. There are none today, so the grid empties, and every reading in the rail says it was not measured rather than reporting zero.
That distinction is the whole reason to trust the thing. Over no rows a count and a sum both come back a real zero, and zero is comfortably inside every warning line you would set for dropped packets or retries. A rail without this state would go quietly, confidently green for a fleet it could not see, which is the exact moment you most need it not to. Silence gets its own answer, each heading counts how many of its readings are in it, and it never wins the ranking either, so a real warning is never buried under a metric that simply went quiet.
The rail is a proper tree for anyone not using a mouse. Arrow keys open a shut branch, close an open one, walk what is on screen and step out to the parent; each state is a shape as well as a colour; and a heading reads its own summary aloud, worst state and all, so a screen reader never has to count what a shut branch left out.
How do I show the health of a grid’s rows beside it?
Load the KPI module and call createKPI(element, { grid, tiles }), handing it the grid itself rather than a copy of the rows, so the panel reads whatever the grid is showing. Each tile names an aggregation, the field it reads, and thresholds with warn, critical and a direction of lowerIsBetter or higherIsBetter. Add tree to group them: tree: { path } reads each tile’s own place as a list, outermost first, tree: { parentKey } points a tile at the one above it, and ids that carry a dot build the same shape with no tree block at all. Set tree: { expanded: true } to open on arrival. A grid-bound panel takes its rows when it is built, so call refresh() from the grid’s own filter:changed and rows:changed events and the rail follows every narrowing the visitor makes. expand, collapse and nodes() drive and read the rail from your own code.