Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

678
Vistas
ng2-charts update labels and data

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 only it works, but When I change both just data are updated in the chart. have any one an explication for this strange behavior.

my template :

<canvas baseChart height="130" width="180"  
    [data]="doughnutChartData"
    [labels]="doughnutChartLabels"
    [chartType]="doughnutChartType"
    (chartHover)="chartHovered($event)"
    (chartClick)="chartClicked($event)">
</canvas>

my class :

export class PlDoughnutComponent implements OnInit {

  constructor(private homeService: TileServiceService) { }

  ngOnInit() {
    this.updatePLdoughnut();

  }

  public util : UtilService = new UtilService();
  public doughnutChartLabels:string[] = ['Download Sales'];
  public doughnutChartData:number[] = [0,0,100];
  public doughnutChartType:string = 'doughnut';

  public updatePLdoughnut(){

    this.homeService.getTile().
    then(res => {

      this.doughnutChartLabels =  res.PLtypes;
      this.doughnutChartData = this.util.objectToIntArray(res.PLByTypes);

    })
  }
}
about 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

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]);
}

Or, using new ECMAScript syntax:

this.lineChartLabels.length = 0;
this.lineChartLabels.push(...tempLabels);

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!

about 4 years ago · Santiago Trujillo Denunciar

0

Recently i had to use ng2-charts and i was having a very big issues with updating my data untill i found this sollution:

<div class="chart">
    <canvas baseChart [datasets]="datasets_lines" [labels]="labels_line" [colors]="chartColors" [options]="options" [chartType]="lineChartType">
    </canvas>
</div>

and here what i have in my component :

import { Component, OnInit, Pipe, ViewChild, ElementRef } from '@angular/core';
import { BaseChartDirective } from 'ng2-charts/ng2-charts';

@Component({
    moduleId: module.id,
    selector: 'product-detail',
    templateUrl: 'product-detail.component.html'
})

export class ProductDetailComponent {
    @ViewChild(BaseChartDirective) chart: BaseChartDirective;

    private datasets_lines: { label: string, backgroundColor: string, borderColor: string, data: Array<any> }[] = [
        {
        label: "Quantities",
        data: Array<any>()
    }
];

private labels_line = Array<any>();

private options = {
    scales: {
        yAxes: [{
            ticks: {
                beginAtZero: true
            }
        }]
    }
};


constructor() { }
ngOnInit() {

    this.getStats();

}
getStats() {

    this._statsService.getStatistics(this.startDate, this.endDate, 'comparaison')
        .subscribe(
        res => {
            console.log('getStats success');
            this.stats = res;

            this.labels_line = this.getDates();
            this.datasets_lines = [];

            let arr: any[];
            arr = [];
            for (let stat of this.stats) {
                arr.push(stat.quantity);
            }

            this.datasets_lines.push({
                label: 'title',
                data: arr
            });

            this.refresh_chart();

        },
        err => {
            console.log("getStats failed from component");
        },
        () => {
            console.log('getStats finished');
        });
}

refresh_chart() {
    setTimeout(() => {
        console.log(this.datasets_lines_copy);
        console.log(this.datasets_lines);
        if (this.chart && this.chart.chart && this.chart.chart.config) {
            this.chart.chart.config.data.labels = this.labels_line;
            this.chart.chart.config.data.datasets = this.datasets_lines;
            this.chart.chart.update();
        }
    });
}

getDates() {
    let dateArray: string[] = [];
    let currentDate: Date = new Date();
    currentDate.setTime(this.startDate.getTime());
    let pushed: string;
    for (let i = 1; i < this.daysNum; i++) {
        pushed = currentDate == null ? '' : this._datePipe.transform(currentDate, 'dd/MM/yyyy');
        dateArray.push(pushed);
        currentDate.setTime(currentDate.getTime() + 24 * 60 * 60 * 1000);
    }
    re

turn dateArray;
    }    
}

i m sure this is the right way to do it, and hope this would be helpfull

about 4 years ago · Santiago Trujillo Denunciar

0

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: `
  <select (change)="onChange($event.target.value)">
    <option value="" disabled selected>Select your option</option>
    <option value="0">Option 0</option>
    <option value="1">Option 1</option>
  </select>

  <canvas baseChart
          chartType="bar"
          [datasets]="barChartData"
          [labels]="barChartLabels"
          [colors]="barChartColors">
  </canvas>
  `
})
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: `
  <select (change)="onChange($event.target.value)">
    <option value="" disabled selected>Select your option</option>
    <option value="0">Option 0</option>
    <option value="1">Option 1</option>
  </select>

  <canvas baseChart
          chartType="bar"
          [datasets]="barChartData"
          [labels]="barChartLabels"
          [colors]="barChartColors">
  </canvas>
  `
})
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);
  }
}
about 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda