As I'm integrating uPlot into my uibuilder+vue+vuetify dashboard I'm wondering about how to send and cache the data. The basic way I'm sending data is to use messages that have a topic and a payload and then I have a
nr data field in the main Vue object that is updated using
this.nr[msg.topic] = msg.payload. This triggers the reactivity making it such that components that are bound to
this.nr[msg.topic] get updated/notified (see also Uibuilder: to subscribe or not to subscribe? - #48 by tve).
When it comes to streaming data, primarily for a chart, the data consists of all the data points. So for the sake of example, I may have a temperature chart whose data input is bound to
this.nr["temperature_chart_data"]. Now, I can send the whole data set being shown in a message, and that works, but when streaming data in real-time it's a waste to send potentially thousands of data points when all that has changed is that a new value got appended and perhaps the oldest value should be dropped.
What I'm considering is to support a
msg.operation field with the following choices:
- null or undefined: standard replace, i.e.
nr[topic] = payload
nr[topic].shift(); if (payload !== undefined) nr[topic].push(payload)
This is a bit complicated by the fact that the data for uPlot is in columnar form, so for example, if I have two time series then
data.length == 3 where
data is an array of time values,
data is an array of Y values for the first series, and
data is an array of Y values for the second series. This means that to append a value one can't just append one element to the data array. So maybe I need something like:
- "append_tr": transpose and append such that
payload: [ <timestamp>, <y1>, <y2> ]does the right thing to append to the data
None of this seems super-complicated, but I wonder whether there's a better way to skin this cat...