潘志宝
2025-02-11 d4baadcd4b87f93c9a807e20ba7f10151dfbc45c
提交 | 用户 | 时间
d7fad0 1 <template>
J 2   <el-card shadow="never" class="aui-card--fill">
3     <div class="mod-his__index">
1cdc15 4       <el-form :inline="true" :model="formData" label-width="70px">
d7fad0 5         <el-form-item label="开始时间">
J 6           <el-date-picker
f3edfb 7             v-model="formData.startTime"
8             type="datetime"
33a088 9             format="YYYY-MM-DD HH:mm:00"
10             value-format="YYYY-MM-DD HH:mm:00"
f3edfb 11             placeholder="选择日期时间"/>
d7fad0 12         </el-form-item>
J 13         <el-form-item label="结束时间">
14           <el-date-picker
f3edfb 15             v-model="formData.endTime"
16             type="datetime"
33a088 17             format="YYYY-MM-DD HH:mm:00"
18             value-format="YYYY-MM-DD HH:mm:00"
f3edfb 19             placeholder="选择日期时间"/>
d7fad0 20         </el-form-item>
J 21         <el-form-item label="预测时间">
22           <el-date-picker
f3edfb 23             v-model="formData.predictTime"
24             type="datetime"
33a088 25             format="YYYY-MM-DD HH:mm:00"
26             value-format="YYYY-MM-DD HH:mm:00"
f3edfb 27             placeholder="选择日期时间"/>
d7fad0 28         </el-form-item>
J 29         <el-form-item label="预测频率">
f3edfb 30           <el-input-number v-model="formData.predictFreq" controls-position="right"
31                            :min="1"
d7fad0 32                            :max="10"/>
J 33         </el-form-item>
34         <el-form-item>
35           <el-button-group>
1cdc15 36             <el-button type="primary" plain :icon="DArrowLeft"
33a088 37                        :loading="loading1" @click="leftSearchDataByRange()"/>
f3edfb 38             <el-button type="primary" plain :icon="Search"
33a088 39                        :loading="loading1" @click="getList()">查询
f3edfb 40             </el-button>
1cdc15 41             <el-button type="primary" plain :icon="DArrowRight"
33a088 42                        :loading="loading1" @click="rightSearchDataByRange()"/>
1cdc15 43           </el-button-group>
44         </el-form-item>
45         <el-form-item>
46           <el-button-group>
47             <el-button type="primary" plain :icon="CaretLeft"
48                        @click="playChart(true)"/>
49             <el-button type="primary" plain :icon="VideoPlay" v-if="!isPlay"
50                        @click="playHandle('play')"/>
51             <el-button type="primary" plain :icon="VideoPause" v-if="isPlay"
52                        @click="playHandle('pause')"/>
53             <el-button type="primary" plain :icon="CaretRight"
54                        @click="playChart(false)"/>
d7fad0 55           </el-button-group>
J 56         </el-form-item>
57
58         <div class="his-body">
59           <div class="his-body-left">
60             <div class="his-body-tree">
61               <el-tree
f3edfb 62                 :data="treeData"
63                 show-checkbox
64                 node-key="id"
65                 ref="tree"
66                 highlight-current
67                 :props="defaultProps"
68                 @check="onCheckTree"/>
d7fad0 69             </div>
J 70           </div>
71           <div class="his-body-right">
72             <div class="his-body-chart">
33a088 73               <el-form :inline="true" :model="calRateForm" :rules="formRules" ref="calRateFormRef"
f3edfb 74                        label-width="108px">
d7fad0 75                 <el-row>
f3edfb 76                   <el-col :span="6">
d7fad0 77                     <el-form-item label="预测项" prop="calItem" style="width: 90%">
33a088 78                       <el-select size="small" v-model="calRateForm.calItem"
79                                  @change="calItemBaseVale"
f3edfb 80                                  placeholder="请选择">
d7fad0 81                         <el-option
33a088 82                           v-for="itemOut in formData.checkedItemData"
83                           :key="itemOut.id"
84                           :label="itemOut.label"
85                           :value="itemOut.id"/>
d7fad0 86                       </el-select>
J 87                     </el-form-item>
88                   </el-col>
89                   <el-col :span="6">
90                     <el-form-item label="精准度偏差" prop="IN_DEVIATION">
f3edfb 91                       <el-input-number size="small" v-model="calRateForm.IN_DEVIATION"
92                                        controls-position="right" :min="1"
d7fad0 93                                        :max="10"/>
J 94                     </el-form-item>
95                   </el-col>
96                   <el-col :span="6">
97                     <el-form-item label="不可信率偏差" prop="OUT_DEVIATION">
f3edfb 98                       <el-input-number size="small" v-model="calRateForm.OUT_DEVIATION"
99                                        controls-position="right"
d7fad0 100                                        :min="1"
J 101                                        :max="20"/>
102                     </el-form-item>
103                   </el-col>
104                   <el-col :span="4">
105                     <el-form-item>
f3edfb 106                       <el-button size="small" type="primary" plain :loading="loading2"
107                                  @click="calAccuracyRate">计算精准度
d7fad0 108                       </el-button>
J 109                     </el-form-item>
110                   </el-col>
111                 </el-row>
112                 <el-row>
113                   <el-col :span="4">
114                     <el-form-item label="精准度:">
f3edfb 115                       {{ calRateForm.IN_ACCURACY_RATE }}%
d7fad0 116                     </el-form-item>
J 117                   </el-col>
118                   <el-col :span="4">
119                     <el-form-item label="预测平均值:">
f3edfb 120                       {{ calRateForm.itemPreAvg }}
d7fad0 121                     </el-form-item>
J 122                   </el-col>
123                   <el-col :span="4">
124                     <el-form-item label="预测最大值:">
f3edfb 125                       {{ calRateForm.itemPreMax }}
d7fad0 126                     </el-form-item>
J 127                   </el-col>
128                   <el-col :span="4">
129                     <el-form-item label="预测最小值:">
f3edfb 130                       {{ calRateForm.itemPreMin }}
d7fad0 131                     </el-form-item>
J 132                   </el-col>
133                   <el-col :span="4">
134                     <el-form-item label="预测累积量:">
f3edfb 135                       {{ calRateForm.preCumulant }}
d7fad0 136                     </el-form-item>
J 137                   </el-col>
138                 </el-row>
139                 <el-row>
140                   <el-col :span="4">
141                     <el-form-item label="不可信率:">
f3edfb 142                       {{ calRateForm.OUT_ACCURACY_RATE }}%
d7fad0 143                     </el-form-item>
J 144                   </el-col>
145                   <el-col :span="4">
146                     <el-form-item label="真实平均值:">
f3edfb 147                       {{ calRateForm.itemAvg }}
d7fad0 148                     </el-form-item>
J 149                   </el-col>
150                   <el-col :span="4">
151                     <el-form-item label="真实最大值:">
f3edfb 152                       {{ calRateForm.itemMax }}
d7fad0 153                     </el-form-item>
J 154                   </el-col>
155                   <el-col :span="4">
156                     <el-form-item label="真实最小值:">
f3edfb 157                       {{ calRateForm.itemMin }}
d7fad0 158                     </el-form-item>
J 159                   </el-col>
160                   <el-col :span="4">
161                     <el-form-item label="真实累积量:">
f3edfb 162                       {{ calRateForm.realCumulant }}
d7fad0 163                     </el-form-item>
J 164                   </el-col>
165                 </el-row>
166               </el-form>
167               <el-form :inline="true" :model="formData" label-width="100px">
168                 <el-row>
52bd8c 169                   <el-col :span="16">
d7fad0 170                     <el-form-item label="数据类型">
J 171                       <el-checkbox-group v-model="formData.chartCheck" @change="changeChartCheck">
f3edfb 172                         <el-checkbox v-for="item in formData.chartOptions" :label="item"
173                                      :key="item">{{ item }}
d7fad0 174                         </el-checkbox>
J 175                       </el-checkbox-group>
176                     </el-form-item>
177                   </el-col>
178                   <el-col :span="6">
179                     <el-form-item>
f3edfb 180                       <el-radio v-model="formData.isMultipleY" :label="false"
181                                 @input="onChangeMultipleY">单坐标轴
182                       </el-radio>
183                       <el-radio v-model="formData.isMultipleY" :label="true"
184                                 @input="onChangeMultipleY">多坐标轴
185                       </el-radio>
d7fad0 186                     </el-form-item>
J 187                   </el-col>
188                 </el-row>
189               </el-form>
f3edfb 190               <div ref="dataAnalysisChart" style="height: 500px;"></div>
d7fad0 191             </div>
J 192           </div>
193         </div>
194       </el-form>
195     </div>
196   </el-card>
197 </template>
198 <script lang="ts" setup>
f3edfb 199 import {getYMDHMS} from "@/utils/dateUtil"
200 import * as McsApi from '@/api/model/mcs'
201 import * as echarts from "echarts";
1cdc15 202 import {Search, DArrowLeft, DArrowRight, VideoPlay, VideoPause, CaretLeft, CaretRight} from '@element-plus/icons-vue'
d7fad0 203
f3edfb 204 defineOptions({name: 'AnalysisformData'})
d7fad0 205
f3edfb 206 const message = useMessage() // 消息弹窗
207 const {t} = useI18n() // 国际化
208 const dataAnalysisChart = ref(null);
209 const loading1 = ref(false) // 列表的加载中
210 const loading2 = ref(false) // 列表的加载中
211 const total = ref(0) // 列表的总页数
212 const list = ref([]) // 字典表格数据
213 let formData = ref({
214   rangeDate: '',
215   startTime: '',
216   endTime: '',
217   predictTime: '',
218   predictTimeStr: '',
219   startTimeStr: '',
220   endTimeStr: '',
221   predictTimeStamp: 0,
222   startTimeStamp: 0,
223   endTimeStamp: 0,
224   currentStamp: '',
225   currentStamp60: '',
226   predictStamp: '',
227   chartCheck: ['T+L', '真实值'],
52bd8c 228   chartOptions: ['T+N', 'T+L', '当时', '真实值', '调整值', '预测累计', '真实累计'],
f3edfb 229   checkedItemData: [],
230   backItem: '',
231   backValue: 0,
232   backCoe: 1,
233   preCumulant: 0,
234   realCumulant: 0,
235   queryStep: 2,
236   isMultipleYRadio: '单坐标轴',
237   isMultipleY: false,
adf924 238   predictFreq: 2,
f3edfb 239 })
33a088 240 const calRateFormRef = ref()
241 const calRateForm = ref({
242   calItem: undefined,
27a268 243   IN_DEVIATION: 10,
244   OUT_DEVIATION: 50,
f3edfb 245   IN_ACCURACY_RATE: 0,
246   OUT_ACCURACY_RATE: 0,
247   itemAvg: 0,
248   itemMax: 0,
249   itemMin: 0,
250   itemPreAvg: 0,
251   itemPreMax: 0,
252   itemPreMin: 0,
253   preCumulant: 0,
254   realCumulant: 0
255 })
256 let itemData = ref({
257   currentTreeList: [],
258   chart: {},
259   option: {}
260 })
261 const treeData = ref([])
262 const itemDataObject = ref()
263 const timer = ref()
264 let myChart = null;
1cdc15 265 const isPlay = ref(false)
f26b8f 266
f3edfb 267 const formRules = reactive({
268   calItem: [{required: true, message: '预测项不能为空', trigger: 'blur'}],
269   IN_DEVIATION: [{required: true, message: '精准度偏差不能为空', trigger: 'blur'}],
270   OUT_DEVIATION: [{required: true, message: '不可信率偏差不能为空', trigger: 'blur'}],
271 })
d7fad0 272
f3edfb 273 /** 查询列表 */
f9ae47 274 const getList = async (isClear = true) => {
f3edfb 275   loading1.value = true
276   try {
277     if (!formData.value.chartCheck) {
278       formData.value.chartCheck = ['真实值']
d7fad0 279     }
f3edfb 280     let chartCheckArray = formData.value.chartCheck;
281     if (!formData.value.checkedItemData || formData.value.checkedItemData.length == 0) {
282       itemData.value.option = {};
283       return;
d7fad0 284     }
f3edfb 285     let outIds = formData.value.checkedItemData.map(item => {
286       return item.id
d7fad0 287     })
f3edfb 288     const params = reactive({
289       outIds: outIds,
290       predictTime: formData.value.predictTime,
291       startTime: formData.value.startTime,
292       endTime: formData.value.endTime
293     })
294     const data = await McsApi.getPreDataCharts(params)
295     formData.value.predictTime = data.predictTime;
296     formData.value.startTime = data.startTime
297     formData.value.endTime = data.endTime
d7fad0 298
f3edfb 299     let xAxisData = data.categories;
52bd8c 300     let defaultYAxis = [
301       {
302         type: 'value',
303         name: "累计值",
304         splitLine: {show: false},
305         axisLine: {show: true},
306         position: 'right'
307       },
308       {
309         type: 'value',
310         name: "",
311         splitLine: {show: false},
312         axisLine: {show: true},
313         position: 'left'
314       }
315     ];
f3edfb 316     let yAxisData = [];
317     let offset = 0;
318     let yAxisIndex = 0;
319     let legendData = [];
320     let yMaxArr = [];
321     let seriesData = [];
322     seriesData.push({
323       name: '',
324       data: [null],
325       type: 'line',
326       smooth: true,
327       color: 'green',
328       markLine: {
329         silent: true,
330         lineStyle: {
331           color: '#32a487',
332           width: 2
333         },
334         data: [{
335           xAxis: formData.value.predictTime
336         }],
337         label: {
338           normal: {
339             formatter: formData.value.predictTime
340           }
341         },
342         symbol: ['circle', 'none'],
343       },
344     });
345     itemDataObject.value = {}
52bd8c 346     yAxisData.push({
347       type: 'value',
348       name: "累计值",
349       position: 'right',
350       splitLine: {
351         show: false
352       },
353       axisLine: {
354         show: true,
355         lineStyle: {}
356       },
357       axisLabel: {
358         formatter: '{value}'
359       }
360     })
f3edfb 361     for (let i = 0; i < data.dataViewList.length; i++) {
362       let dataView = data.dataViewList[i]
363       itemDataObject.value[dataView.outId] = dataView;
364       let maxValue = dataView.maxValue;
365       let minValue = dataView.minValue;
52bd8c 366       yAxisIndex = (formData.value.isMultipleY ? i : 0) + 1;
f3edfb 367       let yMax = maxValue;
368       if (maxValue < 0) {
369         maxValue = 1;
370       } else if (maxValue < 10) {
371         yMax = (Math.ceil(maxValue * 11) / 10).toFixed(1);
372       } else if (maxValue < 100) {
373         yMax = (Math.ceil(maxValue * 1.1 / 5) * 5);
374       } else {
375         yMax = (Math.ceil(maxValue * 1.1 / 10) * 10);
376       }
377       yMaxArr.push(yMax);
378       let yMin = minValue;
379       if (minValue >= 0) {
380         yMin = 0;
381       } else if (minValue > -10) {
382         yMin = (Math.floor(minValue * 11) / 10).toFixed(1);
383       } else if (minValue > -100) {
384         yMin = (Math.floor(minValue * 1.1 / 5) * 5);
385       } else {
386         yMin = (Math.floor(minValue * 1.1 / 10) * 10);
387       }
388       yAxisData.push({
389         type: 'value',
390         name: "",
391         min: yMin,
392         max: yMax,
393         position: 'left',
394         offset: offset,
395         splitLine: {
396           show: false
397         },
398         axisLine: {
399           show: true,
400           lineStyle: {}
401         },
402         axisLabel: {
403           formatter: '{value}'
404         }
405       })
406       offset = offset + 40
407       if (chartCheckArray.indexOf('真实值') !== -1) {
32396c 408         let legendName = dataView.resultName + '(真实)';
f3edfb 409         legendData.push(legendName);
410         seriesData.push({
411           name: legendName,
412           data: dataView.realData || [],
413           type: 'line',
414           yAxisIndex: yAxisIndex,
415           showSymbol: false,
f9ae47 416           smooth: false,
f3edfb 417           lineStyle: {
418             width: 2
419           }
420         });
421       }
422       if (chartCheckArray.indexOf('T+N') !== -1) {
32396c 423         let legendName = dataView.resultName + '(T+N)';
f9ae47 424         legendData.push(legendName);
f3edfb 425         seriesData.push({
426           name: legendName,
427           data: dataView.preDataN || [],
428           type: 'line',
429           yAxisIndex: yAxisIndex,
430           showSymbol: false,
f9ae47 431           smooth: false,
f3edfb 432           lineStyle: {
433             width: 2
434           }
435         });
436       }
437       if (chartCheckArray.indexOf('T+L') !== -1) {
32396c 438         let legendName = dataView.resultName + '(T+L)';
f3edfb 439         legendData.push(legendName);
440         seriesData.push({
441           name: legendName,
442           data: dataView.preDataL || [],
443           type: 'line',
444           showSymbol: false,
445           connectNulls: true,
446           yAxisIndex: yAxisIndex,
f9ae47 447           smooth: false,
f3edfb 448           lineStyle: {
449             width: 2
450           }
451         });
452       }
453       if (chartCheckArray.indexOf('当时') !== -1) {
32396c 454         let legendName = dataView.resultName + '(当时)';
f3edfb 455         legendData.push(legendName);
456         seriesData.push({
457           name: legendName,
458           data: dataView.curData || [],
459           type: 'line',
460           yAxisIndex: yAxisIndex,
f9ae47 461           showSymbol: true,
462           smooth: false,
f3edfb 463           lineStyle: {
f9ae47 464             width: 3
f3edfb 465           }
466         });
467       }
468       if (chartCheckArray.indexOf('调整值') !== -1) {
32396c 469         let legendName = dataView.resultName + '(调整值)';
f3edfb 470         legendData.push(legendName);
471         seriesData.push({
472           name: legendName,
473           data: dataView.adjData || [],
474           type: 'line',
475           yAxisIndex: yAxisIndex,
476           showSymbol: false,
477           connectNulls: true,
f9ae47 478           smooth: false,
f3edfb 479           lineStyle: {
480             width: 2,
481             type: 'dashed'
482           }
483         });
484       }
52bd8c 485
486       if (chartCheckArray.indexOf('预测累计') !== -1) {
487         let legendName = dataView.resultName + '(预测累计)';
488         legendData.push(legendName);
489         let seriesLeiJiData = []
490         if (dataView.curData) {
491           let leiJi = 0;
492           for (let i = 0; i < dataView.curData.length; i++) {
493             let item = dataView.curData[i];
494             leiJi = leiJi + Number(item[1])
495             seriesLeiJiData.push([item[0], (leiJi / 60).toFixed(2)]);
496           }
497         }
498         seriesData.push({
499           name: legendName,
500           data: seriesLeiJiData,
501           type: 'line',
502           yAxisIndex: 0,
503           showSymbol: false,
504           connectNulls: true,
505           smooth: false,
506           lineStyle: {
507             width: 2,
508             type: 'dashed'
509           }
510         });
511       }
512
513       if (chartCheckArray.indexOf('真实累计') !== -1) {
514         let legendName = dataView.resultName + '(真实累计)';
515         legendData.push(legendName);
516         let seriesLeiJiData = []
517         if (dataView.realData) {
518           let leiJi = 0;
519           let lCount = 0
520           for (let i = 0; i < dataView.realData.length; i++) {
521             let item = dataView.realData[i];
522             if(new Date(item[0]).getTime() < new Date(formData.value.predictTime).getTime()) {
523               continue
524             }
525             if (lCount > dataView.curData.length) {
526               continue
527             }
528             lCount = lCount + 1
529             leiJi = leiJi + Number(item[1])
530             seriesLeiJiData.push([item[0], (leiJi / 60).toFixed(2)]);
531           }
532         }
533         seriesData.push({
534           name: legendName,
535           data: seriesLeiJiData,
536           type: 'line',
537           yAxisIndex: 0,
538           showSymbol: false,
539           connectNulls: true,
540           smooth: false,
541           lineStyle: {
542             width: 2,
543             type: 'dashed'
544           }
545         });
546       }
d7fad0 547     }
f3edfb 548     //如果最大值相差不大,改成一致大小
549     if (yMaxArr.length > 1) {
550       let max = Math.max.apply(null, yMaxArr);
551       let min = Math.min.apply(null, yMaxArr);
552       if (Math.abs((max - min) / max) <= 0.2) {
553         for (let i = 0; i < yAxisData.length; i++) {
554           yAxisData[i].max = max;
555         }
556       }
d7fad0 557     }
52bd8c 558
f3edfb 559     myChart = echarts.init(dataAnalysisChart.value);
560     let option = {
561       title: {
562         text: ''
563       },
564       tooltip: {
565         trigger: 'axis'
566       },
567       legend: {
568         show: true,
569         data: legendData,
570         top: 10
571       },
572       grid: {
573         top: '20%',
574         left: '3%',
575         right: '6%',
576         bottom: '3%',
577         containLabel: true
578       },
579       xAxis: {
580         type: 'category',
581         boundaryGap: false,
582         data: xAxisData
583       },
52bd8c 584       yAxis: formData.value.isMultipleY ? yAxisData : defaultYAxis,
f3edfb 585       dataZoom: [
586         {
587           type: 'inside',
588           start: 0,
589           end: 100
590         },
591         {
592           start: 0,
593           end: 10
594         }
595       ],
596       series: seriesData
d7fad0 597     }
f9ae47 598     if (isClear) {
599       myChart.clear()
600     }
f3edfb 601     myChart.setOption(option)
602   } finally {
603     loading1.value = false
d7fad0 604   }
d4baad 605
606   calItemBaseVale()
f3edfb 607 }
608
609 onMounted(() => {
33a088 610   resetForm()
f3edfb 611   getPreItemTree()
612 })
613
614 async function getPreItemTree() {
615   treeData.value = await McsApi.getPredictItemTree()
f9ae47 616 }
617
618 function changeChartCheck(value) {
619   getList(true)
f3edfb 620 }
621
1cdc15 622 function onChangeMultipleY() {
623   getList(true)
624 }
625
626 function playChart(isBack = false) {
627   let mins = isBack ? formData.value.predictFreq * -1 : formData.value.predictFreq
628   let startTime = formData.value.startTime;
629   let endTime = formData.value.endTime;
630   let predictTime = formData.value.predictTime;
631   if (predictTime) {
632     predictTime = getYMDHMS(new Date(predictTime).getTime() + 1000 * 60 * mins);
633     formData.value.predictTime = predictTime;
634   }
635   if (startTime) {
636     startTime = getYMDHMS(new Date(startTime).getTime() + 1000 * 60 * mins);
637     formData.value.startTime = startTime;
638   }
639   if (endTime) {
640     endTime = getYMDHMS(new Date(endTime).getTime() + 1000 * 60 * mins);
641     formData.value.endTime = endTime;
642   }
643   getList(false);
644 }
645
646 function playHandle(type) {
647   isPlay.value = 'play' === type
648   let doPlay = setInterval(function () {
649     if (isPlay.value) {
650       playChart()
651     } else {
652       clearInterval(doPlay);
653     }
654     if (new Date().getTime() - new Date(formData.value.predictTime).getTime() < 1000 * 60 ) {
655       isPlay.value = false
656       clearInterval(doPlay);
657     }
658   }, 1000)
659 }
660
f3edfb 661 function leftSearchDataByRange() {
662   let mins = getRangeMins();
663   let startTime = formData.value.startTime;
664   let endTime = formData.value.endTime;
665   let predictTime = formData.value.predictTime;
666   if (predictTime) {
1cdc15 667     predictTime = getYMDHMS(new Date(predictTime).getTime() - 1000 * 60 * mins);
f3edfb 668     formData.value.predictTime = predictTime;
669   }
670   if (startTime) {
1cdc15 671     startTime = getYMDHMS(new Date(startTime).getTime() - 1000 * 60 * mins);
f3edfb 672     formData.value.startTime = startTime;
673   }
674   if (endTime) {
1cdc15 675     endTime = getYMDHMS(new Date(endTime).getTime() - 1000 * 60 * mins);
f3edfb 676     formData.value.endTime = endTime;
677   }
f9ae47 678   getList(false);
f3edfb 679 }
680
681 function getRangeMins() {
682   let result: string | number = 0;
683   if (formData.value.startTime && formData.value.endTime) {
684     let startStamp = new Date(formData.value.startTime).getTime();
685     let endStamp = new Date(formData.value.endTime).getTime();
686     let queryStep = ((endStamp - startStamp) / (1000 * 60)).toFixed(0);
687     result = queryStep >= 0 ? queryStep : 0;
688   }
689   return result;
690 }
691
692 function onCheckTree(data, checked, indeterminate) {
693   formData.value.checkedItemData = [];
694   if (checked.checkedNodes) {
27a268 695     let cns = [...checked.checkedNodes]
696     for (let i = 0; i < cns.length; i++) {
697       if (cns[i].id.indexOf('-') !== -1) {
698         continue
699       }
700       formData.value.checkedItemData.push(cns[i])
701     }
f3edfb 702   }
703   debounce(getList, 1000);
704 }
705
706 function debounce(func, wait) {
707   let args = [];
708   if (timer.value) {
709     clearTimeout(timer.value);
710   }
711   timer.value = setTimeout(() => {
712     func.apply(this, args);
713     timer.value = null;
714   }, wait)
715 }
716
717 function calItemBaseVale() {
718   if (!calRateForm.value.calItem) {
719     calRateForm.value.itemPreMax = 0;
720     calRateForm.value.itemPreMin = 0;
721     calRateForm.value.itemPreAvg = 0;
722     calRateForm.value.preCumulant = 0;
723     calRateForm.value.itemMax = 0;
724     calRateForm.value.itemMin = 0;
725     calRateForm.value.itemAvg = 0;
726     calRateForm.value.realCumulant = 0;
727   } else {
33a088 728     let dataView = itemDataObject.value[calRateForm.value.calItem]
f3edfb 729     calRateForm.value.itemPreMax = dataView.preMax;
730     calRateForm.value.itemPreMin = dataView.preMin;
731     calRateForm.value.itemPreAvg = dataView.preAvg;
732     calRateForm.value.preCumulant = dataView.preCumulant;
733     calRateForm.value.itemMax = dataView.hisMax;
734     calRateForm.value.itemMin = dataView.hisMin;
735     calRateForm.value.itemAvg = dataView.hisAvg;
736     calRateForm.value.realCumulant = dataView.hisCumulant;
737   }
27a268 738   calAccuracyRate()
f3edfb 739 }
740
741 function calAccuracyRate() {
27a268 742   const valid = calRateFormRef.value.validate()
743   if (!valid) return
f3edfb 744
27a268 745   let dataView = itemDataObject.value[calRateForm.value.calItem]
746   let seriesReaData = dataView.realData;
747   let seriesPreData = dataView.preDataL;
748   if (seriesReaData == null || seriesPreData == null ||
749     seriesReaData.length === 0 || seriesPreData.length === 0) {
f3edfb 750     loading2.value = false;
27a268 751     return;
752   }
753   let predictValueMap = {};
754   seriesPreData.forEach(function (item) {
755     predictValueMap[item[0]] = item[1];
f3edfb 756   })
27a268 757   let pointValueMap = {};
758   seriesReaData.forEach(function (item) {
759     pointValueMap[item[0]] = item[1];
760   })
761   let inDeviation = Number(calRateForm.value.IN_DEVIATION);
762   let outDeviation = Number(calRateForm.value.OUT_DEVIATION);
763   if (inDeviation === 0 && outDeviation === 0) {
764     loading2.value = false;
765     return;
766   }
767   let inDeviationCount = 0;
768   let outDeviationCount = 0;
769   let totalCount = 0;
770   for (let key in predictValueMap) {
771     let predictValue = predictValueMap[key];
772     let pointValue = pointValueMap[key];
773     if (pointValue == null || "" === pointValue || predictValue == null || "" === predictValue) {
774       continue;
775     }
776     let deviationAbs = (predictValue - pointValue) >= 0 ? (predictValue - pointValue) : (predictValue - pointValue) * -1;
777     if (deviationAbs < inDeviation) {
778       inDeviationCount = inDeviationCount + 1;
779     }
780     if (deviationAbs > outDeviation) {
781       outDeviationCount = outDeviationCount + 1;
782     }
783     totalCount = totalCount + 1;
784   }
785
786   let rateIn = (inDeviationCount / totalCount * 100).toFixed(2);
787   let rateOut = (outDeviationCount / totalCount * 100).toFixed(2);
788   calRateForm.value.IN_ACCURACY_RATE = Number(rateIn);
789   calRateForm.value.OUT_ACCURACY_RATE = Number(rateOut);
790   loading2.value = false;
f3edfb 791 }
792
793 function rightSearchDataByRange() {
794   let mins = getRangeMins();
795   let startTime = formData.value.startTime;
796   let endTime = formData.value.endTime;
797   let predictTime = formData.value.predictTime;
798   if (predictTime) {
1cdc15 799     predictTime = getYMDHMS(new Date(predictTime).getTime() + 1000 * 60 * mins);
f3edfb 800     formData.value.predictTime = predictTime;
801   }
802   if (startTime) {
1cdc15 803     startTime = getYMDHMS(new Date(startTime).getTime() + 1000 * 60 * mins);
f3edfb 804     formData.value.startTime = startTime;
805   }
806   if (endTime) {
1cdc15 807     endTime = getYMDHMS(new Date(endTime).getTime() + 1000 * 60 * mins);
f3edfb 808     formData.value.endTime = endTime;
809   }
f9ae47 810   getList(false);
f3edfb 811 }
d7fad0 812
33a088 813 /** 重置表单 */
814 const resetForm = () => {
815   formData.value = {
816     rangeDate: '',
817     startTime: '',
818     endTime: '',
819     predictTime: '',
820     predictTimeStr: '',
821     startTimeStr: '',
822     endTimeStr: '',
823     predictTimeStamp: 0,
824     startTimeStamp: 0,
825     endTimeStamp: 0,
826     currentStamp: '',
827     currentStamp60: '',
828     predictStamp: '',
829     chartCheck: ['T+L', '真实值'],
52bd8c 830     chartOptions: ['T+N', 'T+L', '当时', '真实值', '调整值', '预测累计', '真实累计'],
33a088 831     checkedItemData: [],
832     backItem: '',
833     backValue: 0,
834     backCoe: 1,
835     preCumulant: 0,
836     realCumulant: 0,
837     queryStep: 2,
838     isMultipleYRadio: '单坐标轴',
839     isMultipleY: false,
f9ae47 840     predictFreq: 2,
33a088 841   }
842   calRateForm.value = {
843     calItem: undefined,
27a268 844     IN_DEVIATION: 10,
845     OUT_DEVIATION: 50,
33a088 846     IN_ACCURACY_RATE: 0,
847     OUT_ACCURACY_RATE: 0,
848     itemAvg: 0,
849     itemMax: 0,
850     itemMin: 0,
851     itemPreAvg: 0,
852     itemPreMax: 0,
853     itemPreMin: 0,
854     preCumulant: 0,
855     realCumulant: 0
856   }
857   calRateFormRef.value?.resetFields()
858 }
d7fad0 859 </script>
J 860 <style scoped>
f3edfb 861 .el-form-item {
862   margin-bottom: 0 !important;
863 }
d7fad0 864
f3edfb 865 .his-body-chart {
866   height: 100%;
867   border: 1px solid lightgray;
868   padding: 10px;
869 }
d7fad0 870
f3edfb 871 .his-body-tree {
872   height: 100%;
873   border: 1px solid lightgray;
874   padding: 10px;
875 }
d7fad0 876
f3edfb 877 .his-body-right {
878   width: 80%;
879   height: 100%;
880   padding-top: 10px;
881 }
d7fad0 882
f3edfb 883 .his-body-left {
884   width: 20%;
885   height: 100%;
886   padding: 10px 10px 0 0;
887 }
d7fad0 888
f3edfb 889 .his-body {
890   width: 100%;
891   height: calc(calc(100vh - 68px - 38px - 160px));
892   display: flex;
893   flex-direction: row;
894   justify-content: flex-start;
895   align-content: flex-start;
896 }
d7fad0 897 </style>