demo D36
Win-loss, gauge, range in htmx
The compact chart set for KPI grids
render: 'winloss' | 'gauge' | 'range'
This grid shows the compact chart set built for KPI columns: a win-loss strip, a gauge against a target, and a range marker. It fits a small visual signal into a normal row, where a full chart would take more space than the metric deserves.
This is the htmx version. A server-rendered table is upgraded in place, so the page is readable before any script runs and gains the full grid when the module loads, which suits a progressively enhanced app.
The configuration
<link rel="stylesheet" href="https://cdn.latticegrid.dev/lattice-grid@1.107.0/lattice-grid.min.css">
<!-- A real, server-rendered table: readable with JavaScript off. data-field on
each header names the column that cell becomes, and data-id on each row is
the key the grid carries it under. -->
<table id="winloss-gauge-range-table" data-lattice-grid>
<thead>
<tr>
<th data-field="service">Service</th>
<th data-field="team">Team</th>
<th data-field="streak">Last 14 days</th>
<th data-field="utilisation">Utilisation</th>
<th data-field="spread">Latency spread</th>
</tr>
</thead>
<tbody>
<tr data-id="0"><td>fraud-edge</td><td>Commerce</td><td>[1,-1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1]</td><td>27</td><td>[283,222,199,232,269,257,287,303,393]</td></tr>
<tr data-id="1"><td>payments-stream</td><td>Growth</td><td>[1,1,-1,-1,1,1,-1,-1,-1,1,1,1,-1,-1]</td><td>74</td><td>[172,198,164,171,155,162,189,221,272]</td></tr>
<tr data-id="2"><td>checkout-edge</td><td>Payments</td><td>[-1,-1,-1,-1,-1,1,-1,-1,-1,-1,1,1,-1,-1]</td><td>54</td><td>[87,63,65,75,89,68,58,59,41]</td></tr>
<!-- the rest of the rows, rendered by your server -->
</tbody>
</table>
<script type="module">
import { readTable, hydrateTable } from 'https://cdn.latticegrid.dev/lattice-grid@1.107.0/modules/htmx.esm.min.js';
// A table cell carries text, so the columns whose values are whole objects
// travel as JSON and are read back here. Everything else
// arrives as the number, boolean or string it already looks like.
const rows = readTable(document.getElementById('winloss-gauge-range-table')).rows.map((row) => ({
...row,
streak: JSON.parse(row.streak),
spread: JSON.parse(row.spread),
}));
// The markup carries the rows; a server-rendered table's column types are
// declared in the config hydrateTable takes. The grid replaces the table
// where it stood.
const grid = hydrateTable(document.getElementById('winloss-gauge-range-table'), {
selection: 'multiple',
toolPanel: {
side: 'left',
panels: ['columns', 'filters', 'views', 'quick'],
actions: ['undo', 'redo', 'export', 'restore', 'maximise'],
exportName: 'lattice-demo',
},
columns: [
{ field: 'service', title: 'Service', layout: { pin: 'start', width: 170 } },
{ field: 'team', title: 'Team', filter: { type: 'set' } },
// Every mark the same height: the question a win/loss strip answers is
// how often, never how much.
{ id: 'streak-last-14-days', field: 'streak', title: 'Last 14 days', layout: { width: 190 },
sort: { enabled: false }, filter: { enabled: false }, cell: { render: 'winloss' } },
{ field: 'utilisation', title: 'Utilisation', type: 'number', layout: { width: 140 },
format: { suffix: '%' }, cell: { render: 'gauge', props: { min: 0, max: 100 } } },
// Nine readings drawn as a span with the middle marked, against a
// pinned scale so the widest row is visibly the widest.
{ id: 'spread-latency-spread', field: 'spread', title: 'Latency spread', layout: { width: 220 },
sort: { enabled: false }, filter: { enabled: false }, cell: { render: 'range', props: { min: 0, max: 1200 } } },
{ field: 'status', title: 'Status', layout: { width: 130 },
cell: { render: 'pill', props: { variant: {
map: { healthy: 'success', degraded: 'warning', failing: 'danger' },
default: 'neutral',
} } } },
],
rows,
});
</script>
Win-loss, gauge and range charts for compact KPI columns
Win-loss, gauge and range are three small chart types for a column of key performance figures, where a full chart would take more space than the metric deserves. A win-loss strip shows a run of wins and losses as a row of ticks, a gauge shows a single value against a minimum and maximum as an arc or dial, and a range shows a value’s position between a low and high bound as a bar. A developer reaches for these where a KPI grid needs to show, at a glance, whether a value is on target or trending well, across dozens of rows, without a dedicated chart panel per row. Lattice Grid selects the type with the render option, set to 'winloss', 'gauge' or 'range', so a column of quarterly targets can switch from a range bar to a gauge dial by changing one string on the column definition, with the value, minimum and maximum read from the row data. Each chart draws to a small canvas sized to the cell, and only cells for rows currently on screen are drawn, so a JavaScript data grid with several such columns keeps its scroll performance on a sheet of ten thousand rows. Colour thresholds are set once per column, so a gauge or range column stays consistent across every row without per-cell styling.
What is a gauge chart in a data grid column?
A gauge chart in a grid column draws a single value as an arc or dial against a set minimum and maximum, inside one cell, so a reader can judge at a glance whether a figure such as capacity used or a score achieved sits low, mid or high on its scale. In Lattice Grid, set render: 'gauge' on a column definition and supply the value, min and max from the row data; the grid draws the dial to a small canvas sized to the cell for each visible row.