Search code examples
angulartypescriptchart.jsngfor

Chart.js:9352 Failed to create chart. Unable to dynamically create charts


Hi I'm coming up to this error when trying to dynamically create some charts in my angular project.

Chart.js:9352 Failed to create chart: can't acquire context from the given item

export class StudentStudyProgressComponent implements OnInit {
  charts = [];
  semesters = [1, 2, 3, 4, 5, 6];

  constructor(private logic: LogicService) {
  }

  ngOnInit() {
    this.makeDetailCharts(this.semesters);
  }

  private makeDetailCharts(semesters: number[]) {
  semesters.forEach((semester)=>{

   this.charts.push(
    new Chart('chartStudyProgress' + semester, {
      type: 'doughnut',
      data: {
        labels: ['Geslaagd', 'Opgenomen', 'Resterend'],
        datasets: [
          {
            data: this.logic.giveStudyProgressForSemester(this.student.Curriculum, semester),
            borderColor: "#3cba9f",
            backgroundColor: [
              ('#66B266'),
              ('#FFFF66'),
              ('#FF7F7F')
            ]
          }
        ]
      },
      options: {
        title: {
          display: true,
          text: 'Semester '+semester
        },
        legend: {
          display: false
        },
      }
    })
   );
  });
 }
}

I think the problem occurs when I want to dynamically create the charts in my html:

 <div class="row" *ngFor="let semester of semesters">
  <div class="col-4">
   <div [hidden]="!charts">
    <canvas id="{{'chartStudyProgress'+semester}}" style="max-width: 30%;">{{ charts[semester] }}</canvas>
   </div>
  </div>
 </div>

If I declare the charts statically it works:

<div class="row" >
 <div class="col-4">
  <div [hidden]="!charts">
   <canvas id="chartStudyProgress1" style="max-width: 30%;">{{ charts[1] }}</canvas>
   <canvas id="chartStudyProgress2" style="max-width: 30%;">{{ charts[2] }}</canvas>
   <canvas id="chartStudyProgress3" style="max-width: 30%;">{{ charts[3] }}</canvas>
   <canvas id="chartStudyProgress4" style="max-width: 30%;">{{ charts[4] }}</canvas>
   <canvas id="chartStudyProgress5" style="max-width: 30%;">{{ charts[5] }}</canvas>
   <canvas id="chartStudyProgress6" style="max-width: 30%;">{{ charts[6] }}</canvas>
  </div>
 </div>
</div>

Is there an expert who can help me create my charts dynamically?


Solution

  • You are trying to get canvases before they are created in the view. Use ngAfterViewInit instead of ngOnInit:

    ngAfterViewInit() {
      this.makeDetailCharts(this.semesters);
    }