mus*_*918 20 javascript chart.js ng2-charts angular
我正在尝试使用ng2-chart动态创建图表,我从角度2服务获取信息,当我仅更改图表的标签时它工作,当我更改数据时它只能工作,但当我更改两者时,只更新数据在图表中.对这种奇怪的行为有任何解释.
我的模板:
<canvas baseChart height="130" width="180"
[data]="doughnutChartData"
[labels]="doughnutChartLabels"
[chartType]="doughnutChartType"
(chartHover)="chartHovered($event)"
(chartClick)="chartClicked($event)">
</canvas>
Run Code Online (Sandbox Code Playgroud)
我的课 :
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);
})
}
}
Run Code Online (Sandbox Code Playgroud)
Sle*_*er9 42
显然,如果你不修改标签数组的原始引用,它似乎工作,至少对我来说.我的意思是,如果你想要一套完全不同的标签,你应该这样做:
在模板中:
<canvas baseChart
[datasets]="lineChartData"
[labels]="lineChartLabels"
[options]="lineChartOptions"
[chartType]="'line'"></canvas>
Run Code Online (Sandbox Code Playgroud)
在ts组件中:
this.lineChartLabels.length = 0;
for (let i = tempLabels.length - 1; i >= 0; i--) {
this.lineChartLabels.push(tempLabels[i]);
}
Run Code Online (Sandbox Code Playgroud)
或者,使用新的ECMAScript语法:
this.lineChartLabels.length = 0;
this.lineChartLabels.push(...tempLabels);
Run Code Online (Sandbox Code Playgroud)
关键可能是this.lineChartLabels.length = 0;语句,它通过将其长度设置为0来实际"清空"数组,而无需修改引用.希望这可以帮助!
小智 13
最近我不得不使用ng2-charts,我在更新数据时遇到了很大的问题,直到我发现这个解决方案:
<div class="chart">
<canvas baseChart [datasets]="datasets_lines" [labels]="labels_line" [colors]="chartColors" [options]="options" [chartType]="lineChartType">
</canvas>
</div>
Run Code Online (Sandbox Code Playgroud)
在这里我的组件:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
我确定这是正确的方法,并希望这将是有益的
小智 9
就像Deyd之前指出的那样,这是由Angular 2 +的变化检测和ng2-charts中的错误组合引起的.
根据我自己的观察(如果我错了,请纠正我),Angular会在很短的时间内将几个变化合并到一个集合(changes: SimpleChanges)中ngOnChanges.
不幸的是,ng2-charts只检查数据集是否已使用此集合进行更改并更新它.否则它会完全重建整个图表.但是,由于更改检测的工作方式,可能会更改多个属性.然后,即使标签和可能的其他属性也已更新,只有数据集才会更新.参见ngOnChangesng2-charts:valor-
software/ng2-charts/src/charts/charts.ts
如果您不想在应用程序中单独复制ng2-charts并自行解决问题,则此问题的可能解决方法是使用JavaScript的内置函数设置数据集的延迟很短setTimeout(callback: () => void, delay: number).
之前:
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
后:
@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);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
诀窍在于清除标签和数据数组,下面的代码对我不起作用:( ```
clearCharts() {
this.barChartLabels= [];
this.barChartData= [
{data: [], label: 'label1'},
{data: [], label: 'label2'}
];
}
Run Code Online (Sandbox Code Playgroud)
However when I changed the way I cleared the data helped me (Using object reference)
clearCharts() {
this.barChartLabels= [];
this.emptyChartData(this.barChartData);
}
emptyChartData(obj) {
obj[0].data = [];
obj[1].data = [];
obj[0].label = 'label1';
obj[1].label = 'label2';
}
Run Code Online (Sandbox Code Playgroud)
````
小智 5
使用BaseChartDirective我做了图表更新,它达到了目的.以下示例:
import { BaseChartDirective } from 'ng2-charts/ng2-charts';
Run Code Online (Sandbox Code Playgroud)
在课堂内添加如下
@ViewChild(BaseChartDirective) chart: BaseChartDirective;
Run Code Online (Sandbox Code Playgroud)
当您要更改值时,请添加如下
setTimeout(() => {
if (this.chart && this.chart.chart && this.chart.chart.config) {
this.chart.chart.config.data.labels = this.labels_pie;
this.chart.chart.update();
}
});
Run Code Online (Sandbox Code Playgroud)
小智 5
使用 BaseChartDirective 我进行了图表更新,它达到了目的。示例如下:
import { BaseChartDirective } from 'ng2-charts';
Run Code Online (Sandbox Code Playgroud)
在类中添加如下
@ViewChild(BaseChartDirective) chart: BaseChartDirective;
Run Code Online (Sandbox Code Playgroud)
当您有要更改的值时,请添加如下
this.chart.ngOnChanges({});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
31676 次 |
| 最近记录: |