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.