I have three charts to display for three different services. SO creating array of charts and pushing each newly created chart.
Here is my code.

      import Chart from 'chart.js;
      public charts: any;
      canvas: any;
      ctx: any;

      this.canvas = document.getElementById(serviceChart) as HTMLCanvasElement;
      this.ctx = this.canvas.getContext('2d');
        
    
      this.charts.push(new Chart(this.ctx, {
            // The type of chart we want to create
            type: 'bar',
            // The data for our dataset
            data: barChartDataCollection,
            // Configuration options go here
            options: this.barChartOptions
        }));

I am getting Canvas is already in use. Chart with ID '0' must be destroyed before the canvas with ID 'idpService' can be reused. error while creating new chart and pushing into array. Do i need to destroy each chart after creating it? If yes, How? and where to destroy it? If not, then what is the solution? Please help!

The data which I am getting from api is:

[ { "timestamp": ":2023-04-18", "status": null, "majorVersion": "0", "minorVersion": "74", "statusCodes": [], "receivedPackets": 8640, "expectedPackets": 8640, "received": 100, "lost": 0 }, { "timestamp": ":2023-04-20", "status": null, "majorVersion": "0", "minorVersion": "74", "statusCodes": [], "receivedPackets": 8639, "expectedPackets": 8640, "received": 99, "lost": 1 }, { "timestamp": ":2023-04-24", "status": null, "majorVersion": "0", "minorVersion": "74", "statusCodes": [], "receivedPackets": 8601, "expectedPackets": 8640, "received": 99, "lost": 1 }, { "timestamp": ":2023-05-11", "status": null, "majorVersion": "0", "minorVersion": "78", "statusCodes": [], "receivedPackets": 8639, "expectedPackets": 8640, "received": 99, "lost": 1 } ]

2

There are 2 best solutions below

0
xoxo On BEST ANSWER

Finally I found an answer.

I needed to initialize the ctx this way:

  let ctx: CanvasRenderingContext2D = canvas.getContext("2d")!; // <--

Now I am able to display all the charts in parallel.

6
kikon On

If you don't want to see the charts in parallel you can simply destroy the current/topmost chart:

(this.charts[this.charts.length - 1] as Chart|undefined)?.destroy();

this.charts.push(new Chart( ......

If you are willing to destroy the chart object, then it makes little sense to keep all charts in an array, it would suffice to keep only the current chart object.

Also, in this case, of sequential charts, it is almost always possible and simpler to just change the data and options of the current chart and call its .update() method to display the next one, so you don't destroy and recreate it.

Another option is to create a new canvas for each chart, that would allow the charts to be displayed in parallel. A simplified version would be

const serviceCanvas = document.getElementById('serviceChart') as HTMLCanvas;
if(this.charts.length > 0){
   this.canvas = document.createElement('canvas');
   serviceCanvas.parentNode!.appendChild(this.canvas);
}
else{
    this.canvas = serviceCanvas;
}