Working on an Angular 6 Project, I have a Component that receives a tile Object from its parent. The goal is to generate a Chart using chart.js for each passed tile. The issue is that only the first Chart gets rendered successfully, while the rest fail with the following console Error Code:
Failed to create chart: can't acquire context from the given item
Here is a snippet of my tile.component.html:
<div *ngIf="tile.type === 'tileImg'">
<div class="card custom-card"
routerLinkActive="glowing">
<img class="card-img-top rounded" src="{{ tile.imgPath }}" alt="Tile image" />
<div class="card-body">
<p class=" card-text text-center">{{ tile.name }}</p>
</div>
</div>
</div>
<div *ngIf="tile.type === 'tileChart'">
<div class="card custom-card"
routerLinkActive="glowing">
<div>
<canvas id="canvas">{{ chart }}</canvas>
</div>
<div class="card-body">
<p class=" card-text text-center">{{ tile.name }}</p>
</div>
</div>
</div>
Additionally, in my tile.component.ts file:
import { Component, OnInit, Input } from '@angular/core';
import { Chart } from 'chart.js';
import { Tile } from 'src/app/tile-container/tile/tile.model';
@Component({
selector: 'app-tile',
templateUrl: './tile.component.html',
styleUrls: ['./tile.component.css']
})
export class TileComponent implements OnInit {
@Input() tile: Tile;
chart = [];
constructor() { }
ngOnInit() {
if (this.tile.getType() == 'tileChart') {
this.generateChart(this.tile.getChartType(), this.tile.getChartData());
}
}
generateChart(chartType: string, chartData: number[]) {
this.chart = new Chart('canvas', {
type: chartType,
data: {
datasets: [{
data: chartData,
backgroundColor: ['#F39E01', '#b8bbc1']
}],
labels: ['Verbrauch diese Woche', 'Einsparung in kWh']
},
options: {
legend: {
display: false,
},
rotation: 1.1 * Math.PI,
circumference: 0.8 * Math.PI
}
});
}
}
As an example, the parent tile-container.component.html looks like:
<div class="container custom-container">
<div class="container-heading">
<h2>{{ tileContainer.name }}</h2>
</div>
<hr />
<div class="row">
<div class="col text-center"
*ngFor="let tile of tileContainer.tiles">
<app-tile
[tile]="tile">
</app-tile>
</div>
</div>
</div>
Take a look at the Screnshot from missing charts for reference.
EDIT
I've made some edits to my typescript code by introducing a unique id for each chart created:
ngOnInit() {
console.log(this.tile.id);
if (this.tile.getType() == 'tileChart') {
this.chartId = this.tile.id.toString();
this.ctx = document.getElementById(this.chartId);
console.log(this.ctx);
this.generateChart(this.tile.getChartType(), this.tile.getChartData());
}
}
Utilizing data binding in the following html:
<div>
<p>{{ chartId }}</p>
<canvas id="{{ chartId }}">{{ chart }}</canvas>
</div>
Check out the Picture of error codes for more details.