ng2-charts: Updating lineChartLabels does not reflect on the chart

Hi, I’m unable to update labels of a chart. I’m using ng2-charts. On the line chart example here, labels are defined with this line: public lineChartLabels:Array<any> = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; After this line executed I’m changing the value of lineChartLabels with 7 different strings but I can not see any changes on the chart. Do you have any idea?

You can see the problem on this line: https://github.com/mertyildiran/Tower/blob/67d7c7dabfd7a4eafd4202aebdab7ac10cdfce87/src/app/home/home.component.ts#L81

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 18 (1 by maintainers)

Most upvoted comments

Apparently, if you do not modify the original reference to the labels array, it seems to work, at least for me. I mean, if you want a completely different set of labels, you should do something like this:

In the template:

<canvas baseChart
  [datasets]="lineChartData"
  [labels]="lineChartLabels"
  [options]="lineChartOptions"
  [chartType]="'line'"></canvas>

In the ts component:

this.lineChartLabels.length = 0;
for (let i = tempLabels.length - 1; i >= 0; i--) {
  this.lineChartLabels.push(tempLabels[i]);
}

The key is maybe the this.lineChartLabels.length = 0; statement, which practically ‘empties’ your array by setting its length to 0, without modifying the reference. Hope this helps!

This answer is explaining everything. Here is the summary:

Apparently, Angular2 is unable to detect the label changes so you need to update them manually. First, make sure you have imported ViewChild from @angular/core:

import { Component, OnInit, ViewChild } from '@angular/core';

Then import BaseChartDirective:

import { BaseChartDirective } from 'ng2-charts/ng2-charts';

Get the first chart with (I don’t know what to do if you need to handle multiple charts):

export class HomeComponent implements OnInit {
    @ViewChild(BaseChartDirective) chart: BaseChartDirective;
    ...

Lastly, update the labels manually with:

this.chart.chart.config.data.labels = this.lineChartLabels;

Now you should be able to see the new labels on your chart.

I think this issue still needs to fixed.

Getting multiple charts

First import ViewChildren, QueryList and BaseChartDirective with:

import { Component, OnInit, ViewChildren, ElementRef, QueryList, AfterViewInit } from '@angular/core';
import { BaseChartDirective } from 'ng2-charts/ng2-charts';

Now get the all charts available on the page as a QueryList:

export class HomeComponent implements OnInit, AfterViewInit {
    @ViewChildren(BaseChartDirective) charts: QueryList<BaseChartDirective>;

You cannot use charts[0] on QueryLists so you need to iterate using forEach:

    ngAfterViewInit() {
        this.parseCharts();
        this.loadChart1();
        this.loadChart2();
    }

    parseCharts() {
        this.charts.forEach((child) => {
            this.chart.push(child);
        });
        //console.log(this.chart[0]);
    }

ngAfterViewInit() is the most suitable [lifecycle hook] for parsing/extracting charts from the QueryList. constructor() or ngOnInit() is too early to parse them. After parsing you can use the charts with chart[n] respective to DOM order.

How i resolve the problem is like below.

@ViewChildren(BaseChartDirective) charts: QueryList<BaseChartDirective>;

` this.reportService.getUserSales(startDateString, endDateString).subscribe(t => {

  this.userSaleReponse = t.Data;
  let labels = this.userSaleReponse.map(function (a) { return a.Name; });
  this.userPieLabels = labels;
  let pieData = this.userSaleReponse.map(function (a) { return a.Total; });
  this.userSaleData = pieData;
  this.charts.forEach((child) => {
    if (child.chartType == 'pie') {
      child.labels.splice(0);
      child.labels = labels;
    }
    child.ngOnChanges({} as SimpleChanges);
  });
});

` I have multiple charts on html side, one is line chart another is pie chart. LineChart works well when I remove the previous array with splice(0) and add items by push. It detects change automatically. But pie chart doesn’t work like that. So that I have added QueryList<BaseChartDirective> that gets all basechart directives. After the data comes from server, it is organized and then iterates over charts to find the pie chart (which is hacky a bit because if there is more than one pie chart this will fail) and then call the ngOnChanges to invoke detecting changes on piechart.