潘志宝
2024-12-30 9e2e0baeff46fb6ecfe21145f7250d67b13ca79e
src/views/model/pre/analysis/index.vue
@@ -4,37 +4,42 @@
      <el-form :inline="true" :model="formData" label-width="80px">
        <el-form-item label="开始时间">
          <el-date-picker
              size="mini"
              v-model="formData.startTime"
              type="datetime"
              placeholder="选择日期时间"/>
            v-model="formData.startTime"
            type="datetime"
            format="YYYY-MM-DD HH:mm:00"
            value-format="YYYY-MM-DD HH:mm:00"
            placeholder="选择日期时间"/>
        </el-form-item>
        <el-form-item label="结束时间">
          <el-date-picker
              size="mini"
              v-model="formData.endTime"
              type="datetime"
              placeholder="选择日期时间"/>
            v-model="formData.endTime"
            type="datetime"
            format="YYYY-MM-DD HH:mm:00"
            value-format="YYYY-MM-DD HH:mm:00"
            placeholder="选择日期时间"/>
        </el-form-item>
        <el-form-item label="预测时间">
          <el-date-picker
              size="mini"
              v-model="formData.predictTime"
              type="datetime"
              placeholder="选择日期时间"/>
            v-model="formData.predictTime"
            type="datetime"
            format="YYYY-MM-DD HH:mm:00"
            value-format="YYYY-MM-DD HH:mm:00"
            placeholder="选择日期时间"/>
        </el-form-item>
        <el-form-item label="预测频率">
          <el-input-number size="mini" v-model="formData.predictFreq" controls-position="right" :min="1"
          <el-input-number v-model="formData.predictFreq" controls-position="right"
                           :min="1"
                           :max="10"/>
        </el-form-item>
        <el-form-item>
          <el-button-group>
            <el-button size="mini" type="primary" plain :icon="ArrowLeft"
                       v-loading="loading1" @click="leftSearchDataByRange()"/>
            <el-button size="mini" type="primary" plain :icon="Search"
                       v-loading="loading1" @click="getList()">查询</el-button>
            <el-button size="mini" type="primary" plain :icon="ArrowRight"
                       v-loading="loading1" @click="rightSearchDataByRange()"/>
            <el-button type="primary" plain :icon="ArrowLeft"
                       :loading="loading1" @click="leftSearchDataByRange()"/>
            <el-button type="primary" plain :icon="Search"
                       :loading="loading1" @click="getList()">查询
            </el-button>
            <el-button type="primary" plain :icon="ArrowRight"
                       :loading="loading1" @click="rightSearchDataByRange()"/>
          </el-button-group>
        </el-form-item>
@@ -42,46 +47,52 @@
          <div class="his-body-left">
            <div class="his-body-tree">
              <el-tree
                  :data="treeData"
                  show-checkbox
                  node-key="id"
                  ref="tree"
                  highlight-current
                  :props="defaultProps"
                  @check="onCheckTree"/>
                :data="treeData"
                show-checkbox
                node-key="id"
                ref="tree"
                highlight-current
                :props="defaultProps"
                @check="onCheckTree"/>
            </div>
          </div>
          <div class="his-body-right">
            <div class="his-body-chart">
              <el-form :inline="true" :model="calRateForm" :rules="formRules" ref="calRateForm" label-width="108px">
              <el-form :inline="true" :model="calRateForm" :rules="formRules" ref="calRateFormRef"
                       label-width="108px">
                <el-row>
                  <el-col :span="6" >
                  <el-col :span="6">
                    <el-form-item label="预测项" prop="calItem" style="width: 90%">
                      <el-select v-model="calRateForm.calItem" @change="calItemBaseVale" placeholder="请选择">
                      <el-select size="small" v-model="calRateForm.calItem"
                                 @change="calItemBaseVale"
                                 placeholder="请选择">
                        <el-option
                            v-for="item in formData.checkedItemData"
                            :key="item.id"
                            :label="item.label"
                            :value="item.id"/>
                          v-for="itemOut in formData.checkedItemData"
                          :key="itemOut.id"
                          :label="itemOut.label"
                          :value="itemOut.id"/>
                      </el-select>
                    </el-form-item>
                  </el-col>
                  <el-col :span="6">
                    <el-form-item label="精准度偏差" prop="IN_DEVIATION">
                      <el-input-number size="mini" v-model="calRateForm.IN_DEVIATION" controls-position="right" :min="1"
                      <el-input-number size="small" v-model="calRateForm.IN_DEVIATION"
                                       controls-position="right" :min="1"
                                       :max="10"/>
                    </el-form-item>
                  </el-col>
                  <el-col :span="6">
                    <el-form-item label="不可信率偏差" prop="OUT_DEVIATION">
                      <el-input-number size="mini" v-model="calRateForm.OUT_DEVIATION" controls-position="right"
                      <el-input-number size="small" v-model="calRateForm.OUT_DEVIATION"
                                       controls-position="right"
                                       :min="1"
                                       :max="20"/>
                    </el-form-item>
                  </el-col>
                  <el-col :span="4">
                    <el-form-item>
                      <el-button size="mini" type="primary" plain :loading="loading2" @click="calAccuracyRate">计算精准度
                      <el-button size="small" type="primary" plain :loading="loading2"
                                 @click="calAccuracyRate">计算精准度
                      </el-button>
                    </el-form-item>
                  </el-col>
