I used ng2charts module to render charts. If i try with below dummy data, bar chart rendering properly.
Typescript
public barChartOptions: any = {
scaleShowVerticalLines: false,
responsive: true
};
public barChartLabels: string[] = ['Label1', 'Label2', 'Label3'];
public barChartType: string = 'bar';
public barChartLegend: boolean = true;
public barChartData: any[] = [
{ data: [65, 59, 80], label: 'Data1' },
{ data: [28, 48, 40], label: 'Data2' },
{ data: [30, 28, 80], label: 'Data3' }
];
Component Html :
<canvas style="height:230px" baseChart [datasets]="barChartData" [labels]="barChartLabels" [options]="barChartOptions" [legend]="barChartLegend" [chartType]="barChartType" (chartHover)="chartHovered($event)" (chartClick)="chartClicked($event)"></canvas>
But If i tried to get data from server and set data dynamically not working as expected.
I'm Getting below error
HomeComponent.html:73 ERROR TypeError: Cannot read property 'data' of undefined
Please refer my below code.
export class HomeComponent implements OnInit {
serverData: any;
public barChartOptions: any = {
scaleShowVerticalLines: false,
responsive: true
};
public barChartLabels: string[];
public barChartType: string = 'bar';
public barChartLegend: boolean = true;
public barChartData: any[];
constructor(private fb: FormBuilder, private Service: Service,
private route: ActivatedRoute, private router: Router, private _configService: ConfigService) {
this.getApis();
}
ngOnInit() {
const loggedInUser = new LoggedInUser();
const user = loggedInUser.getLoggedUser();
if (user != null) {
this.loggedInUserId = loggedInUser.getLoggedUser().UserId;
}
}
getApis() {
this._configService.get()
.subscribe(c => {
this.apiEndpoints = c;
this.loadDashBoardDetails();
},
error => { this.msg = <any>error; });
}
loadDashBoardDetails() {
this.indLoading = true;
this.Service.get("APIENDPOINT")
.subscribe(c => {
this.serverData = c[0];
this.loadserverData();
this.indLoading = false;
},
error => {
this.msg = <any>error;
}
);
}
loadserverData() {
let chartData: any[];
let data1 = '';
let data2 = '';
let data3 = '';
this.barChartLabels = new Array<string>();
chartData = new Array<any>();
for (let _i = 0; _i < this.serverData.length; _i++) {
this.barChartLabels.push(this.serverData[_i].Code);
if (data1 === '') {
data1 = this.serverData[_i].Target;
} else {
data1 = data1 + ',' + this.serverData[_i].data1;
}
if (data2 === '') {
data2 = this.serverData[_i].data2;
} else {
data2 = data2 + ',' + this.serverData[_i].data2;
}
if (data3 === '') {
data3 = this.serverData[_i].data3;
} else {
data3 = data3 + ',' + this.serverData[_i].data3;
}
}
chartData.push({
data: data1,
label: 'data1 label'
});
chartData.push({
data: data2,
label: 'data2 label'
});
chartData.push({
data: data3,
label: 'data3 label'
});
this.barChartData = chartData;
}
}
You're getting that error because the data is undefined when the chart is rendered. You can avoid this by using *ngIf
on your chart
<canvas
*ngIf="barChartData"
baseChart
style="height:230px"
[datasets]="barChartData"
[labels]="barChartLabels"
[options]="barChartOptions"
[legend]="barChartLegend"
[chartType]="barChartType"
(chartHover)="chartHovered($event)"
(chartClick)="chartClicked($event)">
</canvas>
The above HTML will not be rendered until the data is resolved. Once the data is resovled and barChartData is no longer undefined, the chart will be rendered.
EDIT:
The chart won't rerender if you keep adding data to the barChartData
array. When you get your data, instead of pushing it to the barChartData
array, create a local array to build the data. Then assign the local array to barChartData
when all the data is populated in the local array. Ng2Charts doesn't rerender until the reference to the array changes or you manually call for it to rerender.
EDIT2
Your data also should be of type number
. You have data1 = '';