ng2图表多图表更新
ng2 chart multiple chart update
在我的代码中,我使用 API 获取用于监控的服务器数据
我有多个图表,所有图表都工作正常,所以我每 1 秒更新一次图表,我也每 1 秒从服务器调用 API,但只有我的第一个图表不会更新其他图表,任何解决方案? ?
注意:我正在使用 valor-software
的 ng2-chart
import { Chart } from 'chart.js';
import { ChangeDetectorRef } from '@angular/core';
import { Component, OnInit,ViewChild} from '@angular/core';
import { ApiServiceService } from '../api-service.service';
import { Observable , interval } from 'rxjs';
import { switchMap} from 'rxjs/operators';
import {IData} from '../interface/data'
import { BaseChartDirective} from 'ng2-charts';
import { DatePipe } from '@angular/common';
Chart.defaults.global.elements.line.fill = false;
//==================================================
import { Servers } from '../custom-config/servers'; // Servers Data
import {lineChart} from '../custom-config/chart-config'// chart Configration Data
@Component({
selector: 'app-server-monit',
templateUrl: './server-monit.component.html',
styleUrls: ['./server-monit.component.css'],
})
export class ServerMonitComponent implements OnInit {
@ViewChild( BaseChartDirective) chart: BaseChartDirective;
public _servers= Servers;
//==========================================
// time
pipe = new DatePipe('en-US'); // Use your own locale
public now;
public currentTime;
//==========================================
// Line Chart configration
public chartType = 'line';
public chartLegend = true;
public chartColor = '#eee'
public chartOptions = lineChart.Options
public colors = lineChart.Colors
constructor(private api: ApiServiceService) {
}
ngOnInit() {
for (let i = 0; i < this._servers.length; i++ ) {
// get data on Init
this.api.checkServer(this._servers[i].ip+':'+this._servers[i].port).subscribe((data:IData) => {
this.proccessData(data, i)
});
// get data every subsequent 1 seconds
const result = interval(1000).pipe(
switchMap(() => this.api.checkServer(this._servers[i].ip+':'+this._servers[i].port)),)
.subscribe((data:IData) => {
this.proccessData(data, i) // proccess the APIdata
this.forceChartRefresh(); // Update charts
});
}
}
proccessData(data: IData , index){
this.now = Date.now();
this.currentTime = this.pipe.transform(this.now, 'mediumTime');
//=============================================================
let totalClients = data.total_clients;
let input = Math.round(data.input_kbit /1024);
let output = Math.round(data.output_kbit /1024);
if(
this._servers[index].charts.traffic.dataset[0].data.length <= 20 &&
this._servers[index].charts.traffic.dataset[1].data.length <= 20 &&
this._servers[index].charts.traffic.dataset[2].data.length <= 20
){
this._servers[index].charts.traffic.dataset[0].data.push(totalClients)
this._servers[index].charts.traffic.dataset[1].data.push(input)
this._servers[index].charts.traffic.dataset[2].data.push(output)
this._servers[index].charts.traffic.labels.push(this.currentTime)
}
else {
this._servers[index].charts.traffic.dataset[0].data.shift()
this._servers[index].charts.traffic.dataset[1].data.shift()
this._servers[index].charts.traffic.dataset[2].data.shift()
this._servers[index].charts.traffic.labels.shift()
}
}
forceChartRefresh() {
this.chart.chart.update()
}
}
<p>
server-monit works!
</p>
<div class="col-4" *ngFor="let server of _servers">
<div>
<canvas baseChart
[datasets]="server.charts.traffic.dataset"
[labels]="server.charts.traffic.labels"
[options]="chartOptions"
[colors]=""
[legend]="chartLegend"
[chartType]="chartType"
></canvas>
</div>
</div>
经过一番研究,我发现了问题所在:
问题是:
@ViewChild( BaseChartDirective) chart: BaseChartDirective;
它只选择第一个 child,所以
this.chart.chart.update()
只更新第一个 child ,解决方案是:应该使用 QueryList
@ViewChildren(BaseChartDirective) charts: QueryList<BaseChartDirective>;
并更新列表:
this.charts.forEach((child) => {
child.chart.update()
});
您不需要这样做,在您当前的对象中创建一个数据对象和一个标签对象。当您从数据源获取图表数据时,您可能必须修改它以适应您正在处理的图表模式,然后遍历所有对象并插入图表数据。
这一切都发生在点击事件中,我使用Angular 8.如果需要帮助,请给我留言。
(以下模型中的属性)
public barChartData: any[] = [{ data: [], label: 'Red' }, { data: [], label: 'Blue' }],
public barChartLabels: any[] = [""]
this.redBlueCountByDate.forEach((item) => {
barChartLabels.push(new Date(item.eomDate).toLocaleDateString("en-US"));
barChartData[0].data.push(item.redDataCount);
barChartData[1].data.push(item.blueDataCount);
})
this.modelData.find(x => x.dataID == dataID).barChartData = barChartData;
this.modelData.find(x => x.dataID == dataID).barChartLabels = barChartLabels;
在我的代码中,我使用 API 获取用于监控的服务器数据 我有多个图表,所有图表都工作正常,所以我每 1 秒更新一次图表,我也每 1 秒从服务器调用 API,但只有我的第一个图表不会更新其他图表,任何解决方案? ? 注意:我正在使用 valor-software
的 ng2-chartimport { Chart } from 'chart.js';
import { ChangeDetectorRef } from '@angular/core';
import { Component, OnInit,ViewChild} from '@angular/core';
import { ApiServiceService } from '../api-service.service';
import { Observable , interval } from 'rxjs';
import { switchMap} from 'rxjs/operators';
import {IData} from '../interface/data'
import { BaseChartDirective} from 'ng2-charts';
import { DatePipe } from '@angular/common';
Chart.defaults.global.elements.line.fill = false;
//==================================================
import { Servers } from '../custom-config/servers'; // Servers Data
import {lineChart} from '../custom-config/chart-config'// chart Configration Data
@Component({
selector: 'app-server-monit',
templateUrl: './server-monit.component.html',
styleUrls: ['./server-monit.component.css'],
})
export class ServerMonitComponent implements OnInit {
@ViewChild( BaseChartDirective) chart: BaseChartDirective;
public _servers= Servers;
//==========================================
// time
pipe = new DatePipe('en-US'); // Use your own locale
public now;
public currentTime;
//==========================================
// Line Chart configration
public chartType = 'line';
public chartLegend = true;
public chartColor = '#eee'
public chartOptions = lineChart.Options
public colors = lineChart.Colors
constructor(private api: ApiServiceService) {
}
ngOnInit() {
for (let i = 0; i < this._servers.length; i++ ) {
// get data on Init
this.api.checkServer(this._servers[i].ip+':'+this._servers[i].port).subscribe((data:IData) => {
this.proccessData(data, i)
});
// get data every subsequent 1 seconds
const result = interval(1000).pipe(
switchMap(() => this.api.checkServer(this._servers[i].ip+':'+this._servers[i].port)),)
.subscribe((data:IData) => {
this.proccessData(data, i) // proccess the APIdata
this.forceChartRefresh(); // Update charts
});
}
}
proccessData(data: IData , index){
this.now = Date.now();
this.currentTime = this.pipe.transform(this.now, 'mediumTime');
//=============================================================
let totalClients = data.total_clients;
let input = Math.round(data.input_kbit /1024);
let output = Math.round(data.output_kbit /1024);
if(
this._servers[index].charts.traffic.dataset[0].data.length <= 20 &&
this._servers[index].charts.traffic.dataset[1].data.length <= 20 &&
this._servers[index].charts.traffic.dataset[2].data.length <= 20
){
this._servers[index].charts.traffic.dataset[0].data.push(totalClients)
this._servers[index].charts.traffic.dataset[1].data.push(input)
this._servers[index].charts.traffic.dataset[2].data.push(output)
this._servers[index].charts.traffic.labels.push(this.currentTime)
}
else {
this._servers[index].charts.traffic.dataset[0].data.shift()
this._servers[index].charts.traffic.dataset[1].data.shift()
this._servers[index].charts.traffic.dataset[2].data.shift()
this._servers[index].charts.traffic.labels.shift()
}
}
forceChartRefresh() {
this.chart.chart.update()
}
}
<p>
server-monit works!
</p>
<div class="col-4" *ngFor="let server of _servers">
<div>
<canvas baseChart
[datasets]="server.charts.traffic.dataset"
[labels]="server.charts.traffic.labels"
[options]="chartOptions"
[colors]=""
[legend]="chartLegend"
[chartType]="chartType"
></canvas>
</div>
</div>
经过一番研究,我发现了问题所在: 问题是:
@ViewChild( BaseChartDirective) chart: BaseChartDirective;
它只选择第一个 child,所以
this.chart.chart.update()
只更新第一个 child ,解决方案是:应该使用 QueryList
@ViewChildren(BaseChartDirective) charts: QueryList<BaseChartDirective>;
并更新列表:
this.charts.forEach((child) => {
child.chart.update()
});
您不需要这样做,在您当前的对象中创建一个数据对象和一个标签对象。当您从数据源获取图表数据时,您可能必须修改它以适应您正在处理的图表模式,然后遍历所有对象并插入图表数据。
这一切都发生在点击事件中,我使用Angular 8.如果需要帮助,请给我留言。
(以下模型中的属性)
public barChartData: any[] = [{ data: [], label: 'Red' }, { data: [], label: 'Blue' }],
public barChartLabels: any[] = [""]
this.redBlueCountByDate.forEach((item) => {
barChartLabels.push(new Date(item.eomDate).toLocaleDateString("en-US"));
barChartData[0].data.push(item.redDataCount);
barChartData[1].data.push(item.blueDataCount);
})
this.modelData.find(x => x.dataID == dataID).barChartData = barChartData;
this.modelData.find(x => x.dataID == dataID).barChartLabels = barChartLabels;