|
@@ -1,21 +1,164 @@
|
|
|
-import { Component, ViewEncapsulation } from '@angular/core';
|
|
|
+import { Component, ViewEncapsulation, OnInit } from '@angular/core';
|
|
|
import { DatePipe } from '@angular/common';
|
|
|
+import * as echarts from 'echarts';
|
|
|
+import { CommonModule } from '@angular/common';
|
|
|
+import { FormsModule } from '@angular/forms';
|
|
|
+import { EchartDirective } from '../../shared/directives/echarts.directive';
|
|
|
|
|
|
@Component({
|
|
|
standalone: true,
|
|
|
selector: 'app-device-monitor',
|
|
|
- styleUrls: ['./device-monitor.css'],
|
|
|
- imports: [DatePipe],
|
|
|
templateUrl: './device-monitor.component.html',
|
|
|
+ styleUrls: ['./device-monitor.css'],
|
|
|
+ imports: [
|
|
|
+ DatePipe,
|
|
|
+ CommonModule,
|
|
|
+ FormsModule,
|
|
|
+ EchartDirective
|
|
|
+ ],
|
|
|
encapsulation: ViewEncapsulation.None
|
|
|
})
|
|
|
-export class DeviceMonitorComponent {
|
|
|
-currentTime: Date = new Date();
|
|
|
- ngOnInit(): void {
|
|
|
- // 更新时间,每秒更新一次
|
|
|
+export class DeviceMonitorComponent implements OnInit {
|
|
|
+ currentTime: Date = new Date();
|
|
|
+ vibrationData: number[] = [];
|
|
|
+ upperThreshold = 0.8;
|
|
|
+ lowerThreshold = 0.2;
|
|
|
+ currentAmplitude = 0.58;
|
|
|
+ healthIndex = 89;
|
|
|
+ temperature = 68;
|
|
|
+ rotationSpeed = 1420;
|
|
|
+ chartOptions: any;
|
|
|
+
|
|
|
+ statusValues = [
|
|
|
+ { label: '当前振幅', value: 0.58, unit: 'mm/s', icon: 'fa-wave-square', color: 'blue' },
|
|
|
+ { label: '健康指数', value: 89, unit: '%', icon: 'fa-heartbeat', color: 'green' },
|
|
|
+ { label: '温度', value: 68, unit: '°C', icon: 'fa-thermometer-half', color: 'orange' },
|
|
|
+ { label: '转速', value: 1420, unit: 'RPM', icon: 'fa-tachometer-alt', color: 'purple' }
|
|
|
+ ];
|
|
|
+
|
|
|
+ alertHistory = [
|
|
|
+ { time: '14:30:22', desc: '振动超标 (0.92 mm/s)', level: 'warning' },
|
|
|
+ { time: '11:45:10', desc: '温度异常 (78°C)', level: 'critical' },
|
|
|
+ { time: '09:15:33', desc: '转速波动超出范围', level: 'info' }
|
|
|
+ ];
|
|
|
+
|
|
|
+ ngOnInit(): void {
|
|
|
setInterval(() => {
|
|
|
this.currentTime = new Date();
|
|
|
}, 1000);
|
|
|
|
|
|
- }
|
|
|
-}
|
|
|
+ this.generateVibrationData();
|
|
|
+ this.updateChartOptions();
|
|
|
+
|
|
|
+ setInterval(() => {
|
|
|
+ this.updateSensorData();
|
|
|
+ }, 3000);
|
|
|
+ }
|
|
|
+
|
|
|
+ generateVibrationData(): void {
|
|
|
+ for (let i = 0; i < 200; i++) {
|
|
|
+ const baseValue = Math.sin(i * 0.2) * 0.5;
|
|
|
+ const noise = (Math.random() - 0.5) * 0.2;
|
|
|
+ this.vibrationData.push(baseValue + noise + 0.5);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ updateSensorData(): void {
|
|
|
+ this.currentAmplitude = 0.4 + Math.random() * 0.5;
|
|
|
+ this.healthIndex = Math.max(70, Math.min(95, this.healthIndex + (Math.random() - 0.5) * 5));
|
|
|
+ this.temperature = Math.max(60, Math.min(75, this.temperature + (Math.random() - 0.5) * 2));
|
|
|
+ this.rotationSpeed = 1400 + Math.floor(Math.random() * 50);
|
|
|
+
|
|
|
+ this.statusValues[0].value = parseFloat(this.currentAmplitude.toFixed(2));
|
|
|
+ this.statusValues[1].value = Math.round(this.healthIndex);
|
|
|
+ this.statusValues[2].value = Math.round(this.temperature);
|
|
|
+ this.statusValues[3].value = this.rotationSpeed;
|
|
|
+
|
|
|
+ // 更新振动数据
|
|
|
+ this.vibrationData.shift();
|
|
|
+ const newValue = 0.4 + Math.random() * 0.6;
|
|
|
+ this.vibrationData.push(newValue);
|
|
|
+
|
|
|
+ // 更新图表
|
|
|
+ this.updateChartOptions();
|
|
|
+ }
|
|
|
+
|
|
|
+ updateChartOptions(): void {
|
|
|
+ this.chartOptions = {
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
+ formatter: (params: any) => {
|
|
|
+ const value = params[0].value;
|
|
|
+ let status = '正常';
|
|
|
+ if (value > this.upperThreshold) status = '超标';
|
|
|
+ if (value < this.lowerThreshold) status = '过低';
|
|
|
+
|
|
|
+ return `时间: ${params[0].name}<br/>振幅: ${value.toFixed(2)} mm/s<br/>状态: ${status}`;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ left: '3%',
|
|
|
+ right: '4%',
|
|
|
+ bottom: '12%',
|
|
|
+ top: '10%',
|
|
|
+ containLabel: true
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ boundaryGap: false,
|
|
|
+ data: Array.from({length: 200}, (_, i) => `${i*0.2}s`),
|
|
|
+ axisLine: { show: false },
|
|
|
+ axisTick: { show: false },
|
|
|
+ axisLabel: { show: false }
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: 'value',
|
|
|
+ min: 0,
|
|
|
+ max: 1.5,
|
|
|
+ splitLine: {
|
|
|
+ lineStyle: { color: 'rgba(0, 0, 0, 0.05)' }
|
|
|
+ },
|
|
|
+ axisLabel: { formatter: '{value} mm/s' }
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '振动波形',
|
|
|
+ type: 'line',
|
|
|
+ smooth: true,
|
|
|
+ symbol: 'none',
|
|
|
+ sampling: 'average',
|
|
|
+ data: this.vibrationData,
|
|
|
+ lineStyle: { width: 2, color: '#3498db' },
|
|
|
+ areaStyle: {
|
|
|
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
|
+ { offset: 0, color: 'rgba(52, 152, 219, 0.3)' },
|
|
|
+ { offset: 1, color: 'rgba(52, 152, 219, 0.1)' }
|
|
|
+ ])
|
|
|
+ },
|
|
|
+ markLine: {
|
|
|
+ silent: true,
|
|
|
+ symbol: 'none',
|
|
|
+ lineStyle: { color: '#e74c3c', width: 1, type: 'dashed' },
|
|
|
+ data: [
|
|
|
+ {
|
|
|
+ name: '阈值上限',
|
|
|
+ yAxis: this.upperThreshold,
|
|
|
+ label: { formatter: '上限: {c} mm/s', position: 'end' }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '阈值下限',
|
|
|
+ yAxis: this.lowerThreshold,
|
|
|
+ label: { formatter: '下限: {c} mm/s', position: 'end' }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ animation: false
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ updateThreshold(): void {
|
|
|
+ this.updateChartOptions();
|
|
|
+ }
|
|
|
+}
|