@@ -89,54 +100,54 @@
                <el-row>
                  <el-col :span="4">
                    <el-form-item label="精准度:">
                      {{calRateForm.IN_ACCURACY_RATE}}%
                      {{ calRateForm.IN_ACCURACY_RATE }}%
                    </el-form-item>
                  </el-col>
                  <el-col :span="4">
                    <el-form-item label="预测平均值:">
                      {{calRateForm.itemPreAvg}}
                      {{ calRateForm.itemPreAvg }}
                    </el-form-item>
                  </el-col>
                  <el-col :span="4">
                    <el-form-item label="预测最大值:">
                      {{calRateForm.itemPreMax}}
                      {{ calRateForm.itemPreMax }}
                    </el-form-item>
                  </el-col>
                  <el-col :span="4">
                    <el-form-item label="预测最小值:">
                      {{calRateForm.itemPreMin}}
                      {{ calRateForm.itemPreMin }}
                    </el-form-item>
                  </el-col>
                  <el-col :span="4">
                    <el-form-item label="预测累积量:">
                      {{calRateForm.preCumulant}}
                      {{ calRateForm.preCumulant }}
                    </el-form-item>
                  </el-col>
                </el-row>
                <el-row>
                  <el-col :span="4">
                    <el-form-item label="不可信率:">
                      {{calRateForm.OUT_ACCURACY_RATE}}%
                      {{ calRateForm.OUT_ACCURACY_RATE }}%
                    </el-form-item>
                  </el-col>
                  <el-col :span="4">
                    <el-form-item label="真实平均值:">
                      {{calRateForm.itemAvg}}
                      {{ calRateForm.itemAvg }}
                    </el-form-item>
                  </el-col>
                  <el-col :span="4">
                    <el-form-item label="真实最大值:">
                      {{calRateForm.itemMax}}
                      {{ calRateForm.itemMax }}
                    </el-form-item>
                  </el-col>
                  <el-col :span="4">
                    <el-form-item label="真实最小值:">
                      {{calRateForm.itemMin}}
                      {{ calRateForm.itemMin }}
                    </el-form-item>
                  </el-col>
                  <el-col :span="4">
                    <el-form-item label="真实累积量:">
                      {{calRateForm.realCumulant}}
                      {{ calRateForm.realCumulant }}
                    </el-form-item>
                  </el-col>
                </el-row>
@@ -146,20 +157,25 @@
                  <el-col :span="12">
                    <el-form-item label="数据类型">
                      <el-checkbox-group v-model="formData.chartCheck" @change="changeChartCheck">
                        <el-checkbox v-for="item in formData.chartOptions" :label="item" :key="item">{{item}}
                        <el-checkbox v-for="item in formData.chartOptions" :label="item"
                                     :key="item">{{ item }}
                        </el-checkbox>
                      </el-checkbox-group>
                    </el-form-item>
                  </el-col>
                  <el-col :span="6">
                    <el-form-item>
                      <el-radio v-model="formData.isMultipleY" :label="false" @input="onChangeMultipleY">单坐标轴</el-radio>
                      <el-radio v-model="formData.isMultipleY" :label="true" @input="onChangeMultipleY">多坐标轴</el-radio>
                      <el-radio v-model="formData.isMultipleY" :label="false"
                                @input="onChangeMultipleY">单坐标轴
                      </el-radio>
                      <el-radio v-model="formData.isMultipleY" :label="true"
                                @input="onChangeMultipleY">多坐标轴
                      </el-radio>
                    </el-form-item>
                  </el-col>
                </el-row>
              </el-form>
              <div id="data-analysis" style="height: 500px;"></div>
              <div ref="dataAnalysisChart" style="height: 500px;"></div>
            </div>
          </div>
        </div>
