Live streams
Local streams
Feed live samples from your own page into the engine.
Open, push, close
const stream = engine.live.openLocal('Line 3 press')
socket.onmessage = (msg) => {
const s = JSON.parse(msg.data)
stream.push({
t: s.time, // any monotonic number: seconds, ms, sample index
signals: [
{ name: 'force', unit: 'kN', value: s.force },
{ name: 'stroke', unit: 'mm', value: s.stroke },
],
})
}
// Later
stream.close()pushtakes one sample or an array of them.- New signal names become new columns automatically.
- After
close(),pushis ignored and the connection leavesstate.live.
High sample rates
At kHz rates, push blocks by column instead of one object per sample. Typed arrays are copied into the buffer in bulk: millions of samples per second, with the charts still drawing every frame.
// One block per message from your source: t and every signal the same length
stream.pushColumns({
t: times, // Float64Array (or any array of numbers)
columns: { force: force, stroke: stroke },
units: { force: 'kN', stroke: 'mm' },
})- A signal missing from a block reads as a gap for its samples.
- A column whose length differs from
tthrows aRangeError.
Plotting it
The stream appears in state.live (its id is stream.id) and is selected when it first appears, so every chart plots it. If a worksheet’s X column does not exist in the live data, the worksheet switches to t. Multi-band charts on t scroll with a window you set:
engine.view.setLiveWindow(30) // seconds; null shows everything buffered
engine.datasets.toggle(stream.id) // hide or show it like any dataset
engine.live.rowCount(stream.id) // samples buffered now (cheap: poll it for a counter)state.live[i].rowCount only updates on structural changes (a new signal, a status change); use live.rowCount() for a ticking counter.