Я новичок в использовании диаграмм, но я создаю компонент для создания диаграммы, используя ng2-диаграммы и данные (температуру), которые каждую секунду получают из службы MQTT. Он отлично работает, но в момент, когда данные обновляются каждую секунду, он получает что-то вроде этого:
Графики обновляются
Я хочу, чтобы каждый определенный кусок обновления, переместитесь вправо, оставив старые данные позади, но не удаляя их. Также хочу, чтобы пользователь мог, перетаскивая мышь влево или вправо, увидеть старые данные или новые.
Я попытался использовать диаграмму js -plugin-zoom, и она работает, но когда я масштабирую или панорамирование, данные исчезают. Также попытался использовать полосу прокрутки, и она просто появляется, но диаграмма никогда не расширяется, поэтому полоса прокрутки остается бесполезной.
Это мой код:
charts.component. html
<div style="display: block">
<canvas baseChart [datasets]="chartData" [labels]="chartLabels" [options]="chartOptions"
[legend]="chartLegend" [chartType]="chartType" (chartHover)="chartHovered($event)"
(chartClick)="chartClicked($event)">
</canvas>
</div>
charts.component.ts
import { Component, OnInit, Input } from '@angular/core';
import { ChartOptions, ChartType, ChartDataSets } from 'chart.js';
import { Label } from 'ng2-charts';
import 'chartjs-plugin-zoom';
import 'hammerjs';
@Component({
selector: 'app-charts',
templateUrl: './charts.component.html',
styleUrls: ['./charts.component.css']
})
export class ChartsComponent implements OnInit {
@Input() typeChart: ChartType;
@Input() typeLabel: Label;
@Input() set chartAppOptions(options) {
if (this.typeLabel) { this.typeLabel = this.updateLabel(this.typeLabel); }
for (const option of options) {
// console.log(option);
this.addValuesChartData(option);
}
}
date = new Date();
chartOptions: ChartOptions = {
responsive: true,
// We use these empty structures as placeholders for dynamic theming.
scales: { xAxes: [{ticks: {beginAtZero: true}}], yAxes: [{}] },
plugins: {
zoom: {
pan: {
enabled: true,
mode: 'xy',
},
zoom: {
enabled: true,
mode: 'xy',
},
}
}
};
chartLabels: Label[] = [];
chartType: ChartType = 'line';
chartLegend = true;
chartData: ChartDataSets[] = [
{data: [], label: '' }
];
constructor() {}
ngOnInit() {
if (this.typeChart) { this.chartType = this.typeChart; }
}
updateLabel(label: Label) {
let labelString: Label;
if (!label) {
label = 'date';
}
switch (label) {
case 'date':
labelString =
`${this.date.getDate()}/${this.date.getMonth() + 1}/${this.date.getFullYear()} ${this.date.getHours()}:${this.date.getMinutes()}`;
break;
default:
labelString = label;
break;
}
return labelString;
}
addValuesChartData({name, value}) {
const emptyChartData = this.findInArray(this.chartData, '', 'label');
const notFound = -1;
if (!value) {
value = 0;
}
if (emptyChartData !== notFound) {
this.chartData[emptyChartData].label = name;
}
const positionChartData = this.findInArray(this.chartData, name, 'label');
if (positionChartData === notFound) {
const newChartData: ChartDataSets = {
data: [],
label: name
};
this.chartData.push(newChartData);
const newChartDataLabelPosition = this.findInArray(this.chartData, name, 'label');
this.chartData[newChartDataLabelPosition].data.push(value);
} else {
this.chartData[positionChartData].data.push(value);
}
const lengthChartData = this.chartData[0].data.length;
const lenghtChartLabels = this.chartLabels.length;
if (lengthChartData !== lenghtChartLabels) {
this.chartLabels.push(this.typeLabel);
}
}
findInArray(arr, name, extension) {
return arr.findIndex(item => item[extension] === name);
}
// events
chartClicked({ event, active }: { event: MouseEvent, active: {}[] }): void {}
chartHovered({ event, active }: { event: MouseEvent, active: {}[] }): void {}
}
Вот как Звоню компонент со страницы:
html
<div>
<app-charts [chartAppOptions]="chartAppOptions4" typeLabel="date" typeChart="line"></app-charts>
</div>
ц
import { Component } from '@angular/core';
import { MqttSvc } from 'src/app/services/mqtt.service';
@Component({
selector: 'app-chart',
templateUrl: './chart.component.html',
styleUrls: ['./chart.component.css']
})
export class ChartComponent {
chartAppOptions4 = [
{
name: 'Temperatura',
value: 0,
},
{
name: 'Temperatura * 2',
value: 0,
},
{
name: 'Temperatura * 3',
value: 0,
},
{
name: 'Temperatura * 4',
value: 0,
}
];
subscribe: any;
constructor( private mqttSvc: MqttSvc) {}
connect() {
console.log('connected');
this.subscribe = this.mqttSvc.connect(SERVIDOR/API).subscribe(data => {
const temp = Number(data.payload.toString());
console.log(temp);
this.changeChartAppOptions(temp);
});
}
disconnect() {
console.log('disconnect');
this.subscribe.unsubscribe();
}
changeChartAppOptions(temp: number) {
for (let i = 0, n = this.chartAppOptions4.length; i < n; i++) {
const j = i + 1;
if (this.chartAppOptions4[i].value !== temp * j) {
this.chartAppOptions4 = [
{
name: 'Temperatura',
value: temp,
},
{
name: 'Temperatura * ' + j,
value: temp * j,
},
{
name: 'Temperatura * ' + j,
value: temp * j,
},
{
name: 'Temperatura * ' + j,
value: temp * j,
}
];
}
}
}
}