Time series
The time-series explorer draws millions of points — sensor readings, energy meters, application metrics, prices, lab instruments — in stacked panes, each with a left and a right axis, as lines, areas, steps or points. Points too close to tell apart are thinned to the first, lowest, highest and last in each pixel column, so a million points redraw in a few milliseconds and every spike still shows.
Drag to move, Shift and drag to zoom to a range, Ctrl and the wheel or a pinch to zoom; an overview underneath and quick ranges. Thresholds as lines and bands, events as flags and spans, anomalies marked, the same window a day, week or year earlier drawn behind. Live data follows the newest point. A cursor reads every series at once and a table always gives the window's figures. PNG and CSV out.
A year of a compressor
A year of readings from one compressor, about 1.2 million points: vibration and power every minute, temperatures every five and fifteen minutes. Shifts and weekends, a Christmas shutdown, the bearing wearing until it was replaced, and a sensor outage that shows as a gap.
Get the code
<script src="/assets/bmx-components.min.js"></script>
<bmx-timeseries id="ts-compressor" label="Compressor C-3, Riverside plant" zone="Europe/London" presets="1h,1d,7d,30d,all" style="inline-size: 100%"></bmx-timeseries>
<script>
const timeseries = document.getElementById('ts-compressor');
timeseries.events = [ /* your events */ ];
timeseries.series = [ /* your series */ ];
</script>
This week against last
An office building's electricity every fifteen minutes for five weeks, last week drawn faintly behind this one, with the supply's capacity as a band. Anomalies are marked: the heating left on one Saturday stands out from every ordinary morning.
Get the code
<script src="/assets/bmx-components.min.js"></script>
<bmx-timeseries id="ts-building" label="Harbour House, electricity" zone="Europe/London" presets="1d,7d,all" compare="week" anomalies style="inline-size: 100%"></bmx-timeseries>
<script>
const timeseries = document.getElementById('ts-building');
timeseries.events = [ /* your events */ ];
timeseries.series = [ /* your series */ ];
</script>
Live from a meter
A reading a second, as a page would receive them over a WebSocket. The window follows the newest point and the last fifteen minutes are kept; drag back to look at something and following stops until you choose the newest again.
// Node 18 or later, or a Web Worker: the engine, from the Gold package.
import { seriesFromCsv, storeOf, findAnomalies, resample } from './dist/node/bmx-timeseries.mjs';
const { series } = seriesFromCsv(await readFile('meter-export.csv', 'utf8'));
for (const s of series) {
const store = storeOf(s);
const [first, last] = store.extent();
const spikes = findAnomalies(store, { window: 96, threshold: 5 });
const hourly = resample(store, first, last, 3_600_000, 'mean');
await saveHourly(s.id, hourly);
if (spikes.length) await raiseTicket(s.id, spikes);
}