0

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/echarts@5.3.3/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.

127 0 0 1_5501_echarts html - Google Chrome 8_23_2022 3_52_45 PM (2)

Kaiido
  • 123,334
  • 13
  • 219
  • 285
Yash Chauhan
  • 174
  • 13
  • 1
    Please don't edit your question in a way it invalidates the answer it has received. Moreover if you're going to copy the solutions that are in there and pretend it came from you. – Kaiido Aug 23 '22 at 22:48
  • Apologize, I forgot to add the error image that I was getting while trying to implement with canvas. Appreciate your help man. Have a great day ahead. – Yash Chauhan Aug 24 '22 at 06:58

1 Answers1

1

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/echarts@5.3.3/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.

Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • Nope, it's not working. Uncaught TypeError: canvasEl.transferControlToOffscreen is not a function at wrkButton (echarts.html:96:40) at HTMLButtonElement.onclick (echarts.html:23:33) – Yash Chauhan Aug 23 '22 at 11:25
  • "If the element with an id ""chart-container1" isn't a , then you need to target one instead." – Kaiido Aug 23 '22 at 11:29
  • I already did it. But Still, It's not working. can we connect over LinkedIn? – Yash Chauhan Aug 23 '22 at 11:39
  • Do `console.log(canvasEl)`, what does that output? – Kaiido Aug 23 '22 at 11:56
  • So this is not a element, you need to target a element. If you don't have one in your document, create one. – Kaiido Aug 23 '22 at 12:21
  • I have tried. But it's not working. Console Output: Uncaught ReferenceError: global is not defined at new ECharts (echarts.js:248:28) at new init$1 (echarts.js:2291:15) at onmessage (echarts1.worker.js:6:19) ECharts @ echarts.js:248 init$1 @ echarts.js:2291 onmessage @ echarts1.worker.js:6 – Yash Chauhan Aug 23 '22 at 12:29