作者:风一样的梦 | 来源:互联网 | 2023-02-09 19:12
我正在尝试使用ng2-chart动态创建图表,我从角度2服务获取信息,当我仅更改图表的标签时它工作,当我更改数据时它只能工作,但当我更改两者时,只更新数据在图表中.对这种奇怪的行为有任何解释.
我的模板:
我的课 :
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);
})
}
}
Sleeper9..
42
显然,如果你不修改 标签数组的原始引用 ,它似乎工作,至少对我来说.我的意思是,如果你想要一套完全不同的标签,你应该这样做:
在模板中:
在ts组件中:
this.lineChartLabels.length = 0;
for (let i = tempLabels.length - 1; i >= 0; i--) {
this.lineChartLabels.push(tempLabels[i]);
}
或者,使用新的ECMAScript语法:
this.lineChartLabels.length = 0;
this.lineChartLabels.push(...tempLabels);
关键可能是this.lineChartLabels.length = 0;
语句,它通过将其长度设置为0来实际"清空"数组,而无需修改引用.希望这可以帮助!
1> Sleeper9..: 显然,如果你不修改 标签数组的原始引用 ,它似乎工作,至少对我来说.我的意思是,如果你想要一套完全不同的标签,你应该这样做:
在模板中:
在ts组件中:
this.lineChartLabels.length = 0;
for (let i = tempLabels.length - 1; i >= 0; i--) {
this.lineChartLabels.push(tempLabels[i]);
}
或者,使用新的ECMAScript语法:
this.lineChartLabels.length = 0;
this.lineChartLabels.push(...tempLabels);
关键可能是this.lineChartLabels.length = 0;
语句,它通过将其长度设置为0来实际"清空"数组,而无需修改引用.希望这可以帮助!
这个答案对我有用
2> 小智..: 最近我不得不使用ng2-charts,我在更新数据时遇到了很大的问题,直到我发现这个解决方案:
在这里我的组件:
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
我确定这是正确的方法,并希望这将是有益的
3> 小智..: 就像Deyd之前指出的那样,这是由Angular 2 +的变化检测和ng2-charts中的错误组合引起的.
根据我自己的观察(如果我错了,请纠正我),Angular会在很短的时间内将几个变化合并到一个集合(changes: SimpleChanges
)中ngOnChanges
.
不幸的是,ng2-charts只检查数据集 是否已使用此集合进行更改并更新它.否则它会完全重建整个图表.但是,由于更改检测的工作方式,可能会更改多个属性.然后,即使标签和可能的其他属性也已更新,只有数据集才会更新.参见ngOnChanges
ng2-charts:valor-
software/ng2-charts/src/charts/charts.ts
如果您不想在应用程序中单独复制ng2-charts并自行解决问题,则此问题的可能解决方法是使用Javascript的内置函数设置数据集的延迟很短setTimeout(callback: () => void, delay: number)
.
之前:
@Component({
selector: 'app-root',
template: `
Select your option
Option 0
Option 1
`
})
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;
}
}
后:
@Component({
selector: 'app-root',
template: `
Select your option
Option 0
Option 1
`
})
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);
}
}
4> 小智..: 使用BaseChartDirective我做了图表更新,它达到了目的.以下示例:
import { BaseChartDirective } from 'ng2-charts/ng2-charts';
在课堂内添加如下
@ViewChild(BaseChartDirective) chart: BaseChartDirective;
当您要更改值时,请添加如下
setTimeout(() => {
if (this.chart && this.chart.chart && this.chart.chart.config) {
this.chart.chart.config.data.labels = this.labels_pie;
this.chart.chart.update();
}
});