问题
Is it possible to update any chart
from ng2-charts
dynamically? I know there are other libraries like angular2-highcharts
, but I would like to handle it using ng2-charts
. Main question is how can I redraw chart
, after button click? I can resize window and data will be updated, so it have to be any option to do it manually.
https://plnkr.co/edit/fXQTIjONhzeMDYmAWTe1?p=preview
回答1:
A good way is to get a grip on the chart itself in order to redraw it using the API :
export class MyClass {
@ViewChild( BaseChartDirective ) chart: BaseChartDirective;
private updateChart(){
this.chart.ngOnChanges({});
}
}
回答2:
I figure it out, maybe its not the best existing option, but it works. We can't update existing chart
, but we can create new one, using our existing chart
and add new points. We can even get better effect, turning animation of chart off.
Function that solved problem:
updateChart(){
let _dataSets:Array<any> = new Array(this.datasets.length);
for (let i = 0; i < this.datasets.length; i++) {
_dataSets[i] = {data: new Array(this.datasets[i].data.length), label: this.datasets[i].label};
for (let j = 0; j < this.datasets[i].data.length; j++) {
_dataSets[i].data[j] = this.datasets[i].data[j];
}
}
this.datasets = _dataSets;
}
Live demo: https://plnkr.co/edit/fXQTIjONhzeMDYmAWTe1?p=preview
@UPDATE: as @Raydelto Hernandez mentioned in comment below, better solution is:
updateChart(){
this.datasets = this.dataset.slice()
}
回答3:
Recently I had to use ng2-charts and i was having a very big issues with updating my data until I found this solution:
<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.labels_line = this.getDates();
this._statsService.getStatistics(this.startDate, this.endDate, 'comparaison')
.subscribe(
res => {
console.log('getStats success');
this.stats = res;
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);
}
return dateArray;
}
}
I'm sure this is the right way to do it.
回答4:
**This worked for me - with pie-chart:*
Component.html:
<canvas baseChart [colors]="chartColors" [data]="pieChartData" [labels]="pieChartLabels" [chartType]="pieChartType"></canvas>
Component.ts:
In the header section:
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { Chart } from 'chart.js';
import { BaseChartDirective } from 'ng2-charts/ng2-charts';
In the declaration section of export class:
@ViewChild(BaseChartDirective) chart: BaseChartDirective;
// for custom colors
public chartColors: Array<any> = [{
backgroundColor: ['rgb(87, 111, 158)', 'yellow', 'pink', 'rgb(102, 151, 185)'],
borderColor: ['white', 'white', 'white', 'white']
}];
After the block that updates your pie chart data (using services/sockets or any other means):
this.chart.chart.update();
回答5:
Update any chart from ng2-charts
dynamically is possible.
Example:
http://plnkr.co/edit/m3fBiHpKuDgYG6GVdJQD?p=preview
That Angular update chart, variable or reference must change. When you just change value of array element, variables and references not changed. See also Github.
回答6:
I have found this article after a searching a while. Then I tried every solution that is mentioned in this article but none was working properly. Finally I settled using a dynamic component.
I provided the dynamic data to component that is dynamically added to the parent component. I wrote about the whole process just so you don't go through the challenges.
来源:https://stackoverflow.com/questions/39078061/dynamically-updated-ng2-charts