ng2图表多图表更新

时间:2019-02-11 17:01:23

标签: angular chart.js ng2-charts

在我的代码中,我使用API​​获取用于监控的服务器数据 而且我有多个图表,所有图表工作正常,因此我每隔1秒更新一次图表,并且也每隔1秒从服务器调用一次API,但是只有我的第一个图表不会更新其他图表,任何解决方案?? 注意:我使用的是valor软件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>

2 个答案:

答案 0 :(得分:2)

经过研究,我发现了这个问题: 问题是:

@ViewChild( BaseChartDirective) chart: BaseChartDirective;

它只选择第一个孩子,所以

this.chart.chart.update()

仅更新第一个子项,解决方法是:应该使用QueryList

@ViewChildren(BaseChartDirective) charts: QueryList<BaseChartDirective>;

并更新列表:

  this.charts.forEach((child) => {
      child.chart.update()
  });

答案 1 :(得分:0)

您不需要这样做,只需在当前对象中创建一个数据对象和一个标签对象。当您从数据源获取图形数据时,可能必须对其进行修改以适合您正在使用的图形的模式,然后遍历所有对象并插入图形数据。

这一切都发生在click事件中,我使用Angular8。如果您需要帮助,请给我发消息。

(以下模型中的属性)

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;