I’d like to have objects added to an array in a component each time a subscribed store gets updated. In this case, the store is receiving data from a WebSocket, and I ultimately want to plot the last N
datapoints that I’ve received (N=1000
for example).
The store is defined in socket.js
:
import { readable } from 'svelte/store'; export const datastream = readable([], set => { let socket = new WebSocket("ws://localhost:8765") let data = []; socket.onmessage = function (event) { let { time, value } = JSON.parse(event.data); // update the data array // TODO: set a max buffer size data = [...data, {"time": time, "value": value}]; // set the new data as store value set(data) } })
I then have a Chart.svelte
component which should a) plot the last N
points (implementation not shown), b) update each time my store subscription callback occurs. The catch here is that I may need to do some minor conversion/preprocessing on the incoming WebSocket data. In my Chart.svelte
we have (omitted the plotting stuff for brevity):
<script> ... import { datastream } from './socket.js'; export let plot_data; const unsubscribe = datastream.subscribe(data => { plot_data = [] for (let datum of data) { plot_data = [...plot_data, {x: datum.time, y: datum.value}] } }); $: {... some stuff that sets up plotting ...} </script> <div class='my-chart'> ...(plot_data) </div>
My question is; is this the best way to do this? I think it’s not – It works, but I’ve got a duplicate of the array of data in the datastream
store, and each time I get a new value, I completely rebuild the plot_data
array.
I had attempted to do this with only the most recent data point subscribed in the store, but I couldn’t figure out how to capture the store update and thereby force a new entry into the plot_data
array (and thus, refresh the plot).
Advertisement
Answer
Is this what you are looking for:
See this repl: receive updates in batches
But use this store for your use:
let socket = new WebSocket("ws://localhost:8765") const datastream = readable(null, set => { socket.onmessage = function (event) { set ({ time, value } = JSON.parse(event.data)); }; });