ng2-charts update labels and data

前端 未结 12 1078
长发绾君心
长发绾君心 2020-12-03 01:25

I\'m trying to create dynamically a chart using ng2-chart, I get information from an angular 2 service, when I change only labels of chart it works and when I change data on

12条回答
  •  情歌与酒
    2020-12-03 01:52

    Like Deyd pointed out before, this is caused by a combination of Angular 2+'s change detection and a bug in ng2-charts.

    According to my own observations (correct me if I'm wrong), Angular merges several changes within a very short timeframe into a single collection (changes: SimpleChanges) when ngOnChanges is called.

    Unfortunately, ng2-charts only checks if the dataset has been changed with this collection and updates it. Otherwise it completely rebuilds the entire chart. However, because of the way the change detection works, more than one property might have been changed. Then, only the dataset gets updated even if the labels and possibly other properties have been updated as well. See ngOnChanges in ng2-charts: valor-software/ng2-charts/src/charts/charts.ts

    And if you don't want to have a separate copy of ng2-charts in your app and fix the problem yourself, a possible workaround for this problem is to set the dataset with a short delay using JavaScript's built-in function setTimeout(callback: () => void, delay: number).

    Before:

    @Component({
      selector: 'app-root',
      template: `
      
    
      
      
      `
    })
    export class AppComponent implements OnInit {
      chartData: string[];
      chartLabels: string[];
      chartColors: string[];
    
      onChange(id: string) {
        getFromApiById(id)
          .then(result => this._setChart(result.data, result.labels, result.colors));
      }
    
      private _setChart(data: string[], labels: string[], colors: string[]) {
        this.chartData = data;
        this.chartLabels = labels;
        this.chartColors = colors;
      }
    }
    

    After:

    @Component({
      selector: 'app-root',
      template: `
      
    
      
      
      `
    })
    export class AppComponent implements OnInit {
      chartData: string[];
      chartLabels: string[];
      chartColors: string[];
    
      onChange(id: string) {
        getFromApiById(id)
          .then(result => this._setChart(result.data, result.labels, result.colors));
      }
    
      private _setChart(data: string[], labels: string[], colors: string[]) {
        this.chartLabels = labels;
        this.chartColors = colors;
    
        setTimeout(() => {
          this.chartData = data;
        }, 50);
      }
    }
    

提交回复
热议问题