can anyone help me to implement a web worker?
Main Code:
dataset = "dataset" + document.getElementById("dataset").value
const config = {
xAxis: {
type: 'category',
data: Object.keys(window[dataset])
},
yAxis: {
type: 'value'
},
series: [
{
data: Object.values(window[dataset]),
type: 'line'
}
]
};
const offscreenCanvas = document.getElementById("chart-container1");
const worker1 = new Worker('echarts1.worker.js');
worker1.postMessage({ canvas: offscreenCanvas, config }, [offscreenCanvas]);
Web Worker (echarts1.worker.js)
importScripts('https://cdn.jsdelivr.net/npm/[email protected]/dist/echarts.js');
onmessage = function (event) {
console.log("Started Worker");
const { canvas, config } = event.data;
const chart = echarts.init(canvas);
chart.setOption(config);
console.log("Finished Worker");
};
While Executing I'm facing the below error in the console.
You are transferring a (possible) HTMLCanvasElement (<canvas>
), not an OffscreenCanvas.
To get the OffscreenCanvas out of that HTMLCanvasElement, you need to call its .transferControlToOffscreen()
method:
const canvasEl = document.getElementById("chart-container1");
const offscreenCanvas = canvasEl.transferControlToOffscreen();
const worker1 = new Worker('echarts1.worker.js');
worker1.postMessage({ canvas: offscreenCanvas, config }, [offscreenCanvas]);
(If the element with an id ""chart-container1"
isn't a <canvas>
, then you need to target one instead.)
Then, the library you do use isn't meant to work in Web-Workers, yet. There is an open issue on the GH of the project, but I don't see a sign of the devs there. It is apparently possible to make something work though, with minimized features (no mouse events), by making the script think it's in a Window environment.
self.window = self.global = self;
const workerScriptContent = `
importScripts('https://cdn.jsdelivr.net/npm/[email protected]/dist/echarts.js');
// make echarts think it's in a Window env.
self.window = self.global = self;
onmessage = function (event) {
const { canvas, config } = event.data;
const chart = new echarts.init(canvas);
chart.setOption(config);
};
`;
const workerURL = URL.createObjectURL(new Blob([workerScriptContent], { type: "text/javascript" }));
const worker = new Worker(workerURL);
const config = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: 'line'
}
]
};
const canvasEl = document.querySelector("canvas");
const offscreenCanvas = canvasEl.transferControlToOffscreen();
worker.postMessage({ canvas: offscreenCanvas, config }, [offscreenCanvas]);
<canvas height=300 width=800></canvas>
Now, you may also be interested in this package, which I didn't test myself (and I couldn't read all its readme), but it seems like it's doing what you're after and probably handles more edge-cases than this simple workaround.