andresmonc
andresmonc

Reputation: 478

Angular Chart.JS Only One Canvas Rendering

I created a bar chart component and this is working fine. However I run into problems when trying to display multiple charts with the same component. I'm generating "tiles" dynamically through an ngFor and inside each tile there's a component. The issue is that only the first tile is generating a chart and the rest of the tiles are not. Apologies in advance if I did not provide enough information just let me know and I'll provide more.

ngFor

<div *ngFor="let productLevel of productLevels" class="col-xl-2 col-lg-3 col-md-3 col-sm-4 col-6" align="center">
   <app-health-tile [routerLink]="['/details/',group,productLevel.plId]" [title]="productLevel.plId" [up]="productLevel.up" [warning]="productLevel.warning" [down]="productLevel.down"></app-health-tile>
</div>

health-tile.component.ts

<div id="tile" [ngClass]="{'error': error, 'warning': issue, 'healthy': healthy}" align="left">
    <div>{{title}}</div>
    <app-barchart></app-barchart>
    <div id="counter">
        {{up}} <i class="fa fa-long-arrow-up" aria-hidden="true"></i>
        {{warning}} <i class="fa fa-exclamation" aria-hidden="true"></i>
        {{down}} <i class="fa fa-long-arrow-down" aria-hidden="true"></i>
    </div>
</div>

barchart.component.ts

import { Component, OnInit } from '@angular/core';
import { Chart } from 'chart.js';

@Component({
  selector: 'app-barchart',
  templateUrl: './barchart.component.html',
  styleUrls: ['./barchart.component.css']
})
export class BarchartComponent implements OnInit {
  barChart = [];

  constructor() { }


  ngOnInit(): void {
    this.barChart = new Chart('canvas', {
      type: 'bar',
      data: {
        backgroundColor: "#FFFFFF",
        labels: ['4H', '4L', 'Close'],
        datasets: [{
          label: '# of Inc.',
          data: [2,3,1],
          borderColor: '#FFFFFF',
          backgroundColor: "#FFFFFF",
        }]
      },
      options: {
        maintainAspectRatio: false,
        legend: {
          display: false
        },
        scales: {
          xAxes: [{
            display: true,
            gridLines: {
              // display: false,
              drawOnChartArea: false,
              zeroLineColor: '#FFFFFF',
              color: '#FFFFFF',
              fontStyle: "bold",
            },
            ticks: {
              fontColor: '#FFFFFF',
              fontFamily: 'Lato',
              fontStyle: "bold",
              precision:0
            },
          }],
          yAxes: [{
            display: true,
            gridLines: {
              drawOnChartArea: false,
              zeroLineColor: '#FFFFFF',
              color: '#FFFFFF',
              fontStyle: "bold",
            },
            ticks: {
              fontColor: '#FFFFFF',
              fontFamily: 'Lato',
              fontStyle: "bold",
              precision:0
            },
          }],
        }
      }
    });
  }

}

Upvotes: 0

Views: 1340

Answers (1)

Suraj Gupta
Suraj Gupta

Reputation: 465

Problem was with your canvas id, you should pass dynamic ids to your chart.

For example:

You have to pass dynamic ids from your component to the canvas.

and you have instantiate your Chart in ngAfterViewInit ie. after View gets initialized.

Your chart template should be like this:

<div class="chart-container">    
    <canvas [id]="chartId" >{{ barChart }}</canvas>    
  </div>
  barchart test

and in your component it should be like this:

export class BarchartComponent implements OnInit {
  @Input() chartId:string;
  barChart = [];
  constructor(
  ) { }

  ngOnInit(): void {
    setTimeout(() => {
      this.barChart = new Chart(this.chartId, {
      type: 'bar',
      data: {
        backgroundColor: "#000000",
        labels: ['4H', '4L', 'Close'],
        datasets: [{
          label: '# of Inc.',
          data: [2,3,1],
          borderColor: '#000000',
          backgroundColor: "#000000",
        }]
      },
      options: {
        maintainAspectRatio: false,
        legend: {
          display: false
        },
        scales: {
          xAxes: [{
            display: true,
            gridLines: {
              // display: false,
              drawOnChartArea: false,
              zeroLineColor: '#000000',
              color: '#000000',
              fontStyle: "bold",
            },
            ticks: {
              fontColor: '#000000',
              fontFamily: 'Lato',
              fontStyle: "bold",
              precision:0
            },
          }],
          yAxes: [{
            display: true,
            gridLines: {
              drawOnChartArea: false,
              zeroLineColor: '#000000',
              color: '#000000',
              fontStyle: "bold",
            },
            ticks: {
              fontColor: '#000000',
              fontFamily: 'Lato',
              fontStyle: "bold",
              precision:0
            },
          }],
        }
      }
    }, 100);
    })
  
  }

}

Here is the working demo for the same. demo

Upvotes: 2

Related Questions