Ng2-charts: options should update/refresh the chart on ngOnChanges

Created on 16 Dec 2016  ·  18Comments  ·  Source: valor-software/ng2-charts

Currently only changes to the data and labels are considered to redraw/refresh the chart. In my case I need to set the chart's title, axis labels, etc dynamically based on data I load from my server. Please add this or let me know how to work around this in my app. Thanks

Most helpful comment

I've been working around this with the following.

import { BaseChartDirective } from 'ng2-charts';

In class

ViewChild(BaseChartDirective) private _chart;

And when you need to force a refresh

forceChartRefresh() {
        setTimeout(() => {
            this._chart.refresh();
        }, 10);
    }

This is less than elegant and didn't seem to work for me without the setTimeout but it's getting us by until this is fixed.

All 18 comments

I have the same problem for "line" chart

Changes in lineChartData gives new data in the plot (works fine)

Changes in lineChartOptions only works the first time it is changed. Same behaviour with

  1. this.lineChartData = newLineData; or
  2. this.lineChartOptions.scales.xAxes[0].ticks.min = newMin
    this.lineChartOptions.scales.xAxes[0].ticks.max = newMax

I want to give new xAxes each time a timer is triggered.

[datasets]="lineChartData"
[options]="lineChartOptions"
[colors]="lineChartColors"
[legend]="lineChartLegend"
[chartType]="lineChartType"
(chartHover)="chartHovered($event)"
(chartClick)="chartClicked($event)">

Experiencing same issue. Any update on this?

I have the same problem. The 'options' Objects is missing in the ngOnChanges Method implementation. Only 'data' changes are recognized for some reason.

    ChartComponent.prototype.ngOnChanges = function (changes) {
        var _this = this;
        if (this.chart && changes['data']) {
            var currentValue_1 = changes['data'].currentValue;
            ['datasets', 'labels', 'xLabels', 'yLabels'].forEach(function (property) {
                _this.chart.data[property] = currentValue_1[property];
            });
            this.chart.update();
        }
    };

But for some reason if I update the options Object, chartjs stops working.

  ChartComponent.prototype.ngOnChanges = function (changes) {
    var _this = this;
    if (this.chart) {

      if(changes['data']) {
        var currentValue_1 = changes['data'].currentValue;
        ['datasets', 'labels', 'xLabels', 'yLabels'].forEach(function (property) {
          _this.chart.data[property] = currentValue_1[property];
        });
      }

      if(changes['options']){
        Object.assign(this.chart.options, changes['options'].currentValue);
      }

      this.chart.update();

    }
  };

I need to update the yAxis Label so the following is enough for me, but this needs to be generic!

    ChartComponent.prototype.ngOnChanges = function (changes) {
        var _this = this;
        if (this.chart) {

          if(changes['data']) {
            var currentValue_1 = changes['data'].currentValue;
            ['datasets', 'labels', 'xLabels', 'yLabels'].forEach(function (property) {
              _this.chart.data[property] = currentValue_1[property];
            });
          } 

          if(changes['options']){
            this.chart.options.scales.yAxes[0].scaleLabel.labelString = changes['options'].currentValue.scales.yAxes[0].scaleLabel.labelString
          }

          this.chart.update();

        }
    };

If I update the x-axis labels with new labels, e.g., from [2008,2009,2010,2011,2012,2013,2014,2015,2016] to [2012,2013,2014,2015,2016], the chart continues to show the old labels, and draws the chart data incorrectly, from 2008 onwards. This issue seems to have come up for chart.js https://github.com/chartjs/Chart.js/issues/593 -- and they are saying they have fixed it. So the Angular-2 side needs to reflect that fix.

I have the same issues.. I have to change labels for new data arriving from the backend.
Data change correctly doing the clone of the array but for label not.

I've been working around this with the following.

import { BaseChartDirective } from 'ng2-charts';

In class

ViewChild(BaseChartDirective) private _chart;

And when you need to force a refresh

forceChartRefresh() {
        setTimeout(() => {
            this._chart.refresh();
        }, 10);
    }

This is less than elegant and didn't seem to work for me without the setTimeout but it's getting us by until this is fixed.

Thank you it is work ;)

@ryan-morris I used your working around, but failed when compile my code: TS2341: Property ‘refresh’ is private and only accessible within class ‘BaseChartDirective ’.”
And refresh() was defined as private. Do you have any other suggestion?
Thanks~

thanks @ryan-morris!

@zechfox I had the same error and got around the typescript compiler by using this:

(<any>this._chart).refresh()

However, this still only updated datasets for me, so I ended up forcing Angular to refresh the whole canvas by doing this (noting that my <canvas> has *ngIf="graph":

this.graph = undefined;
this.changeDetector.markForCheck();
setTimeout(() => { 
    this.graph = newDataAndColorsAndOptions;
    this.changeDetector.markForCheck();
},0);

@stefanSlalom Thanks for the tip, was the solution for me.

Just to expand on using (<any>this._chart).refresh() , a slightly cleaner way to resolve the compiler gripes - especially if you plan to use refresh() in multiple places - is to update your directive declaration, eg:

@ViewChild(BaseChartDirective) chartWidget: BaseChartDirective;

to

@ViewChild(BaseChartDirective) chartWidget: any;

I had a simplier solution :)
Just use wrapper canvas inside the div and ngIf for it.

  1. Then set it to false show variable.
  2. Change data
  3. Set show variable to true inside setTimeout(()=>{this.show = true}, 0)

Impossible stupid, but working.

Thank you, @AlexanderKozhevin! After hours of frustration, this resolved this for me.

can you help me i am new to angular 2 and i am using chart.js to make a dynamic chart i have created node.js backend api which give data to an angular 2 service .The problem is that all the variables required to make the chart gets updated but the chart is not getting updated until reload i want to update it without reloading the page.Could you please help me with this thanks in advance.

@longhairguy
I'm a code-mentor. It's my job to help people.
https://www.codementor.io/alexander-k

Closed by ef5d2f4

I've been working around this with the following.

import { BaseChartDirective } from 'ng2-charts';

In class

ViewChild(BaseChartDirective) private _chart;

And when you need to force a refresh

forceChartRefresh() {
        setTimeout(() => {
            this._chart.refresh();
        }, 10);
    }

This is less than elegant and didn't seem to work for me without the setTimeout but it's getting us by until this is fixed.

For now, setTiemout + ngOnChanges() works
Thanks man, really don't know why such weird behavior.

@stefanSlalom Thanks for the tip, was the solution for me.

Just to expand on using (<any>this._chart).refresh() , a slightly cleaner way to resolve the compiler gripes - especially if you plan to use refresh() in multiple places - is to update your directive declaration, eg:

@ViewChild(BaseChartDirective) chartWidget: BaseChartDirective;

to

@ViewChild(BaseChartDirective) chartWidget: any;

Works Thanks

Was this page helpful?
0 / 5 - 0 ratings