Angular Chart.js Multiple Canvas

👍:2

You can make use of @ViewChildren to get multiple references of <canvas #pr_chart></canvas> instances. I put together an example showing how to do this using your example from above: https://stackblitz.com/edit/angular-chartjs-multiple-charts.

Essentially I have an array of chart elements on my controller:

chartData: Chart.ChartData[] = [
  {
    labels: ['1500', '1600', '1700', '1750', '1800', '1850', '1900', '1950', '1999', '2050'],
    datasets: [{
      data: [86, 378, 106, 306, 507, 111, 133, 221, 783, 5000],
      borderColor: 'red',
      fill: false
    }]
  },
  {
    labels: ['1500', '1600', '1700', '1750', '1800', '1850', '1900', '1950', '1999', '2050'],
    datasets: [{
      data: [86, 378, 106, 306, 507, 111, 133, 221, 783, 5000].reverse(),
      borderColor: 'blue',
      fill: false
    }]
  }
];

These are used to render multiple charts in my template:

<div *ngFor="let data of chartData" class="chart">
  <canvas #pr_chart></canvas>
</div>

Instead of just grabbing a single reference using @ViewChild, you can grab each of the pr_chart instances using @ViewChildren:

@ViewChildren('pr_chart', { read: ElementRef }) chartElementRefs: QueryList<ElementRef>;

Once we have those references, we can loop through them to create the appropriate chart by using that reference along with the associated data:

ngAfterViewInit() {
  this.charts = this.chartElementRefs.map((chartElementRef, index) => {
    const config = Object.assign({}, baseConfig, { data: this.chartData[index] });

    return new Chart(chartElementRef.nativeElement, config);
  });
}

Since in my example I was going to be duplicating most of the configuration for each of the charts and only the data was changing, I created a base configuration that was shared for each of the charts when rendering it:

const baseConfig: Chart.ChartConfiguration = {
  type: 'line',
  options: {
    responsive: true,
    maintainAspectRatio: false,
    legend: { display: false },
    scales: {
      xAxes: [{ display: false }],
      yAxes: [{ display: false }],
    }
  }
};

Leave a comment