i am trying to plot scattergl chart with live data. i am getting the data at speed of around 100ms and the data quantity is around 1000 per traces and i have to show 60 traces for this i have used web workers and promise
web worker code
addEventListener('message', ({ data }) => {
if (data.action === 'updateSpectrogramChart') {
const { frequency, amplitude, maxY } = data;
postMessage(updateSpectrogramChart(frequency, amplitude, maxY));
}
});
function updateSpectrogramChart(frequency, amplitude, maxY) {
const colors = amplitude.map(getColorBasedOnRange);
const traces = [{
x: frequency,
y: Array(frequency.length).fill(maxY),
mode: 'markers',
type: 'scattergl',
marker: {
color: colors,
size: 8,
symbol: 'square',
},
}];
return traces;
}
function getColorBasedOnRange(num) {
if (num === null || num === undefined) {
return 'grey';
}
if (num < -45) return 'indigo';
if (num < -35) return 'blue';
if (num < -25) return 'green';
if (num < -15) return 'yellow';
if (num < -5) return 'orange';
if (num <= Number.POSITIVE_INFINITY) return 'red';
return 'grey';
}
main thread code
plotSpectrogramChart(frequency, amplitude) {
this.spectrogramChart = document.getElementById('spectrogramChart')
Plotly.newPlot(this.spectrogramChart, [], this.getLayout(), { renderer: 'gl' });
this.updateSpectrogramChart(frequency, amplitude);
}
getLayout() {
return {
title: 'Scatter Plot with Colored Data Points',
xaxis: { title: 'Freq. (MHz)' },
yaxis: { showticklabels: false },
showlegend: false,
};
}
async updateSpectrogramChart(frequency, amplitude) {
console.time()
const worker = this.workers[this.workerIndex];
this.workerIndex = (this.workerIndex + 1) % this.numWorkers;
// console.log('worker index', this.workerIndex);
this.dataQueue.push({ worker, frequency, amplitude, maxY: this.maxY++, minY:this.minY++, traceCount: this.traceCount++ }); //worker 1
if (!this.processingData) {
this.processQueue(2);
}
}
async processQueue(batchSize) {
if (this.dataQueue.length > 0) {
this.processingData = true;
const batch = this.dataQueue.splice(0, batchSize);
const batchResults = await Promise.all(
batch.map(({ worker, frequency, amplitude, maxY, minY, traceCount }) =>
this.postMessageToWorker(worker, frequency, amplitude, maxY, minY, traceCount)
)
);
for (const result of batchResults) {
if (result) {
this.handleWorkerResult(result);
}
}
this.processingData = false;
this.processQueue(batchSize);
}
}
postMessageToWorker(worker, frequency, amplitude, maxY, minY, traceCount) {
return new Promise((resolve) => {
worker.postMessage({
action: 'updateSpectrogramChart',
frequency,
amplitude,
maxY
});
worker.onmessage = (event) => {
let data = {
traces: event.data,
maxY,
minY,
traceCount
}
resolve(data);
};
});
}
handleWorkerResult(result) {
if (this.spectrogramChart.data.length > 49) {
Plotly.deleteTraces(this.spectrogramChart, 0);
this.traceCount--;
}
Plotly.addTraces(this.spectrogramChart, result.traces);
Plotly.relayout(this.spectrogramChart, { 'yaxis.range': [result.minY, result.maxY] });
console.timeEnd()
}```