Ng2-charts: Labels not updating when dynamically trying to change them

Created on 21 Mar 2017  路  15Comments  路  Source: valor-software/ng2-charts

I'm using ng2-charts and I'm trying to build support for drilling down into a chart. It shouldn't be hard, just a matter of handling the click event, then changing the labels and the data and I should be pretty much done. But for some reason, the labels aren't updating properly. Check out this plnkr: http://plnkr.co/edit/YPYdegwj3yLnS42Kbisd?p=preview

When you click 2006 and then click January, everything still functions. I'm only changing the labels at this point, not the data. As soon as I do change the data, things get weird. Near the bottom of src/app.ts, there's this piece of code:

// setTimeout(() => {
//  this.barChartData = this.currentNode.bars; // uncomment this first
// }, 0)

Uncomment the second line so that the data is changed and try drilling down into 2006/January again. When clicking 2006, the labels don't get updated. Now uncomment the rest of the setTimeout() and you'll notice that everything works as it should: labels updating, data updating. Beautiful.

But this setTimeout() really should not be necessary. Since it has to do with databinding, I suspect this is an ng2-charts bug and not a chart.js bug.

Most helpful comment

here is another work around that works on my end just add a condition on the canvas wrapper element
*ngIf="lineChartLabels.length > 0" to redraw the chart.

                  <div class="chart" *ngIf="lineChartLabels.length > 0">
                    <canvas baseChart height="114"
                            [datasets]="lineChartData"
                            [labels]="lineChartLabels"
                            [options]="chartOptions"
                            [chartType]="lineChartType"
                            [colors]="lineChartColors">
                    </canvas>
                  </div>

All 15 comments

This appears to be the same issue as encountered with #291, #424, and #630. The error here is 'Label' undefined not 'Data' undefined, but seems to be the same issue: setTimeout() shouldn't be necessary, no doubt, but it's one of the workarounds you can use that are necessary to update the chart. @ViewChild seems to be the most stable and least "hacky" way to fix these issues.

I have a similar issue.

I am getting labels and data from the backend, but only the data is dynamically updated. I am doing this in my subscribe:

let stats = response.data;
let labels = [];
let values = [];
let index = 0;
for(let i in stats){
        labels[index] = 'Week ' + stats[i].week;
    values[index] = stats[i].deviationCount;
    index++;
}
this.chartConfig.data.datasets = [{ data: values }];
this.chartConfig.labels = labels;

I am using one of the example line charts and using some of its default values.

<div style="display: block;">
    <canvas baseChart width="400" height="400"
                [datasets]="chartConfig.data.datasets"
                [labels]="chartConfig.labels"
                [options]="chartConfig.options"
                [colors]="lineChartColors"
                [legend]="lineChartLegend"
                [chartType]="chartConfig.type"
                (chartHover)="chartHovered($event)"
                (chartClick)="chartClicked($event)"></canvas>
    </div>

This just renders and chart with no labels, but if I use the example label variable it works:

public lineChartLabels:Array = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];

My this.chartConfig.labels array contains exactly the same number of labels as I have data values (7). I have compared the backend update array to the example array and I cannot see any difference.

What is wrong?

@ChrisWorks Consider trying this :

  setTimeout(function () {
          this.chartConfig.data.datasets = [{ data: values }];
this.chartConfig.labels = labels;
    }, 0);

This should work.
And as said by @JPtenBerge @zbagley, this is just a work around.

The trick is in clearing the label and data array, the below code didnt work for me :(

clearCharts() {
    this.barChartLabels= [];
    this.barChartData= [
      {data: [], label: 'label1'},
      {data: [], label: 'label2'}
    ];
  }

However when I changed the way I cleared the data helped me (Using object reference)
clearCharts() { this.barChartLabels= []; this.emptyChartData(this.barChartData); } emptyChartData(obj) { obj[0].data = []; obj[1].data = []; obj[0].label = 'label1'; obj[1].label = 'label2'; }

@JPtenBerge Were you able to make the chart is back, after navigating in the year 2016?

here is another work around that works on my end just add a condition on the canvas wrapper element
*ngIf="lineChartLabels.length > 0" to redraw the chart.

                  <div class="chart" *ngIf="lineChartLabels.length > 0">
                    <canvas baseChart height="114"
                            [datasets]="lineChartData"
                            [labels]="lineChartLabels"
                            [options]="chartOptions"
                            [chartType]="lineChartType"
                            [colors]="lineChartColors">
                    </canvas>
                  </div>

@juanito-lansangan worked for me thanks!

@juanito-lansangan super!!!

I was already going for the @Viewchild reference to call the .update() method; but your work around is easy and it works! Thanks!

@juanito-lansangan this is nice, but has some not so nice visual flashing effects... any idea to stop that?

@juanito-lansangan neat solution. Thank you.

Also see this similar issue for solution https://github.com/valor-software/ng2-charts/issues/718#issuecomment-471173803

[datasets]="ChartData"
//...other stuff >

and in the component I have a function which update the chart with new data, and then I clone the datasets and re-assign it

drawChart(){
this.ChartData=[{data: this.dataX, label: 'X'}]; // this.dataX has new values from some place in my code
//nothing happened with my chart yet, until I add this lines:
let clone = JSON.parse(JSON.stringify(this.ChartData));
this.ChartData=clone;
//other stuff like labels etc.
}

Use ng4-charts instead. If your label never update after pushing new element to the labelList use this

this.labelList = this.labelList.splice(0) to force re-render

here is another work around that works on my end just add a condition on the canvas wrapper element
*ngIf="lineChartLabels.length > 0" to redraw the chart.

                  <div class="chart" *ngIf="lineChartLabels.length > 0">
                    <canvas baseChart height="114"
                            [datasets]="lineChartData"
                            [labels]="lineChartLabels"
                            [options]="chartOptions"
                            [chartType]="lineChartType"
                            [colors]="lineChartColors">
                    </canvas>
                  </div>

chart.js vs 2.7.2 working for me, thank sm!!

here is another work around that works on my end just add a condition on the canvas wrapper element
*ngIf="lineChartLabels.length > 0" to redraw the chart.

                  <div class="chart" *ngIf="lineChartLabels.length > 0">
                    <canvas baseChart height="114"
                            [datasets]="lineChartData"
                            [labels]="lineChartLabels"
                            [options]="chartOptions"
                            [chartType]="lineChartType"
                            [colors]="lineChartColors">
                    </canvas>
                  </div>

Its not working for me, i have ng2-charts 2.3.2

Was this page helpful?
0 / 5 - 0 ratings

Related issues

brandonreid picture brandonreid  路  3Comments

grahammutter picture grahammutter  路  4Comments

Adwind picture Adwind  路  3Comments

dslima90 picture dslima90  路  3Comments

sarn3792 picture sarn3792  路  4Comments