import { Component, OnInit, ViewChild, inject } from '@angular/core'; import { STColumn, STComponent } from '@delon/abc/st'; import { SFSchema } from '@delon/form'; import { ModalHelper, _HttpClient } from '@delon/theme'; import { SHARED_IMPORTS } from '@shared'; import { DataVCardComponent } from '../card/card.component'; import * as echarts from 'echarts'; import { AgGridAngular } from 'ag-grid-angular'; import { DataVTitleComponent } from '../title/title.component'; import { ColDef } from 'ag-grid-community'; // Column Definition Type Interface import { NzProgressModule } from 'ng-zorro-antd/progress'; import { NzBadgeModule } from 'ng-zorro-antd/badge'; import { Subscription } from 'rxjs'; import { IMqttMessage, MqttService } from 'ngx-mqtt'; import { ChartComponentComponent } from './chart-component/chart-component.component'; @Component({ selector: 'app-data-v-s1', standalone: true, templateUrl: './s1.component.html', styleUrls: ['./s1.component.less'], imports: [NzBadgeModule, NzProgressModule, AgGridAngular, DataVCardComponent, DataVTitleComponent, ...SHARED_IMPORTS, ChartComponentComponent] }) export class DataVS1Component implements OnInit { private readonly http = inject(_HttpClient); private readonly modal = inject(ModalHelper); chart_options1 = {} c1OptionC: echarts.EChartsOption = { series: [ { type: 'gauge', startAngle: 180, endAngle: 0, center: ['50%', '75%'], radius: '90%', min: 0, max: 1, splitNumber: 8, axisLine: { lineStyle: { width: 6, color: [ [0.25, '#74FAFB'], [0.5, '#74FAFB'], [0.75, '#74FAFB'], [1, '#74FAFB'] ] } }, pointer: { icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z', length: '12%', width: 20, offsetCenter: [0, '-60%'], itemStyle: { color: 'auto' } }, axisTick: { length: 12, lineStyle: { color: 'auto', width: 2 } }, splitLine: { length: 20, lineStyle: { color: 'auto', width: 5 } }, axisLabel: { color: '#464646', fontSize: 20, distance: -60, rotate: 'tangential', formatter: function (value: any) { if (value === 0.875) { return ''; } else if (value === 0.625) { return ''; } else if (value === 0.375) { return ''; } else if (value === 0.125) { return ''; } return ''; } }, title: { offsetCenter: [0, '-10%'], fontSize: 20 }, detail: { fontSize: 30, offsetCenter: [0, '-5%'], valueAnimation: true, formatter: function (value: any) { return Math.round(value * 100) + ''; }, color: 'inherit' }, data: [ { value: 0.9, name: '' } ] } ] }; private c1Chart: any; rowData = [ { rwmc: '任务1', rwms: '任务描述1', kssj: '2024-1-1', jhwcsj: '2024-1-2', sfcq: '否', dqzt: '正常', dqjd: '节点1', sjwcsj: '2024-1-2', bjmc: '报警1', bjms: '报警描述1', bjsj: '2024-1-1', gzyy: '-', clff: '-', tzsj: '2024-1-2', zycd: '一般', tzmc: '系统提示', tznr: '账户登录', fj: '-' }, { rwmc: '任务2', rwms: '任务描述2', kssj: '2024-1-2', jhwcsj: '2024-1-3', sfcq: '否', dqzt: '正常', dqjd: '节点2', sjwcsj: '2024-1-2', bjmc: '报警2', bjms: '报警描述2', bjsj: '2024-1-2', gzyy: '-', clff: '-', tzsj: '2024-1-2', zycd: '一般', tzmc: '系统提示', tznr: '账户登录', fj: '-' }, { rwmc: '任务3', rwms: '任务描述3', kssj: '2024-1-3', jhwcsj: '2024-1-4', sfcq: '否', dqzt: '正常', dqjd: '节点3', sjwcsj: '2024-1-2', bjmc: '报警3', bjms: '报警描述3', bjsj: '2024-1-3', gzyy: '-', clff: '-', tzsj: '2024-1-2', zycd: '一般', tzmc: '系统提示', tznr: '账户登录', fj: '-' }, { rwmc: '任务4', rwms: '任务描述4', kssj: '2024-1-4', jhwcsj: '2024-1-5', sfcq: '否', dqzt: '正常', dqjd: '节点4', sjwcsj: '2024-1-2', bjmc: '报警4', bjms: '报警描述4', bjsj: '2024-1-4', gzyy: '-', clff: '-', tzsj: '2024-1-2', zycd: '一般', tzmc: '系统提示', tznr: '账户登录', fj: '-' }, { rwmc: '任务5', rwms: '任务描述5', kssj: '2024-1-5', jhwcsj: '2024-1-6', sfcq: '否', dqzt: '正常', dqjd: '节点5', sjwcsj: '2024-1-2', bjmc: '报警5', bjms: '报警描述5', bjsj: '2024-1-5', gzyy: '-', clff: '-', tzsj: '2024-1-2', zycd: '一般', tzmc: '系统提示', tznr: '账户登录', fj: '-' } ]; colDefs1: ColDef[] = [ { headerName: '时间', field: 'rwmc', flex: 1 }, { headerName: '系统/设备', field: 'rwms', flex: 1 }, { headerName: '操作描述', field: 'kssj', flex: 1 }, { headerName: '操作人员', field: 'jhwcsj', flex: 1 } ]; colDefs2: ColDef[] = [ { headerName: '序号', field: 'rwmc', flex: 1 }, { headerName: '时间', field: 'kssj', flex: 2 }, { headerName: '任务描述', field: 'rwms', flex: 1 }, { headerName: '等级', field: 'dqzt', flex: 1.5 } ]; private subscription: Subscription; constructor(private _mqttService: MqttService) { this.subscription = this._mqttService.observe('s1').subscribe((message: IMqttMessage) => { const messagePayload = JSON.parse(message.payload.toString()); console.log('Received message as object: ', messagePayload.msg); this.c1Chart.setOption(this.c1OptionC); }); } ngOnInit(): void { var c1 = document.getElementById('c1')!; this.c1Chart = echarts.init(c1); var c2 = document.getElementById('c2')!; var c2Chart = echarts.init(c2); let c2OptionC = { series: [ { type: 'gauge', startAngle: 180, endAngle: 0, center: ['50%', '75%'], radius: '90%', min: 0, max: 1, splitNumber: 8, axisLine: { lineStyle: { width: 6, color: [ [0.25, '#74FAFB'], [0.5, '#74FAFB'], [0.75, '#74FAFB'], [1, '#74FAFB'] ] } }, pointer: { icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z', length: '12%', width: 20, offsetCenter: [0, '-60%'], itemStyle: { color: 'auto' } }, axisTick: { length: 12, lineStyle: { color: 'auto', width: 2 } }, splitLine: { length: 20, lineStyle: { color: 'auto', width: 5 } }, axisLabel: { color: '#464646', fontSize: 20, distance: -60, rotate: 'tangential', formatter: function (value: any) { if (value === 0.875) { return ''; } else if (value === 0.625) { return ''; } else if (value === 0.375) { return ''; } else if (value === 0.125) { return ''; } return ''; } }, title: { offsetCenter: [0, '0%'], fontSize: 20 }, detail: { fontSize: 30, offsetCenter: [0, '-5%'], valueAnimation: true, formatter: function (value: any) { return Math.round(value * 100) + ''; }, color: 'inherit' }, data: [ { value: 0.97, name: '' } ] } ] }; var d1 = document.getElementById('d1'); var d1Chart = echarts.init(d1, 'dark'); var d2 = document.getElementById('d2'); var d2Chart = echarts.init(d2, 'dark'); // var d3 = document.getElementById('d3'); // var d3Chart = echarts.init(d3, 'dark'); var errorData = []; var categoryData = []; var barData = []; var dataCount = 100; for (var i = 0; i < dataCount; i++) { var val = Math.random() * 1000; categoryData.push('category' + i); errorData.push([ i, echarts.number.round(Math.max(0, val - Math.random() * 100)), echarts.number.round(val + Math.random() * 80) ]); barData.push(echarts.number.round(val, 2)); } var optionD1; optionD1 = { title: { text: '全水', subtext: '(kg/kg)' }, tooltip: { trigger: 'axis' }, legend: { data: ['测量值', '上限值', '下限值',] }, grid: { left: '3%', right: '3%', bottom: '3%', containLabel: true }, toolbox: { show: false, feature: { dataView: { show: true, readOnly: false }, magicType: { show: true, type: ['line', 'bar'] }, restore: { show: true }, saveAsImage: { show: true } } }, calculable: true, xAxis: [ { type: 'category', data: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'] } ], yAxis: [ { type: 'value' } ], series: [ { name: '测量值', type: 'line', data: [100, 155, 139, 199, 220, 160, 120, 182.2, 150, 155, 160, 180], markPoint: { data: [ { name: 'Max', value: 220, xAxis: 4, yAxis: 220 }, { name: 'Min', value: 100, xAxis: 0, yAxis: 100 } ] }, markLine: { data: [{ type: 'average', name: 'Avg' }] } }, { type: 'custom', name: 'error', itemStyle: { borderWidth: 1.5 }, renderItem: function (_params: any, api: any) { var xValue = api.value(0); var highPoint = api.coord([xValue, api.value(1)]); var lowPoint = api.coord([xValue, api.value(2)]); var halfWidth = api.size([1, 0])[0] * 0.1; var style = api.style({ stroke: api.visual('color'), fill: undefined }); return { type: 'group', children: [ { type: 'line', transition: ['shape'], shape: { x1: highPoint[0] - halfWidth, y1: highPoint[1], x2: highPoint[0] + halfWidth, y2: highPoint[1] }, style: style }, { type: 'line', transition: ['shape'], shape: { x1: highPoint[0], y1: highPoint[1], x2: lowPoint[0], y2: lowPoint[1] }, style: style }, { type: 'line', transition: ['shape'], shape: { x1: lowPoint[0] - halfWidth, y1: lowPoint[1], x2: lowPoint[0] + halfWidth, y2: lowPoint[1] }, style: style } ] }; }, encode: { x: 0, y: [1, 2] }, data: errorData, z: 100 } ] }; this.chart_options1 = { title: { textStyle: { color: "#ffffff" }, text: '全水', subtext: '(kg/kg)', }, legend: { data: ['测量值', '上限值', '下限值',] }, calculable: true, xAxis: [ { axisLine: { lineStyle: { color: [ [0.25, '#74FAFB'], [0.5, '#74FAFB'], [0.75, '#74FAFB'], [1, '#74FAFB'] ] } }, position: 'bottom', type: 'category', data: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'] } ], yAxis: [ { type: 'value' } ], series: [ { name: '测量值', type: 'line', data: [100, 155, 139, 199, 220, 160, 120, 182.2, 150, 155, 160, 180], markPoint: { data: [ { name: '最大值', value: 220, xAxis: 4, yAxis: 220 }, { name: '最小值', value: 100, xAxis: 0, yAxis: 100 } ] }, markLine: { data: [{ type: 'average', name: '平均值' }] } }, { type: 'custom', name: 'error', itemStyle: { borderWidth: 1.5 }, renderItem: function (_params: any, api: any) { var xValue = api.value(0); var highPoint = api.coord([xValue, api.value(1)]); var lowPoint = api.coord([xValue, api.value(2)]); var halfWidth = api.size([1, 0])[0] * 0.1; var style = api.style({ stroke: api.visual('color'), fill: undefined }); return { type: 'group', children: [ { type: 'line', transition: ['shape'], shape: { x1: highPoint[0] - halfWidth, y1: highPoint[1], x2: highPoint[0] + halfWidth, y2: highPoint[1] }, style: style }, { type: 'line', transition: ['shape'], shape: { x1: highPoint[0], y1: highPoint[1], x2: lowPoint[0], y2: lowPoint[1] }, style: style }, { type: 'line', transition: ['shape'], shape: { x1: lowPoint[0] - halfWidth, y1: lowPoint[1], x2: lowPoint[0] + halfWidth, y2: lowPoint[1] }, style: style } ] }; }, encode: { x: 0, y: [1, 2] }, data: errorData, z: 100 } ] }; var optionD2; optionD2 = { title: { text: '热值', subtext: '(kg/kg)' }, grid: { left: '3%', right: '3%', bottom: '3%', containLabel: true }, tooltip: { trigger: 'axis' }, legend: { data: ['超差样数量', '不合格样数量'] }, toolbox: { show: false, feature: { dataView: { show: true, readOnly: false }, magicType: { show: true, type: ['line', 'bar'] }, restore: { show: true }, saveAsImage: { show: true } } }, calculable: true, xAxis: [ { type: 'category', // prettier-ignore data: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'] } ], yAxis: [ { type: 'value' } ], series: [ { name: '超差样数量', type: 'line', data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3], markPoint: { data: [ { type: 'max', name: 'Max' }, { type: 'min', name: 'Min' } ] } }, { name: '不合格样数量', type: 'bar', data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3], markPoint: { data: [ { name: 'Max', value: 182.2, xAxis: 7, yAxis: 183 }, { name: 'Min', value: 2.3, xAxis: 11, yAxis: 3 } ] }, markLine: { data: [{ type: 'average', name: 'Avg' }] } } ] }; var optionD3; optionD3 = { title: { text: '全硫', subtext: '(kg/kg)' }, tooltip: { trigger: 'axis' }, legend: { data: ['超差样数量', '不合格样数量'] }, toolbox: { show: false, feature: { dataView: { show: true, readOnly: false }, magicType: { show: true, type: ['line', 'bar'] }, restore: { show: true }, saveAsImage: { show: true } } }, calculable: true, xAxis: [ { type: 'category', // prettier-ignore data: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'] } ], yAxis: [ { type: 'value' } ], series: [ { name: '超差样数量', type: 'line', data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3], markPoint: { data: [ { type: 'max', name: 'Max' }, { type: 'min', name: 'Min' } ] } }, { name: '不合格样数量', type: 'bar', data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3], markPoint: { data: [ { name: 'Max', value: 182.2, xAxis: 7, yAxis: 183 }, { name: 'Min', value: 2.3, xAxis: 11, yAxis: 3 } ] }, markLine: { data: [{ type: 'average', name: 'Avg' }] } } ] }; optionD1 && d1Chart.setOption(optionD1); optionD2 && d2Chart.setOption(optionD2); this.c1Chart.setOption(this.c1OptionC); c2Chart.setOption(c2OptionC); var r1 = document.getElementById('r1'); var r1Chart = echarts.init(r1, 'dark'); var r2 = document.getElementById('r2'); var r2Chart = echarts.init(r2, 'dark'); var r1SuperCount = 3; // 超差样量 var r1TotalCount = 16; // 总样量 var r2SuperCount = 15; // 合格样量 var r2TotalCount = 16; // 总样量 // 计算超差率 var r1SuperRate = (r1SuperCount / r1TotalCount * 100).toFixed(2); // 保留两位小数 // 计算合格率 var r2SuperRate = (r2SuperCount / r2TotalCount * 100).toFixed(2); // 保留两位小数 // Echarts配置项 var r1Option = { title: { text: '煤样超差率', subtext: '超差率:' + r1SuperRate + '%' }, tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } }, grid: { top: '10%', left: '3%', right: '4%', bottom: '3%', containLabel: true }, xAxis: { type: 'category', data: ['超差样量', '总样量'] }, yAxis: { type: 'value' }, series: [{ data: [r1SuperCount, r1TotalCount], type: 'bar' }] }; // Echarts配置项 var r2Option = { title: { text: '煤样合格率', subtext: '合格率:' + r2SuperRate + '%' }, tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } }, grid: { top: '10%', left: '3%', right: '4%', bottom: '3%', containLabel: true }, xAxis: { type: 'category', data: ['超差样量', '总样量'] }, yAxis: { type: 'value' }, series: [{ data: [r2SuperCount, r2TotalCount], type: 'bar' }] }; r1Chart.setOption(r1Option); r2Chart.setOption(r2Option); // myChart.setOption({ // title: { // text: 'ECharts 入门示例' // }, // tooltip: {}, // xAxis: { // data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] // }, // yAxis: {}, // series: [ // { // name: '销量', // type: 'bar', // data: [5, 20, 36, 10, 10, 20] // } // ] // }); } add(): void { } public unsafePublish(topic: string, message: string): void { this._mqttService.unsafePublish(topic, message, { qos: 1, retain: true }); } ngOnDestroy(): void { this.subscription.unsubscribe(); } }