从服务器更新 ChartJS 图表的数据
Update data from server for ChartJS graph
这几天我的 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),
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], 10), row[4], row[5], row[6], row[7],
parseInt(row[8], 10),
parseInt(row[9], 10),
parseInt(row[10], 10),
parseInt(row[11], 10),
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, '').replace(/"/g, '');
this.id = id;
this.name = name.replace(/"/g, '');
this.refCharge = refCharge.replace(/ /g, '').replace(/"/g, '');
this.refDecharge = refDecharge.replace(/ /g, '').replace(/"/g, '');
this.quantiteEnCours = quantiteEnCours.replace(/ /g, '').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'
},
这几天我的 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),
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], 10), row[4], row[5], row[6], row[7],
parseInt(row[8], 10),
parseInt(row[9], 10),
parseInt(row[10], 10),
parseInt(row[11], 10),
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, '').replace(/"/g, '');
this.id = id;
this.name = name.replace(/"/g, '');
this.refCharge = refCharge.replace(/ /g, '').replace(/"/g, '');
this.refDecharge = refDecharge.replace(/ /g, '').replace(/"/g, '');
this.quantiteEnCours = quantiteEnCours.replace(/ /g, '').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'
},