@@ -168,31 +184,479 @@
  </el-card>
</template>
<script lang="ts" setup>
  import {getYMDHMS} from "@/utils/dateUtil"
  import * as CategoryApi from "@/api/data/ind/category";
  import * as DmModule from '@/api/model/pre/dm'
  import * as ItemApi from "@/api/data/ind/item/item";
  import * as MmPredictItem from '@/api/model/pre/item'
  import * as echarts from "echarts";
  import { onMounted, ref } from 'vue';
  import { Search, ArrowLeft, ArrowRight,} from '@element-plus/icons-vue'
import {getYMDHMS} from "@/utils/dateUtil"
import * as McsApi from '@/api/model/mcs'
import * as echarts from "echarts";
import {Search, ArrowLeft, ArrowRight,} from '@element-plus/icons-vue'
  defineOptions({name: 'AnalysisformData'})
defineOptions({name: 'AnalysisformData'})
  const message = useMessage() // 消息弹窗
  const { t } = useI18n() // 国际化
  const dataCategoryList = ref([] as CategoryApi.IndItemCategoryVO[])
  const loading1 = ref(false) // 列表的加载中
  const loading2 = ref(false) // 列表的加载中
  const total = ref(0) // 列表的总页数
  const list = ref([]) // 字典表格数据
  const queryParams = reactive({
    pageNo: 1,
    pageSize: 10,
    itemno: '',
    itemname: '',
const message = useMessage() // 消息弹窗
const {t} = useI18n() // 国际化
const dataAnalysisChart = ref(null);
const loading1 = ref(false) // 列表的加载中
const loading2 = ref(false) // 列表的加载中
const total = ref(0) // 列表的总页数
const list = ref([]) // 字典表格数据
let formData = ref({
  rangeDate: '',
  startTime: '',
  endTime: '',
  predictTime: '',
  predictTimeStr: '',
  startTimeStr: '',
  endTimeStr: '',
  predictTimeStamp: 0,
  startTimeStamp: 0,
  endTimeStamp: 0,
  currentStamp: '',
  currentStamp60: '',
  predictStamp: '',
  chartCheck: ['T+L', '真实值'],
  chartOptions: ['T+N', 'T+L', '当时', '真实值', '调整值'],
  checkedItemData: [],
  backItem: '',
  backValue: 0,
  backCoe: 1,
  preCumulant: 0,
  realCumulant: 0,
  queryStep: 2,
  isMultipleYRadio: '单坐标轴',
  isMultipleY: false,
  predictFreq: 3,
})
const calRateFormRef = ref()
const calRateForm = ref({
  calItem: undefined,
  IN_DEVIATION: 0,
  OUT_DEVIATION: 0,
  IN_ACCURACY_RATE: 0,
  OUT_ACCURACY_RATE: 0,
  itemAvg: 0,
  itemMax: 0,
  itemMin: 0,
  itemPreAvg: 0,
  itemPreMax: 0,
  itemPreMin: 0,
  preCumulant: 0,
  realCumulant: 0
})
let itemData = ref({
  currentTreeList: [],
  chart: {},
  option: {}
})
const treeData = ref([])
const itemDataObject = ref()
const timer = ref()
let myChart = null;
const formRules = reactive({
  calItem: [{required: true, message: '预测项不能为空', trigger: 'blur'}],
  IN_DEVIATION: [{required: true, message: '精准度偏差不能为空', trigger: 'blur'}],
  OUT_DEVIATION: [{required: true, message: '不可信率偏差不能为空', trigger: 'blur'}],
})
/** 查询列表 */
const getList = async () => {
  loading1.value = true
  try {
    if (!formData.value.chartCheck) {
      formData.value.chartCheck = ['真实值']
    }
    let chartCheckArray = formData.value.chartCheck;
    if (!formData.value.checkedItemData || formData.value.checkedItemData.length == 0) {
      itemData.value.option = {};
      return;
    }
    let outIds = formData.value.checkedItemData.map(item => {
      return item.id
    })
    const params = reactive({
      outIds: outIds,
      predictTime: formData.value.predictTime,
      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
    let xAxisData = data.categories;
    let yAxisData = [];
    let offset = 0;
    let yAxisIndex = 0;
    let legendData = [];
    let yMaxArr = [];
    let seriesData = [];
    seriesData.push({
      name: '',
      data: [null],
      type: 'line',
      smooth: true,
      color: 'green',
      markLine: {
        silent: true,
        lineStyle: {
          color: '#32a487',
          width: 2
        },
        data: [{
          xAxis: formData.value.predictTime
        }],
        label: {
          normal: {
            formatter: formData.value.predictTime
          }
        },
        symbol: ['circle', 'none'],
      },
    });
    itemDataObject.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;
      let yMax = maxValue;
      if (maxValue < 0) {
        maxValue = 1;
      } else if (maxValue < 10) {
        yMax = (Math.ceil(maxValue * 11) / 10).toFixed(1);
      } else if (maxValue < 100) {
        yMax = (Math.ceil(maxValue * 1.1 / 5) * 5);
      } else {
        yMax = (Math.ceil(maxValue * 1.1 / 10) * 10);
      }
      yMaxArr.push(yMax);
      let yMin = minValue;
      if (minValue >= 0) {
        yMin = 0;
      } else if (minValue > -10) {
        yMin = (Math.floor(minValue * 11) / 10).toFixed(1);
      } else if (minValue > -100) {
        yMin = (Math.floor(minValue * 1.1 / 5) * 5);
      } else {
        yMin = (Math.floor(minValue * 1.1 / 10) * 10);
      }
      yAxisData.push({
        type: 'value',
        name: "",
        min: yMin,
        max: yMax,
        position: 'left',
        offset: offset,
        splitLine: {
          show: false
        },
        axisLine: {
          show: true,
          lineStyle: {}
        },
        axisLabel: {
          formatter: '{value}'
        }
      })
      offset = offset + 40
      if (chartCheckArray.indexOf('真实值') !== -1) {
        let legendName = dataView.resultName + '(真实)';
        legendData.push(legendName);
        seriesData.push({
          name: legendName,
          data: dataView.realData || [],
          type: 'line',
          yAxisIndex: yAxisIndex,
          showSymbol: false,
          smooth: true,
          lineStyle: {
            width: 2
          }
        });
      }
      if (chartCheckArray.indexOf('T+N') !== -1) {
        let legendName = dataView.resultName + '(T+N)';
        seriesData.push({
          name: legendName,
          data: dataView.preDataN || [],
          type: 'line',
          yAxisIndex: yAxisIndex,
          showSymbol: false,
          smooth: true,
          lineStyle: {
            width: 2
          }
        });
      }
      if (chartCheckArray.indexOf('T+L') !== -1) {
        let legendName = dataView.resultName + '(T+L)';
        legendData.push(legendName);
        seriesData.push({
          name: legendName,
          data: dataView.preDataL || [],
          type: 'line',
          showSymbol: false,
          connectNulls: true,
          yAxisIndex: yAxisIndex,
          smooth: true,
          lineStyle: {
            width: 2
          }
        });
      }
      if (chartCheckArray.indexOf('当时') !== -1) {
        let legendName = dataView.resultName + '(当时)';
        legendData.push(legendName);
        seriesData.push({
          name: legendName,
          data: dataView.curData || [],
          type: 'line',
          yAxisIndex: yAxisIndex,
          showSymbol: false,
          smooth: true,
          lineStyle: {
            width: 2
          }
        });
      }
      if (chartCheckArray.indexOf('调整值') !== -1) {
        let legendName = dataView.resultName + '(调整值)';
        legendData.push(legendName);
        seriesData.push({
          name: legendName,
          data: dataView.adjData || [],
          type: 'line',
          yAxisIndex: yAxisIndex,
          showSymbol: false,
          connectNulls: true,
          smooth: true,
          lineStyle: {
            width: 2,
            type: 'dashed'
          }
        });
      }
    }
    //如果最大值相差不大,改成一致大小
    if (yMaxArr.length > 1) {
      let max = Math.max.apply(null, yMaxArr);
      let min = Math.min.apply(null, yMaxArr);
      if (Math.abs((max - min) / max) <= 0.2) {
        for (let i = 0; i < yAxisData.length; i++) {
          yAxisData[i].max = max;
        }
      }
    }
    myChart = echarts.init(dataAnalysisChart.value);
    let option = {
      title: {
        text: ''
      },
      tooltip: {
        trigger: 'axis'
      },
      legend: {
        show: true,
        data: legendData,
        top: 10
      },
      grid: {
        top: '20%',
        left: '3%',
        right: '6%',
        bottom: '3%',
        containLabel: true
      },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: xAxisData
      },
      yAxis: formData.value.isMultipleY ? yAxisData : {
        type: 'value',
        splitLine: {show: false},
        axisLine: {show: true}
      },
      dataZoom: [
        {
          type: 'inside',
          start: 0,
          end: 100
        },
        {
          start: 0,
          end: 10
        }
      ],
      series: seriesData
    }
    myChart.clear()
    myChart.setOption(option)
  } finally {
    loading1.value = false
  }
}
onMounted(() => {
  resetForm()
  getPreItemTree()
})
async function getPreItemTree() {
  treeData.value = await McsApi.getPredictItemTree()
}
function leftSearchDataByRange() {
  let mins = getRangeMins();
  let startTime = formData.value.startTime;
  let endTime = formData.value.endTime;
  let predictTime = formData.value.predictTime;
  if (predictTime) {
    predictTime = getYMDHMS(new Date(predictTime) - 1000 * 60 * mins);
    formData.value.predictTime = predictTime;
  }
  if (startTime) {
    startTime = getYMDHMS(new Date(startTime) - 1000 * 60 * mins);
    formData.value.startTime = startTime;
  }
  if (endTime) {
    endTime = getYMDHMS(new Date(endTime) - 1000 * 60 * mins);
    formData.value.endTime = endTime;
  }
  getList();
}
function getRangeMins() {
  let result: string | number = 0;
  if (formData.value.startTime && formData.value.endTime) {
    let startStamp = new Date(formData.value.startTime).getTime();
    let endStamp = new Date(formData.value.endTime).getTime();
    let queryStep = ((endStamp - startStamp) / (1000 * 60)).toFixed(0);
    result = queryStep >= 0 ? queryStep : 0;
  }
  return result;
}
function onCheckTree(data, checked, indeterminate) {
  formData.value.checkedItemData = [];
  if (checked.checkedNodes) {
    formData.value.checkedItemData = [...checked.checkedNodes]
  }
  debounce(getList, 1000);
}
function debounce(func, wait) {
  let args = [];
  if (timer.value) {
    clearTimeout(timer.value);
  }
  timer.value = setTimeout(() => {
    func.apply(this, args);
    timer.value = null;
  }, wait)
}
function calItemBaseVale() {
  if (!calRateForm.value.calItem) {
    calRateForm.value.itemPreMax = 0;
    calRateForm.value.itemPreMin = 0;
    calRateForm.value.itemPreAvg = 0;
    calRateForm.value.preCumulant = 0;
    calRateForm.value.itemMax = 0;
    calRateForm.value.itemMin = 0;
    calRateForm.value.itemAvg = 0;
    calRateForm.value.realCumulant = 0;
  } else {
    let dataView = itemDataObject.value[calRateForm.value.calItem]
    calRateForm.value.itemPreMax = dataView.preMax;
    calRateForm.value.itemPreMin = dataView.preMin;
    calRateForm.value.itemPreAvg = dataView.preAvg;
    calRateForm.value.preCumulant = dataView.preCumulant;
    calRateForm.value.itemMax = dataView.hisMax;
    calRateForm.value.itemMin = dataView.hisMin;
    calRateForm.value.itemAvg = dataView.hisAvg;
    calRateForm.value.realCumulant = dataView.hisCumulant;
  }
}
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;
    }
    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;
  })
  let formData = ref({
}
function rightSearchDataByRange() {
  let mins = getRangeMins();
  let startTime = formData.value.startTime;
  let endTime = formData.value.endTime;
  let predictTime = formData.value.predictTime;
  if (predictTime) {
    predictTime = getYMDHMS(new Date(predictTime) - 0 + 1000 * 60 * mins);
    formData.value.predictTime = predictTime;
  }
  if (startTime) {
    startTime = getYMDHMS(new Date(startTime) - 0 + 1000 * 60 * mins);
    formData.value.startTime = startTime;
  }
  if (endTime) {
    endTime = getYMDHMS(new Date(endTime) - 0 + 1000 * 60 * mins);
    formData.value.endTime = endTime;
  }
  getList();
}
/** 重置表单 */
const resetForm = () => {
  formData.value = {
    rangeDate: '',
    startTime: '',
    endTime: '',
@@ -218,9 +682,9 @@
    isMultipleYRadio: '单坐标轴',
    isMultipleY: false,
    predictFreq: 3,
  })
  let calRateForm = ref({
    calItem: '',
  }
  calRateForm.value = {
    calItem: undefined,
    IN_DEVIATION: 0,
    OUT_DEVIATION: 0,
    IN_ACCURACY_RATE: 0,
@@ -231,462 +695,47 @@
    itemPreAvg: 0,
    itemPreMax: 0,
    itemPreMin: 0,
    preCumulant:0,
    realCumulant:0
  })
  let itemData = ref({
    currentTreeList: [],
    chart: {},
    option: {}
  })
  const chartContainer = ref(null);
  const treeData = ref([])
  const itemDataObject = ref()
  const timer = ref()
  const formRules = reactive({
    calItem: [{required: true, message: '预测项不能为空', trigger: 'blur'}],
    IN_DEVIATION: [{required: true, message: '精准度偏差不能为空', trigger: 'blur'}],
    OUT_DEVIATION: [{required: true, message: '不可信率偏差不能为空', trigger: 'blur'}],
  })
  //const myChart = echarts.init(document.getElementById("data-analysis"));
  /** 查询列表 */
  const getList = async () => {
    loading1.value = true
    try {
      const data = formData.value
      if (!formData.value.chartCheck) {
        formData.value.chartCheck = ['真实值']
      }
      let chartCheckArray = formData.value.chartCheck;
      if (!formData.value.checkedItemData || formData.value.checkedItemData.length == 0) {
        itemData.value.option = {};
        return;
      }
      let itemIdList = formData.value.checkedItemData.map(item => {
        return item.id
      })
      const params = ref({
        itemIds: itemIdList.join(','),
        predictTime: formData.value.predictTime,
        startTime: formData.value.startTime,
        endTime: formData.value.endTime
      })
      const res = await MmPredictItem.getViewCharts(params)
      if (res.code !== 0) {
        return message.error(res.msg)
      }
      formData.value.predictTime = res.data.predictTime;
      formData.value.startTime = res.data.startTime
      formData.value.endTime = res.data.endTime
      let xAxisData = res.data.categories;
      let yAxisData = [];
      let offset = 0;
      let yAxisIndex = 0;
      let legendData = [];
      let yMaxArr = [];
      let seriesData = [];
      seriesData.push({
        name: '',
        data: [null],
        type: 'line',
        smooth: true,
        color: 'green',
        markLine: {
          silent: true,
          lineStyle: {
            color: '#32a487',
            width: 2
          },
          data: [{
            xAxis: formData.value.predictTime
          }],
          label: {
            normal: {
              formatter: formData.value.predictTime
            }
          },
          symbol: ['circle', 'none'],
        },
      });
      itemDataObject.value = {}
      for (let i = 0; i < res.data.dataViewList.length; i++) {
        let dataView = res.data.dataViewList[i]
        itemDataObject.value.dataView.itemId = dataView;
        let maxValue = dataView.maxValue;
        let minValue = dataView.minValue;
        yAxisIndex = formData.value.isMultipleY ? i : 0;
        let yMax = maxValue;
        if (maxValue < 0) {
          maxValue = 1;
        } else if (maxValue < 10) {
          yMax = (Math.ceil(maxValue * 11) / 10).toFixed(1);
        } else if (maxValue < 100) {
          yMax = (Math.ceil(maxValue * 1.1 / 5) * 5);
        } else {
          yMax = (Math.ceil(maxValue * 1.1 / 10) * 10);
        }
        yMaxArr.push(yMax);
        let yMin = minValue;
        if (minValue >= 0) {
          yMin = 0;
        } else if (minValue > -10) {
          yMin = (Math.floor(minValue * 11) / 10).toFixed(1);
        } else if (minValue > -100) {
          yMin = (Math.floor(minValue * 1.1 / 5) * 5);
        } else {
          yMin = (Math.floor(minValue * 1.1 / 10) * 10);
        }
        yAxisData.push({
          type: 'value',
          name: "",
          min: yMin,
          max: yMax,
          position: 'left',
          offset: offset,
          splitLine: {
            show: false
          },
          axisLine: {
            show: true,
            lineStyle: {}
          },
          axisLabel: {
            formatter: '{value}'
          }
        })
        offset = offset + 40
        if (chartCheckArray.indexOf('真实值') !== -1) {
          let legendName = dataView.itemName + '(真实)';
          legendData.push(legendName);
          seriesData.push({
            name: legendName,
            data: dataView.realData || [],
            type: 'line',
            yAxisIndex: yAxisIndex,
            showSymbol: false,
            smooth: true,
            lineStyle: {
              width: 3
            }
          });
        }
        if (chartCheckArray.indexOf('T+N') !== -1) {
          let legendName = dataView.itemName + '(T+N)';
          seriesData.push({
            name: legendName,
            data: dataView.preDataN || [],
            type: 'line',
            yAxisIndex: yAxisIndex,
            showSymbol: false,
            smooth: true,
            lineStyle: {
              width: 3
            }
          });
        }
        if (chartCheckArray.indexOf('T+L') !== -1) {
          let legendName = dataView.itemName + '(T+L)';
          legendData.push(legendName);
          seriesData.push({
            name: legendName,
            data: dataView.preDataL || [],
            type: 'line',
            showSymbol: false,
            connectNulls: true,
            yAxisIndex: yAxisIndex,
            smooth: true,
            lineStyle: {
              width: 3
            }
          });
        }
        if (chartCheckArray.indexOf('当时') !== -1) {
          let legendName = dataView.itemName + '(当时)';
          legendData.push(legendName);
          seriesData.push({
            name: legendName,
            data: dataView.curData || [],
            type: 'line',
            yAxisIndex: yAxisIndex,
            showSymbol: false,
            smooth: true,
            lineStyle: {
              width: 3
            }
          });
        }
        if (chartCheckArray.indexOf('调整值') !== -1) {
          let legendName = dataView.itemName + '(调整值)';
          legendData.push(legendName);
          seriesData.push({
            name: legendName,
            data: dataView.adjData || [],
            type: 'line',
            yAxisIndex: yAxisIndex,
            showSymbol: false,
            connectNulls: true,
            smooth: true,
            lineStyle: {
              width: 3,
              type: 'dashed'
            }
          });
        }
      }
      //如果最大值相差不大,改成一致大小
      if (yMaxArr.length > 1) {
        let max = Math.max.apply(null, yMaxArr);
        let min = Math.min.apply(null, yMaxArr);
        if (Math.abs((max - min) / max) <= 0.2) {
          for (let i = 0; i < yAxisData.length; i++) {
            yAxisData[i].max = max;
          }
        }
      }
      let option = {
        title: {
          text: ''
        },
        tooltip: {
          trigger: 'axis'
        },
        legend: {
          show: true,
          data: legendData,
          top: 10
        },
        grid: {
          top: 50,
          left: '3%',
          right: '6%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: xAxisData
        },
        yAxis: formData.value.isMultipleY ? yAxisData : {
          type: 'value',
          splitLine: {show: false},
          axisLine: {show: true}
        },
        dataZoom: [
          {
            type: 'inside',
            start: 0,
            end: 100
          },
          {
            start: 0,
            end: 10
          }
        ],
        series: seriesData
      }
      //chart.setOption(option)
    } finally {
      loading1.value = false
    }
    preCumulant: 0,
    realCumulant: 0
  }
  onMounted(() => {
    getPreItemTree()
    getList()
  })
  async function getPreItemTree() {
    treeData.value = await MmPredictItem.getMmPredictItemTree()
  }
  function leftSearchDataByRange() {
    let mins = getRangeMins();
    let startTime = formData.value.startTime;
    let endTime = formData.value.endTime;
    let predictTime = formData.value.predictTime;
    if (predictTime) {
      predictTime = getYMDHMS(new Date(predictTime) - 1000 * 60 * mins);
      formData.value.predictTime = predictTime;
    }
    if (startTime) {
      startTime = getYMDHMS(new Date(startTime) - 1000 * 60 * mins);
      formData.value.startTime = startTime;
    }
    if (endTime) {
      endTime = getYMDHMS(new Date(endTime) - 1000 * 60 * mins);
      formData.value.endTime = endTime;
    }
    getList();
  }
  function getRangeMins () {
    let result: string | number = 0;
    if(formData.value.startTime && formData.value.endTime) {
      let startStamp = new Date(formData.value.startTime).getTime();
      let endStamp = new Date(formData.value.endTime).getTime();
      let queryStep = ((endStamp - startStamp) / (1000 * 60)).toFixed(0);
      result = queryStep >= 0 ? queryStep : 0;
    }
    return result;
  }
  function onCheckTree(data, checked, indeterminate) {
    formData.value.checkedItemData = [];
    if (checked.checkedNodes) {
      formData.value.checkedItemData = [...checked.checkedNodes]
    }
    //myChart.clear()
    debounce(getList(), 1000);
  }
  function debounce(func, wait) {
    let args = [];
    if (timer.value) {
      clearTimeout(timer.value);
    }
    timer.value = setTimeout(() => {
      func.apply(this, args);
      timer.value = null;
    }, wait)
  }
  function calItemBaseVale() {
    if (!calRateForm.value.calItem) {
      calRateForm.value.itemPreMax = 0;
      calRateForm.value.itemPreMin = 0;
      calRateForm.value.itemPreAvg = 0;
      calRateForm.value.preCumulant = 0;
      calRateForm.value.itemMax = 0;
      calRateForm.value.itemMin = 0;
      calRateForm.value.itemAvg = 0;
      calRateForm.value.realCumulant = 0;
      return
    } else {
      let dataView = itemDataObject[calRateForm.value.calItem]
      calRateForm.value.itemPreMax = dataView.preMax;
      calRateForm.value.itemPreMin = dataView.preMin;
      calRateForm.value.itemPreAvg = dataView.preAvg;
      calRateForm.value.preCumulant = dataView.preCumulant;
      calRateForm.value.itemMax = dataView.hisMax;
      calRateForm.value.itemMin = dataView.hisMin;
      calRateForm.value.itemAvg = dataView.hisAvg;
      calRateForm.value.realCumulant = dataView.hisCumulant;
    }
  }
  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;
      }
      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() {
    let mins = getRangeMins();
    let startTime = formData.value.startTime;
    let endTime = formData.value.endTime;
    let predictTime = formData.value.predictTime;
    if (predictTime) {
      predictTime = getYMDHMS(new Date(predictTime) - 0 + 1000 * 60 * mins);
      formData.value.predictTime = predictTime;
    }
    if (startTime) {
      startTime = getYMDHMS(new Date(startTime) - 0 + 1000 * 60 * mins);
      formData.value.startTime = startTime;
    }
    if (endTime) {
      endTime = getYMDHMS(new Date(endTime) - 0 + 1000 * 60 * mins);
      formData.value.endTime = endTime;
    }
    getList();
  }
  calRateFormRef.value?.resetFields()
}
</script>
<style scoped>
  .el-form-item {
    margin-bottom: 0 !important;
  }
.el-form-item {
  margin-bottom: 0 !important;
}
  .his-body-chart {
    height: 100%;
    border: 1px solid lightgray;
    padding: 10px;
  }
.his-body-chart {
  height: 100%;
  border: 1px solid lightgray;
  padding: 10px;
}
  .his-body-tree {
    height: 100%;
    border: 1px solid lightgray;
    padding: 10px;
  }
.his-body-tree {
  height: 100%;
  border: 1px solid lightgray;
  padding: 10px;
}
  .his-body-right {
    width: 80%;
    height: 100%;
    padding-top: 10px;
  }
.his-body-right {
  width: 80%;
  height: 100%;
  padding-top: 10px;
}
  .his-body-left {
    width: 20%;
    height: 100%;
    padding: 10px 10px 0 0;
  }
.his-body-left {
  width: 20%;
  height: 100%;
  padding: 10px 10px 0 0;
}
  .his-body {
    width: 100%;
    height: calc(calc(100vh - 68px - 38px - 160px));
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    align-content: flex-start;
  }
.his-body {
  width: 100%;
  height: calc(calc(100vh - 68px - 38px - 160px));
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-content: flex-start;
}
</style>