Saltar al contenido

ng2-charts actualiza etiquetas y datos

Después de consultar con expertos en la materia, programadores de deferentes ramas y maestros hemos dado con la respuesta al dilema y la compartimos en esta publicación.

Solución:

Aparentemente, si tu no modifique la referencia original a las etiquetas array, parece funcionar, al menos para mí. Quiero decir, si quieres un conjunto de etiquetas completamente diferente, deberías hacer algo como esto:

En la plantilla:


En el componente ts:

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

O, usando la nueva sintaxis de ECMAScript:

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

los key es tal vez el this.lineChartLabels.length = 0; declaración, que prácticamente ‘vacía’ su array estableciendo su longitud en 0, sin modificar la referencia. ¡Espero que esto ayude!

Recientemente tuve que usar ng2-charts y estaba teniendo grandes problemas con la actualización de mis datos hasta que encontré esta solución:

y aquí lo que tengo en mi componente:

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 [] = [
        
        label: "Quantities",
        data: Array()
    
];

private labels_line = Array();

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;
        

Estoy seguro de que esta es la forma correcta de hacerlo, y espero que sea útil.

Como Deyd señaló antes, esto es causado por una combinación de detección de cambios de Angular 2 + y un error en ng2-charts.

De acuerdo con mis propias observaciones (corríjame si me equivoco), Angular fusiona varios cambios en un período de tiempo muy corto en una sola colección (changes: SimpleChanges) cuando ngOnChanges se llama.

Desafortunadamente, ng2-charts solo verifica si el conjunto de datos se ha modificado con esta colección y la actualiza. De lo contrario, reconstruye completamente todo el gráfico. Sin embargo, debido a la forma en que funciona la detección de cambios, es posible que se haya cambiado más de una propiedad. Luego, solo se actualiza el conjunto de datos, incluso si las etiquetas y posiblemente otras propiedades también se hayan actualizado. Ver ngOnChanges en ng2-charts: valor-software / ng2-charts / src / charts / charts.ts

Y si no desea tener una copia separada de ng2-charts en su aplicación y solucionar el problema usted mismo, una posible solución para este problema es configurar el conjunto de datos con un breve retraso utilizando la función incorporada de JavaScript setTimeout(callback: () => void, delay: number).

Antes:

@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;
  

Después:

@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);
  

Si crees que ha resultado de utilidad este artículo, agradeceríamos que lo compartas con más desarrolladores de este modo contrubuyes a extender nuestra información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *