| | |
| | | <el-col :span="6"> |
| | | <el-form-item label="精准度偏差" prop="IN_DEVIATION"> |
| | | <el-input-number size="small" v-model="calRateForm.IN_DEVIATION" |
| | | controls-position="right" :min="1" |
| | | :max="10"/> |
| | | controls-position="right" :min="0"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="6"> |
| | | <el-form-item label="不可信率偏差" prop="OUT_DEVIATION"> |
| | | <el-input-number size="small" v-model="calRateForm.OUT_DEVIATION" |
| | | controls-position="right" |
| | | :min="1" |
| | | :max="20"/> |
| | | :min="1"/> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | |
| | | </el-form> |
| | | <el-form :inline="true" :model="formData" label-width="100px"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-col :span="16"> |
| | | <el-form-item label="数据类型"> |
| | | <el-checkbox-group v-model="formData.chartCheck" @change="changeChartCheck"> |
| | | <el-checkbox v-for="item in formData.chartOptions" :label="item" |
| | |
| | | </el-row> |
| | | </el-form> |
| | | <div ref="dataAnalysisChart" style="height: 500px;"></div> |
| | | <div class="chart-foot"> |
| | | <div class="chart-foot-content"> |
| | | <h3 class="chart-foot-title">预警信息</h3> |
| | | <div class="chart-foot-table"> |
| | | <el-table :data="alarmList" style="width: 100%" v-loading="loadingAlarm" height="100px"> |
| | | <el-table-column prop="content" header-align="center" align="left" label="消息内容" min-width="200" /> |
| | | <el-table-column prop="alarmType" label="预警类型" header-align="center" align="left" min-width="150"/> |
| | | <el-table-column prop="alarmTime" label="预警时间" header-align="center" align="left" min-width="150"/> |
| | | </el-table> |
| | | </div> |
| | | </div> |
| | | <div class="chart-foot-content"> |
| | | <h3 class="chart-foot-title">调度建议</h3> |
| | | <div class="chart-foot-table"> |
| | | <el-table :data="suggestList" style="width: 100%" v-loading="loadingAdjust" height="100px"> |
| | | <el-table-column |
| | | prop="scheduleTime" |
| | | label="调度时间" |
| | | header-align="center" |
| | | align="left" |
| | | min-width="160" |
| | | /> |
| | | <el-table-column |
| | | prop="content" |
| | | label="内容" |
| | | min-width="300" |
| | | header-align="center" align="left" |
| | | /> |
| | | <el-table-column |
| | | prop="adjustValue" |
| | | label="调整值" |
| | | header-align="center" |
| | | align="center" |
| | | min-width="100" |
| | | /> |
| | | </el-table> |
| | | </div> |
| | | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | <script lang="ts" setup> |
| | | import {getYMDHMS} from "@/utils/dateUtil" |
| | | import * as McsApi from '@/api/model/mcs' |
| | | import * as AlarmMessageApi from '@/api/model/pre/alarm/message' |
| | | import * as ScheSuggestApi from '@/api/model/sche/suggest' |
| | | import * as echarts from "echarts"; |
| | | import {Search, DArrowLeft, DArrowRight, VideoPlay, VideoPause, CaretLeft, CaretRight} from '@element-plus/icons-vue' |
| | | |
| | |
| | | currentStamp60: '', |
| | | predictStamp: '', |
| | | chartCheck: ['T+L', '真实值'], |
| | | chartOptions: ['T+N', 'T+L', '当时', '真实值', '调整值'], |
| | | chartOptions: ['T+N', 'T+L', '当时', '真实值', '调整值', '预测累计', '真实累计'], |
| | | checkedItemData: [], |
| | | backItem: '', |
| | | backValue: 0, |
| | |
| | | const calRateFormRef = ref() |
| | | const calRateForm = ref({ |
| | | calItem: undefined, |
| | | IN_DEVIATION: 0, |
| | | OUT_DEVIATION: 0, |
| | | IN_DEVIATION: 10, |
| | | OUT_DEVIATION: 50, |
| | | IN_ACCURACY_RATE: 0, |
| | | OUT_ACCURACY_RATE: 0, |
| | | itemAvg: 0, |
| | |
| | | const timer = ref() |
| | | let myChart = null; |
| | | const isPlay = ref(false) |
| | | const alarmList = ref([]) |
| | | const suggestList = ref([]) |
| | | const loadingAlarm = ref(false) |
| | | const loadingAdjust = ref(false) |
| | | |
| | | const formRules = reactive({ |
| | | calItem: [{required: true, message: '预测项不能为空', trigger: 'blur'}], |
| | |
| | | startTime: formData.value.startTime, |
| | | endTime: formData.value.endTime |
| | | }) |
| | | |
| | | const data = await McsApi.getPreDataCharts(params) |
| | | formData.value.predictTime = data.predictTime; |
| | | formData.value.startTime = data.startTime |
| | | formData.value.endTime = data.endTime |
| | | |
| | | const paramsAlarm = reactive({ |
| | | outIds: outIds, |
| | | predictTime: formData.value.predictTime |
| | | }) |
| | | |
| | | loadingAlarm.value = true |
| | | alarmList.value = await AlarmMessageApi.getListByOut(paramsAlarm) |
| | | loadingAlarm.value = false |
| | | |
| | | loadingAdjust.value = true |
| | | suggestList.value = await ScheSuggestApi.getListByOut(paramsAlarm) |
| | | loadingAdjust.value = false |
| | | |
| | | let xAxisData = data.categories; |
| | | let defaultYAxis = [ |
| | | { |
| | | type: 'value', |
| | | name: "累计值", |
| | | splitLine: {show: false}, |
| | | axisLine: {show: true}, |
| | | position: 'right' |
| | | }, |
| | | { |
| | | type: 'value', |
| | | name: "", |
| | | splitLine: {show: false}, |
| | | axisLine: {show: true}, |
| | | position: 'left' |
| | | } |
| | | ]; |
| | | let yAxisData = []; |
| | | let offset = 0; |
| | | let yAxisIndex = 0; |
| | |
| | | }, |
| | | }); |
| | | itemDataObject.value = {} |
| | | yAxisData.push({ |
| | | type: 'value', |
| | | name: "累计值", |
| | | position: 'right', |
| | | splitLine: { |
| | | show: false |
| | | }, |
| | | axisLine: { |
| | | show: true, |
| | | lineStyle: {} |
| | | }, |
| | | axisLabel: { |
| | | formatter: '{value}' |
| | | } |
| | | }) |
| | | for (let i = 0; i < data.dataViewList.length; i++) { |
| | | let dataView = data.dataViewList[i] |
| | | itemDataObject.value[dataView.outId] = dataView; |
| | | let maxValue = dataView.maxValue; |
| | | let minValue = dataView.minValue; |
| | | yAxisIndex = formData.value.isMultipleY ? i : 0; |
| | | yAxisIndex = (formData.value.isMultipleY ? i : 0) + 1; |
| | | let yMax = maxValue; |
| | | if (maxValue < 0) { |
| | | maxValue = 1; |
| | |
| | | } |
| | | }); |
| | | } |
| | | |
| | | if (chartCheckArray.indexOf('预测累计') !== -1) { |
| | | let legendName = dataView.resultName + '(预测累计)'; |
| | | legendData.push(legendName); |
| | | let seriesLeiJiData = [] |
| | | if (dataView.cumulantPreData) { |
| | | seriesLeiJiData = dataView.cumulantPreData |
| | | } |
| | | seriesData.push({ |
| | | name: legendName, |
| | | data: seriesLeiJiData, |
| | | type: 'line', |
| | | yAxisIndex: 0, |
| | | showSymbol: false, |
| | | connectNulls: true, |
| | | smooth: false, |
| | | lineStyle: { |
| | | width: 2, |
| | | type: 'dashed' |
| | | } |
| | | }); |
| | | } |
| | | |
| | | if (chartCheckArray.indexOf('真实累计') !== -1) { |
| | | let legendName = dataView.resultName + '(真实累计)'; |
| | | legendData.push(legendName); |
| | | let seriesLeiJiData = [] |
| | | if (dataView.cumulantRealData) { |
| | | seriesLeiJiData = dataView.cumulantRealData |
| | | } |
| | | seriesData.push({ |
| | | name: legendName, |
| | | data: seriesLeiJiData, |
| | | type: 'line', |
| | | yAxisIndex: 0, |
| | | showSymbol: false, |
| | | connectNulls: true, |
| | | smooth: false, |
| | | lineStyle: { |
| | | width: 2, |
| | | type: 'dashed' |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | //如果最大值相差不大,改成一致大小 |
| | | if (yMaxArr.length > 1) { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | myChart = echarts.init(dataAnalysisChart.value); |
| | | let option = { |
| | | title: { |
| | |
| | | }, |
| | | tooltip: { |
| | | trigger: 'axis' |
| | | }, |
| | | toolbox: { |
| | | show: true, |
| | | feature: { |
| | | saveAsImage: {} |
| | | } |
| | | }, |
| | | legend: { |
| | | show: true, |
| | |
| | | boundaryGap: false, |
| | | data: xAxisData |
| | | }, |
| | | yAxis: formData.value.isMultipleY ? yAxisData : { |
| | | type: 'value', |
| | | splitLine: {show: false}, |
| | | axisLine: {show: true} |
| | | }, |
| | | yAxis: formData.value.isMultipleY ? yAxisData : defaultYAxis, |
| | | dataZoom: [ |
| | | { |
| | | type: 'inside', |
| | |
| | | } finally { |
| | | loading1.value = false |
| | | } |
| | | |
| | | calItemBaseVale() |
| | | } |
| | | |
| | | onMounted(() => { |
| | |
| | | function onCheckTree(data, checked, indeterminate) { |
| | | formData.value.checkedItemData = []; |
| | | if (checked.checkedNodes) { |
| | | formData.value.checkedItemData = [...checked.checkedNodes] |
| | | let cns = [...checked.checkedNodes] |
| | | for (let i = 0; i < cns.length; i++) { |
| | | if (cns[i].id.indexOf('-') !== -1) { |
| | | continue |
| | | } |
| | | formData.value.checkedItemData.push(cns[i]) |
| | | } |
| | | } |
| | | debounce(getList, 1000); |
| | | } |
| | |
| | | calRateForm.value.itemAvg = dataView.hisAvg; |
| | | calRateForm.value.realCumulant = dataView.hisCumulant; |
| | | } |
| | | calAccuracyRate() |
| | | } |
| | | |
| | | function calAccuracyRate() { |
| | | this.$refs['calRateForm'].validate((valid) => { |
| | | if (!valid) { |
| | | return false |
| | | } |
| | | let dataView = itemDataObject[calRateForm.value.calItem] |
| | | let seriesReaData = dataView.realData; |
| | | let seriesPreData = dataView.preDataL; |
| | | if (seriesReaData == null || seriesPreData == null || |
| | | seriesReaData.length === 0 || seriesPreData.length === 0) { |
| | | loading2.value = false; |
| | | return; |
| | | } |
| | | let predictValueMap = {}; |
| | | seriesPreData.forEach(function (item) { |
| | | predictValueMap[item[0]] = item[1]; |
| | | }) |
| | | let pointValueMap = {}; |
| | | seriesReaData.forEach(function (item) { |
| | | pointValueMap[item[0]] = item[1]; |
| | | }) |
| | | let inDeviation = Number(calRateForm.value.IN_DEVIATION); |
| | | let outDeviation = Number(calRateForm.value.OUT_DEVIATION); |
| | | if (inDeviation === 0 && outDeviation === 0) { |
| | | loading2.value = false; |
| | | return; |
| | | } |
| | | let inDeviationCount = 0; |
| | | let outDeviationCount = 0; |
| | | let totalCount = 0; |
| | | for (let key in predictValueMap) { |
| | | let predictValue = predictValueMap[key]; |
| | | let pointValue = pointValueMap[key]; |
| | | if (pointValue == null || "" === pointValue || predictValue == null || "" === predictValue) { |
| | | continue; |
| | | } |
| | | let deviationAbs = (predictValue - pointValue) >= 0 ? (predictValue - pointValue) : (predictValue - pointValue) * -1; |
| | | if (deviationAbs < inDeviation) { |
| | | inDeviationCount = inDeviationCount + 1; |
| | | } |
| | | if (deviationAbs > outDeviation) { |
| | | outDeviationCount = outDeviationCount + 1; |
| | | } |
| | | totalCount = totalCount + 1; |
| | | } |
| | | const valid = calRateFormRef.value.validate() |
| | | if (!valid) return |
| | | |
| | | let rateIn = (inDeviationCount / totalCount * 100).toFixed(2); |
| | | let rateOut = (outDeviationCount / totalCount * 100).toFixed(2); |
| | | calRateForm.value.IN_ACCURACY_RATE = Number(rateIn); |
| | | calRateForm.value.OUT_ACCURACY_RATE = Number(rateOut); |
| | | let dataView = itemDataObject.value[calRateForm.value.calItem] |
| | | let seriesReaData = dataView.realData; |
| | | let seriesPreData = dataView.preDataL; |
| | | if (seriesReaData == null || seriesPreData == null || |
| | | seriesReaData.length === 0 || seriesPreData.length === 0) { |
| | | loading2.value = false; |
| | | return; |
| | | } |
| | | let predictValueMap = {}; |
| | | seriesPreData.forEach(function (item) { |
| | | predictValueMap[item[0]] = item[1]; |
| | | }) |
| | | let pointValueMap = {}; |
| | | seriesReaData.forEach(function (item) { |
| | | pointValueMap[item[0]] = item[1]; |
| | | }) |
| | | let inDeviation = Number(calRateForm.value.IN_DEVIATION); |
| | | let outDeviation = Number(calRateForm.value.OUT_DEVIATION); |
| | | if (inDeviation === 0 && outDeviation === 0) { |
| | | loading2.value = false; |
| | | return; |
| | | } |
| | | let inDeviationCount = 0; |
| | | let outDeviationCount = 0; |
| | | let totalCount = 0; |
| | | for (let key in predictValueMap) { |
| | | let predictValue = predictValueMap[key]; |
| | | let pointValue = pointValueMap[key]; |
| | | if (pointValue == null || "" === pointValue || predictValue == null || "" === predictValue) { |
| | | continue; |
| | | } |
| | | let deviationAbs = (predictValue - pointValue) >= 0 ? (predictValue - pointValue) : (predictValue - pointValue) * -1; |
| | | if (deviationAbs < inDeviation) { |
| | | inDeviationCount = inDeviationCount + 1; |
| | | } |
| | | if (deviationAbs > outDeviation) { |
| | | outDeviationCount = outDeviationCount + 1; |
| | | } |
| | | totalCount = totalCount + 1; |
| | | } |
| | | |
| | | let rateIn = (inDeviationCount / totalCount * 100).toFixed(2); |
| | | let rateOut = (outDeviationCount / totalCount * 100).toFixed(2); |
| | | calRateForm.value.IN_ACCURACY_RATE = Number(rateIn); |
| | | calRateForm.value.OUT_ACCURACY_RATE = Number(rateOut); |
| | | loading2.value = false; |
| | | } |
| | | |
| | | function rightSearchDataByRange() { |
| | |
| | | currentStamp60: '', |
| | | predictStamp: '', |
| | | chartCheck: ['T+L', '真实值'], |
| | | chartOptions: ['T+N', 'T+L', '当时', '真实值', '调整值'], |
| | | chartOptions: ['T+N', 'T+L', '当时', '真实值', '调整值', '预测累计', '真实累计'], |
| | | checkedItemData: [], |
| | | backItem: '', |
| | | backValue: 0, |
| | |
| | | } |
| | | calRateForm.value = { |
| | | calItem: undefined, |
| | | IN_DEVIATION: 0, |
| | | OUT_DEVIATION: 0, |
| | | IN_DEVIATION: 10, |
| | | OUT_DEVIATION: 50, |
| | | IN_ACCURACY_RATE: 0, |
| | | OUT_ACCURACY_RATE: 0, |
| | | itemAvg: 0, |
| | |
| | | } |
| | | </script> |
| | | <style scoped> |
| | | .chart-foot-table { |
| | | border: 1px solid #bababa; |
| | | } |
| | | .chart-foot-title { |
| | | font-size: 14px; |
| | | } |
| | | .chart-foot-content { |
| | | height: 100%; |
| | | width: 50%; |
| | | padding: 5px; |
| | | } |
| | | .chart-foot { |
| | | height: 120px; |
| | | width: 100%; |
| | | display: flex; |
| | | flex-direction: row; |
| | | } |
| | | .el-form-item { |
| | | margin-bottom: 0 !important; |
| | | } |
| | |
| | | .his-body-tree { |
| | | height: 100%; |
| | | border: 1px solid lightgray; |
| | | padding: 10px; |
| | | padding: 10px 10px 20px 10px; |
| | | overflow-y: auto; |
| | | } |
| | | |
| | | .his-body-right { |
| | |
| | | |
| | | .his-body { |
| | | width: 100%; |
| | | height: calc(calc(100vh - 68px - 38px - 160px)); |
| | | height: calc(calc(100vh - 68px - 38px - 60px)); |
| | | display: flex; |
| | | flex-direction: row; |
| | | justify-content: flex-start; |