demo D239
Reference lines, targets and bands in htmx
Target and limit lines and a shaded range over a chart, with a mean line read from the data
annotations: [{ kind: 'line', compute: 'mean' }]
This draws target and limit lines and a shaded band over a chart, with a mean line read from the data itself. It puts the goals on the chart, the target to clear and the limit not to cross, so a reader judges results against them without holding the numbers in their head.
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">
<div id="chart" style="height: 360px"></div>
<!-- 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="chart-annotations-table" data-lattice-grid>
<thead>
<tr>
<th data-field="circuit">Circuit</th>
<th data-field="region">Region</th>
<th data-field="status">Status</th>
<th data-field="bandwidth">Bandwidth</th>
<th data-field="charge">Monthly charge</th>
</tr>
</thead>
<tbody>
<tr data-id="0"><td>DFB-EDI-100000</td><td>Edinburgh</td><td>live</td><td>100</td><td>94.88</td></tr>
<tr data-id="1"><td>MPL-BIR-100001</td><td>Birmingham</td><td>provisioning</td><td>10000</td><td>4324.6</td></tr>
<tr data-id="2"><td>DFB-LON-100002</td><td>London</td><td>live</td><td>2000</td><td>1031.02</td></tr>
<!-- the rest of the rows, rendered by your server -->
</tbody>
</table>
<script type="module">
import { hydrateTable } from 'https://cdn.latticegrid.dev/lattice-grid@1.107.0/modules/htmx.esm.min.js';
import { createChart } from 'https://cdn.latticegrid.dev/lattice-grid@1.107.0/modules/charts.esm.min.js';
// 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('chart-annotations-table'), {
columns: [
{ field: 'circuit', title: 'Circuit', layout: { width: 180 } },
{ field: 'region', title: 'Region', filter: { type: 'set' } },
{ field: 'status', title: 'Status', filter: { type: 'set' } },
{ field: 'bandwidth', title: 'Bandwidth', type: 'number' },
{ field: 'charge', title: 'Monthly charge', type: 'number',
format: { style: 'currency', currency: 'GBP' }, total: 'sum' },
],
});
// Reference marks over the chart: a shaded band, a target, and a mean line
// read from the data so it follows the filtered rows.
createChart({
grid,
container: '#chart',
type: 'bar',
x: 'region',
y: { col: 'charge', fn: 'mean' },
annotations: [
{ kind: 'band', from: 900, to: 1300, label: 'Target range' },
{ kind: 'target', value: 1100, label: 'Goal' },
{ kind: 'line', compute: 'mean', label: 'Mean charge' },
],
});
</script>
Marking a chart with the numbers a reader is meant to judge it against
A chart of results is easier to read when the goals are drawn on it: the target to clear, the limit not to cross, the band to stay inside. Without them a reader has to hold those numbers in their head and eye them off the axis. Annotations in any JavaScript charting layer draw those reference marks directly over the plot. In Lattice Grid a chart’s annotations accept reference and target lines, both distinct so a limit does not read as a mere guide, and a shaded band that marks the range between two values, each with its own label. This is the shape a pass-or-fail chart wants: a spec band, a nominal target in the middle, and an upper limit line, all on the same picture as the data.
An annotation can be a number you type or a figure read from the data. A line given compute: 'mean' or a percentile is resolved from the chart’s current rows rather than fixed, so it always marks the mean, or the p95, of what is on screen. Because the chart reads the grid’s filtered rows, filtering the grid moves a computed line to the new mean on the next frame, so the reference stays honest as the data narrows. Every annotation is described in the chart’s text alternative alongside its label, so a reader using assistive technology hears the target and the limit, not just the bars.
How do you draw a target or reference line on a chart?
Pass an annotations array to the chart. Each entry has a kind: a line for a reference, a target for a goal drawn distinctly from a plain reference, or a band with from and to to shade a range. Give a fixed line a value, or give it compute: 'mean' or a percentile to read the figure from the data so it follows the filtered rows.
Can an annotation follow the data instead of being a fixed number?
Yes. An annotation with compute set to a statistic such as the mean or a percentile resolves against the chart’s current rows rather than a value you type. Because the chart draws from the grid’s filtered rows, the line moves to the new figure whenever the grid is filtered, so it always marks the mean, or the percentile, of what the reader is actually looking at.