从服务器更新 ChartJS 图表的数据

问题描述

几天来,我的 Angular 网站出现问题。 我的目标是从 S7-1500 接收数据以在电视上实时显示数据。

我成功地获得了一些实时数据,但我遇到了一个小问题。当我更改页面时,图表上的数据正在刷新,但如果我停留在同一页面上,则什么也没有发生。

在此服务中,我从 API 获取数据,并将“consoAir”放在 10 数组的末尾:

import {BehaviorSubject,combineLatest,forkJoin,timer} from 'rxjs';
import {HttpClient} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {switchMap} from 'rxjs/operators';

@Injectable()
export class Lineservice{
  constructor(private http: HttpClient) {
    this.getData();
  }

  _consoAir = [ Array(10).fill(0),Array(10).fill(0),Array(10).fill(0)];
  linesubject = new BehaviorSubject<RcvData[]>([]);

  getData(): void {
    const lists: string[] = [
      'assets/donnee-l1.csv','assets/donnee-l2.csv','assets/donnee-l3.csv','assets/donnee-l4.csv','assets/donnee-l5.csv','https://192.168.0.2/DataLogs?Path=/DataLogs/MyDataLog9.csv&Action=DOWNLOAD&E=1'
    ];
    const reqs$ = lists.map(list => this.http.get(list,{responseType: 'text'}));

    timer(0,5000).pipe(
      switchMap(_ => forkJoin(reqs$))
    ).subscribe(listResults => {
        const parsedListResults = listResults.map(data => {
          const csvToRowArray = data.split('\n');
          const lastRow = csvToRowArray[csvToRowArray.length - 2];
          const row = lastRow.split(',');
          return new RcvData(
            parseInt(row[0],10),row[1],row[2],parseInt(row[3],row[4],row[5],row[6],row[7],parseInt(row[8],parseInt(row[9],parseInt(row[10],parseInt(row[11],parseFloat(row[12]),parseFloat(row[13]),parseFloat(row[14]),parseFloat(row[15]),parseFloat(row[16]),parseInt(row[17],10));
        });
        this.linesubject.next(parsedListResults);

        for (const module of parsedListResults) {
          this._consoAir[module.id - 1].push(module.consoAir);

          if (this._consoAir[module.id - 1].length > 10){
            this._consoAir[module.id - 1].splice(0,1);
          }
        }
        console.log(this._consoAir);

      });
  }
}




class RcvData{
  seqNo: number;
  date: string;
  utcTime: string;
  id: number;
  name: string;
  refCharge: string;
  refDecharge: string;
  quantiteEnCours: string;
  quantiteHoraireReel: number;
  quantiteHoraireTheorique: number;
  quantitePosteReel: number;
  quantitePosteTheorique: number;
  trpHeureReel: number;
  trpPosteReel: number;
  trpObjectif: number;
  consoAir: number;
  consoElec: number;
  status: number;


  constructor(
    seqNo: number,date: string,utcTime: string,id: number,name: string,refCharge: string,refDecharge: string,quantiteEnCours: string,quantiteHoraireReel: number,quantiteHoraireTheorique: number,quantitePosteReel: number,quantitePosteTheorique: number,trpHeureReel: number,trpPosteReel: number,trpObjectif: number,consoAir: number,consoElec: number,status: number)
  {
    this.seqNo = seqNo;
    this.date = date.replace(/ /g,'').replace(/"/g,'');
    this.utcTime = utcTime.replace(/ /g,'');
    this.id = id;
    this.name = name.replace(/"/g,'');
    this.refCharge = refCharge.replace(/ /g,'');
    this.refDecharge = refDecharge.replace(/ /g,'');
    this.quantiteEnCours = quantiteEnCours.replace(/ /g,'');
    this.quantiteHoraireReel = quantiteHoraireReel;
    this.quantiteHoraireTheorique = quantiteHoraireTheorique;
    this.quantitePosteReel = quantitePosteReel;
    this.quantitePosteTheorique = quantitePosteTheorique;
    this.trpHeureReel = trpHeureReel;
    this.trpPosteReel = trpPosteReel;
    this.trpObjectif = trpObjectif;
    this.consoAir = consoAir;
    this.consoElec = consoElec;
    this.status = status;
  }
}

在这个 ts 中,我想从服务接收数组数据以显示

import {Component,Input,OnDestroy,OnInit} from '@angular/core';
import { ChartType } from 'chart.js';
import { Lineservice } from '../services/line.service';
import {ActivatedRoute} from '@angular/router';
import {combineLatest,Subscription} from 'rxjs';
import {filter,map} from 'rxjs/operators';
import {log} from 'util';

@Component({
  selector: 'app-conso-graph',templateUrl: './conso-graph.component.html',styleUrls: ['./conso-graph.component.scss']
})
export class ConsoGraphComponent implements OnDestroy{

  linesubscription: Subscription;
  id: number;
  consoAir: number;
  chartType: ChartType;
  chartOptions: any;
  _time: any[] = Array(10).fill(0);
  _consoAir: any[] = this.lineservice._consoAir;
  
  constructor(private lineservice: Lineservice,private route: ActivatedRoute) {
    this.chartIt();
  }

  _focusedData$ = combineLatest(
    this.lineservice.linesubject.pipe(filter(x => x.length > 0)),this.route.params.pipe(filter(x => !!x.id),map(x => x.id - 1))
  ).pipe(
    map(([csvs,id]) => csvs[id])
  );

  gestionData(): void {
    this.linesubscription = this._focusedData$.subscribe(x => this.id = x.id);
    this._consoAir = this.lineservice._consoAir;
    console.log(this._consoAir[5]);
  }

  async chartIt() {
    await this.gestionData();
    this.chartType = 'line';
  }

  chartClicked(e: any): void { }
  chartHovered(e: any): void { }

  ngOnDestroy(): void {
    this.linesubscription.unsubscribe();
  }

}

在这里,我用 HTML 显示图表:

<div class="doubleTrp">
    <canvas baseChart
            [chartType]="chartType"
            [datasets]="[
              {
              data: this._consoAir[this.id - 1],label: 'Consommation Air'
              }
            ]"
            [labels]="this._time"
            [colors]="[{
              backgroundColor: ['rgb(255,182,0)'],hoverBackgroundColor: ['rgb(185,30,30)'],borderWidth: 1
            }]"
            [options]="{
              responsive: true,cutoutPercentage: 100,title : {
                display: true,text: 'Consommation Air',fontSize: 25
              }
            }"
            [legend]="true"
            (chartHover)="chartHovered($event)"
            (chartClick)="chartClicked($event)">
    </canvas>
</div>

我尝试过 SetInterval、Timer 或其他东西,但在服务中,数组正在实时更改,但不在图形组件中...

每个例子都会对我有帮助。 提前致谢。

解决方法

我通过这样做找到了解决方案:

[datasets]="[
                {
                    data: [ graphikElec[0],graphikElec[1],graphikElec[2],graphikElec[3],graphikElec[4],graphikElec[5],graphikElec[6],graphikElec[7],graphikElec[8],graphikElec[9]
                          ],label: 'kWh'
                },