数据可视化大屏
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

s1.component.ts 16KB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585
  1. import { Component, OnInit, ViewChild, inject } from '@angular/core';
  2. import { STColumn, STComponent } from '@delon/abc/st';
  3. import { SFSchema } from '@delon/form';
  4. import { CommonModule } from '@angular/common';
  5. import { ModalHelper, _HttpClient } from '@delon/theme';
  6. import { SHARED_IMPORTS } from '@shared';
  7. import { DataVCardComponent } from '../card/card.component';
  8. import * as echarts from 'echarts';
  9. import { AgGridAngular } from 'ag-grid-angular';
  10. import { DataVTitleComponent } from '../title/title.component';
  11. import { ColDef } from 'ag-grid-community'; // Column Definition Type Interface
  12. import { NzProgressModule } from 'ng-zorro-antd/progress';
  13. import { NzBadgeModule } from 'ng-zorro-antd/badge';
  14. import { Subscription, finalize } from 'rxjs';
  15. import { IMqttMessage, MqttService } from 'ngx-mqtt';
  16. import { ChartComponentComponent } from './chart-component/chart-component.component';
  17. import { NzListModule } from 'ng-zorro-antd/list';
  18. import { TitleService } from '@delon/theme';
  19. @Component({
  20. selector: 'app-data-v-s1',
  21. standalone: true,
  22. templateUrl: './s1.component.html',
  23. styleUrls: ['./s1.component.less'],
  24. imports: [
  25. CommonModule,
  26. NzBadgeModule,
  27. NzProgressModule,
  28. AgGridAngular,
  29. DataVCardComponent,
  30. DataVTitleComponent,
  31. NzListModule,
  32. ...SHARED_IMPORTS,
  33. ChartComponentComponent
  34. ]
  35. })
  36. export class DataVS1Component implements OnInit {
  37. private readonly http = inject(_HttpClient);
  38. private readonly modal = inject(ModalHelper);
  39. chartConfig = {
  40. //每行数
  41. rowNumber: 1,
  42. //check 表格
  43. optionsCheckList: [
  44. { label: '全水', options: {}, checked: true },
  45. { label: '热值', options: {}, checked: true },
  46. { label: '全硫', options: {}, checked: false },
  47. { label: '内水', options: {}, checked: false },
  48. { label: '灰分', options: {}, checked: false },
  49. { label: '挥发分', options: {}, checked: false }
  50. ],
  51. //底部
  52. optionBottomList: [{}],
  53. //左边表格option
  54. optionsList: [
  55. { label: '全水', options: {}, checked: true },
  56. { label: '热值', options: {}, checked: true }
  57. ],
  58. //左边table
  59. tableList: [
  60. {
  61. coldef: [
  62. { headerName: '时间', field: 'rwmc', unSortIcon: true, minWidth: undefined, flex: 1 },
  63. { headerName: '系统/设备', field: 'rwms', unSortIcon: true, minWidth: undefined, flex: 1 },
  64. { headerName: '操作描述', field: 'kssj', unSortIcon: true, minWidth: undefined, flex: 1 },
  65. { headerName: '操作人员', field: 'jhwcsj', unSortIcon: true, minWidth: undefined, flex: 1 }
  66. ],
  67. rowData: []
  68. },
  69. {
  70. coldef: [
  71. { headerName: '序号', field: 'rwmc', unSortIcon: true, minWidth: undefined, flex: 1 },
  72. { headerName: '时间', field: 'kssj', unSortIcon: true, minWidth: undefined, flex: 1 },
  73. { headerName: '任务描述', field: 'rwms', unSortIcon: true, minWidth: undefined, flex: 1 },
  74. { headerName: '等级', field: 'dqzt', unSortIcon: true, minWidth: undefined, flex: 1 }
  75. ],
  76. rowData: []
  77. }
  78. ]
  79. };
  80. handleCheckedItems(checkedItems: { label: string; checked: boolean }[]) {
  81. console.log('当前选中的项目:', checkedItems);
  82. }
  83. chart_options = {};
  84. chart_options0 = {};
  85. chart_options1 = {};
  86. chart_options2 = {};
  87. chart_options3 = {};
  88. chart_options4 = {};
  89. rowData: object[] = [];
  90. colDefs1: ColDef[] = [
  91. { headerName: '时间', field: 'rwmc', flex: 1 },
  92. { headerName: '系统/设备', field: 'rwms', flex: 1 },
  93. { headerName: '操作描述', field: 'kssj', flex: 1 },
  94. { headerName: '操作人员', field: 'jhwcsj', flex: 1 }
  95. ];
  96. colDefs2: ColDef[] = [
  97. { headerName: '序号', field: 'rwmc', flex: 1 },
  98. { headerName: '时间', field: 'kssj', flex: 2 },
  99. { headerName: '任务描述', field: 'rwms', flex: 1 },
  100. { headerName: '等级', field: 'dqzt', flex: 1.5 }
  101. ];
  102. private subscription: Subscription;
  103. constructor(private _mqttService: MqttService) {
  104. this.subscription = this._mqttService.observe('s1').subscribe((message: IMqttMessage) => {
  105. const messagePayload = JSON.parse(message.payload.toString());
  106. console.log('Received message as object: ', messagePayload.msg);
  107. this.chart_options0 = messagePayload.msg;
  108. });
  109. }
  110. ngOnInit(): void {
  111. /** 获取服务器配置 */
  112. this.getServerConfig();
  113. for (var i = 1; i < 30; i++) {
  114. this.rowData.push({
  115. rwmc: '任务' + i,
  116. rwms: '任务描述' + i,
  117. kssj: '2024-1-' + i + ' 13:38:' + i * 11,
  118. jhwcsj: '2024-1-' + i + ' 13:38:' + i * 10,
  119. sfcq: '否',
  120. dqzt: '正常',
  121. dqjd: '节点' + i,
  122. sjwcsj: '2024-1-' + i + ' 13:38:' + i * 27,
  123. bjmc: '报警5',
  124. bjms: '报警描述5',
  125. bjsj: '2024-1-' + i + ' 13:38:' + i * 12,
  126. gzyy: '-',
  127. clff: '-',
  128. tzsj: '2024-1-' + i + ' 13:38:' + i * 19,
  129. zycd: '一般',
  130. tzmc: '系统提示',
  131. tznr: '账户登录',
  132. fj: '-',
  133. cz: '操作'
  134. });
  135. }
  136. var errorData = [];
  137. var categoryData = [];
  138. var barData = [];
  139. var dataCount = 100;
  140. for (var i = 0; i < dataCount; i++) {
  141. var val = Math.random() * 1000;
  142. categoryData.push('category' + i);
  143. errorData.push([i, echarts.number.round(Math.max(0, val - Math.random() * 100)), echarts.number.round(val + Math.random() * 80)]);
  144. barData.push(echarts.number.round(val, 2));
  145. }
  146. this.chart_options = {
  147. backgroundColor: 'transparent',
  148. series: [
  149. {
  150. type: 'gauge',
  151. startAngle: 180,
  152. endAngle: 0,
  153. center: ['50%', '75%'],
  154. radius: '90%',
  155. min: 0,
  156. max: 1,
  157. splitNumber: 8,
  158. axisLine: {
  159. lineStyle: {
  160. width: 6,
  161. color: [
  162. [0.25, '#74FAFB'],
  163. [0.5, '#74FAFB'],
  164. [0.75, '#74FAFB'],
  165. [1, '#74FAFB']
  166. ]
  167. }
  168. },
  169. pointer: {
  170. icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z',
  171. length: '12%',
  172. width: 20,
  173. offsetCenter: [0, '-60%'],
  174. itemStyle: {
  175. color: 'auto'
  176. }
  177. },
  178. axisTick: {
  179. length: 12,
  180. lineStyle: {
  181. color: 'auto',
  182. width: 2
  183. }
  184. },
  185. splitLine: {
  186. length: 20,
  187. lineStyle: {
  188. color: 'auto',
  189. width: 5
  190. }
  191. },
  192. axisLabel: {
  193. color: '#464646',
  194. fontSize: 20,
  195. distance: -60,
  196. rotate: 'tangential',
  197. formatter: function (value: any) {
  198. if (value === 0.875) {
  199. return '';
  200. } else if (value === 0.625) {
  201. return '';
  202. } else if (value === 0.375) {
  203. return '';
  204. } else if (value === 0.125) {
  205. return '';
  206. }
  207. return '';
  208. }
  209. },
  210. title: {
  211. offsetCenter: [0, '-10%'],
  212. fontSize: 20
  213. },
  214. detail: {
  215. fontSize: 30,
  216. offsetCenter: [0, '-5%'],
  217. valueAnimation: true,
  218. formatter: function (value: any) {
  219. return Math.round(value * 100) + '';
  220. },
  221. color: 'inherit'
  222. },
  223. data: [
  224. {
  225. value: 0.9,
  226. name: ''
  227. }
  228. ]
  229. }
  230. ]
  231. };
  232. this.chart_options0 = {
  233. backgroundColor: 'transparent',
  234. series: [
  235. {
  236. type: 'gauge',
  237. startAngle: 180,
  238. endAngle: 0,
  239. center: ['50%', '75%'],
  240. radius: '90%',
  241. min: 0,
  242. max: 1,
  243. splitNumber: 8,
  244. axisLine: {
  245. lineStyle: {
  246. width: 6,
  247. color: [
  248. [0.25, '#74FAFB'],
  249. [0.5, '#74FAFB'],
  250. [0.75, '#74FAFB'],
  251. [1, '#74FAFB']
  252. ]
  253. }
  254. },
  255. pointer: {
  256. icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z',
  257. length: '12%',
  258. width: 20,
  259. offsetCenter: [0, '-60%'],
  260. itemStyle: {
  261. color: 'auto'
  262. }
  263. },
  264. axisTick: {
  265. length: 12,
  266. lineStyle: {
  267. color: 'auto',
  268. width: 2
  269. }
  270. },
  271. splitLine: {
  272. length: 20,
  273. lineStyle: {
  274. color: 'auto',
  275. width: 5
  276. }
  277. },
  278. axisLabel: {
  279. color: '#464646',
  280. fontSize: 20,
  281. distance: -60,
  282. rotate: 'tangential',
  283. formatter: function (value: any) {
  284. if (value === 0.875) {
  285. return '';
  286. } else if (value === 0.625) {
  287. return '';
  288. } else if (value === 0.375) {
  289. return '';
  290. } else if (value === 0.125) {
  291. return '';
  292. }
  293. return '';
  294. }
  295. },
  296. title: {
  297. offsetCenter: [0, '0%'],
  298. fontSize: 20
  299. },
  300. detail: {
  301. fontSize: 30,
  302. offsetCenter: [0, '-5%'],
  303. valueAnimation: true,
  304. formatter: function (value: any) {
  305. return Math.round(value * 100) + '';
  306. },
  307. color: 'inherit'
  308. },
  309. data: [
  310. {
  311. value: 0.97,
  312. name: ''
  313. }
  314. ]
  315. }
  316. ]
  317. };
  318. this.chart_options1 = {
  319. title: {
  320. textStyle: {
  321. color: '#ffffff'
  322. },
  323. text: '全水',
  324. subtext: '(kg/kg)'
  325. },
  326. legend: {
  327. data: ['测量值', '上限值', '下限值']
  328. },
  329. calculable: true,
  330. xAxis: [
  331. {
  332. axisLine: {
  333. lineStyle: {
  334. color: [
  335. [0.25, '#74FAFB'],
  336. [0.5, '#74FAFB'],
  337. [0.75, '#74FAFB'],
  338. [1, '#74FAFB']
  339. ]
  340. }
  341. },
  342. position: 'bottom',
  343. type: 'category',
  344. data: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']
  345. }
  346. ],
  347. yAxis: [
  348. {
  349. type: 'value'
  350. }
  351. ],
  352. series: [
  353. {
  354. name: '测量值',
  355. type: 'line',
  356. data: [100, 155, 139, 199, 220, 160, 120, 182.2, 150, 155, 160, 180],
  357. markPoint: {
  358. data: [
  359. { name: '最大值', value: 220, xAxis: 4, yAxis: 220 },
  360. { name: '最小值', value: 100, xAxis: 0, yAxis: 100 }
  361. ]
  362. },
  363. markLine: {
  364. data: [{ type: 'average', name: '平均值' }]
  365. }
  366. },
  367. {
  368. type: 'custom',
  369. name: 'error',
  370. itemStyle: {
  371. borderWidth: 1.5
  372. },
  373. renderItem: function (_params: any, api: any) {
  374. var xValue = api.value(0);
  375. var highPoint = api.coord([xValue, api.value(1)]);
  376. var lowPoint = api.coord([xValue, api.value(2)]);
  377. var halfWidth = api.size([1, 0])[0] * 0.1;
  378. var style = api.style({
  379. stroke: api.visual('color'),
  380. fill: undefined
  381. });
  382. return {
  383. type: 'group',
  384. children: [
  385. {
  386. type: 'line',
  387. transition: ['shape'],
  388. shape: {
  389. x1: highPoint[0] - halfWidth,
  390. y1: highPoint[1],
  391. x2: highPoint[0] + halfWidth,
  392. y2: highPoint[1]
  393. },
  394. style: style
  395. },
  396. {
  397. type: 'line',
  398. transition: ['shape'],
  399. shape: {
  400. x1: highPoint[0],
  401. y1: highPoint[1],
  402. x2: lowPoint[0],
  403. y2: lowPoint[1]
  404. },
  405. style: style
  406. },
  407. {
  408. type: 'line',
  409. transition: ['shape'],
  410. shape: {
  411. x1: lowPoint[0] - halfWidth,
  412. y1: lowPoint[1],
  413. x2: lowPoint[0] + halfWidth,
  414. y2: lowPoint[1]
  415. },
  416. style: style
  417. }
  418. ]
  419. };
  420. },
  421. encode: {
  422. x: 0,
  423. y: [1, 2]
  424. },
  425. data: errorData,
  426. z: 100
  427. }
  428. ]
  429. };
  430. this.chart_options2 = {
  431. title: {
  432. text: '热值',
  433. subtext: '(kg/kg)'
  434. },
  435. legend: {
  436. data: ['超差样数量', '不合格样数量']
  437. },
  438. xAxis: [
  439. {
  440. type: 'category',
  441. // prettier-ignore
  442. data: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']
  443. }
  444. ],
  445. yAxis: [
  446. {
  447. type: 'value'
  448. }
  449. ],
  450. series: [
  451. {
  452. name: '超差样数量',
  453. type: 'line',
  454. 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],
  455. markPoint: {
  456. data: [
  457. { type: 'max', name: 'Max' },
  458. { type: 'min', name: 'Min' }
  459. ]
  460. }
  461. },
  462. {
  463. name: '不合格样数量',
  464. type: 'bar',
  465. 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],
  466. markPoint: {
  467. data: [
  468. { name: 'Max', value: 182.2, xAxis: 7, yAxis: 183 },
  469. { name: 'Min', value: 2.3, xAxis: 11, yAxis: 3 }
  470. ]
  471. },
  472. markLine: {
  473. data: [{ type: 'average', name: 'Avg' }]
  474. }
  475. }
  476. ],
  477. grid: {
  478. left: '3%',
  479. right: '3%',
  480. bottom: '3%',
  481. containLabel: true
  482. },
  483. toolbox: {
  484. show: false,
  485. feature: {
  486. dataView: { show: true, readOnly: false },
  487. magicType: { show: true, type: ['line', 'bar'] },
  488. restore: { show: true },
  489. saveAsImage: { show: true }
  490. }
  491. },
  492. calculable: true
  493. };
  494. this.chart_options3 = {
  495. title: {
  496. text: '煤样超差率'
  497. },
  498. grid: {
  499. top: '10%',
  500. left: '3%',
  501. right: '4%',
  502. bottom: '3%',
  503. containLabel: true
  504. },
  505. xAxis: {
  506. type: 'category',
  507. data: ['超差样量', '总样量']
  508. },
  509. yAxis: {
  510. type: 'value'
  511. },
  512. series: [
  513. {
  514. data: [3, 16],
  515. label: {
  516. show: true,
  517. position: 'top',
  518. formatter: function (data: { value: string }) {
  519. return data.value;
  520. }
  521. },
  522. type: 'bar'
  523. }
  524. ]
  525. };
  526. this.chart_options4 = {
  527. title: {
  528. text: '煤样合格率',
  529. left: 'center'
  530. },
  531. grid: {
  532. top: '10%',
  533. left: '3%',
  534. right: '4%',
  535. bottom: '3%',
  536. containLabel: true
  537. },
  538. xAxis: {
  539. type: 'category',
  540. data: ['超差样量', '总样量']
  541. },
  542. yAxis: {
  543. type: 'value'
  544. },
  545. series: [
  546. {
  547. data: [15, 16],
  548. type: 'bar',
  549. label: {
  550. show: true,
  551. position: 'top',
  552. formatter: function (data: { value: string }) {
  553. return data.value;
  554. }
  555. }
  556. }
  557. ]
  558. };
  559. //this.chartConfig.optionsCheckList[0].options = this.chart_options1;
  560. this.chartConfig.optionsCheckList[1].options = this.chart_options2;
  561. this.chartConfig.optionsCheckList[2].options = this.chart_options3;
  562. this.chartConfig.optionsCheckList[3].options = this.chart_options4;
  563. this.chartConfig.optionBottomList[0] = this.chart_options3;
  564. this.chartConfig.optionBottomList[1] = this.chart_options4;
  565. }
  566. public unsafePublish(topic: string, message: string): void {
  567. this._mqttService.unsafePublish(topic, message, { qos: 1, retain: true });
  568. }
  569. ngOnDestroy(): void {
  570. this.subscription.unsubscribe();
  571. }
  572. /**
  573. * 服务器获取配置
  574. */
  575. getServerConfig() {
  576. this.http.get('http://localhost:5006/api/config/s1').subscribe(res => {
  577. this.chartConfig.optionsCheckList[0].options = res['data'];
  578. console.log(res);
  579. });
  580. }
  581. }