对比新文件 |
| | |
| | | <template> |
| | | <el-card shadow="never" class="aui-card--fill"> |
| | | <div class="mod-his__index"> |
| | | <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="选择日期时间"/> |
| | | </el-form-item> |
| | | <el-form-item label="结束时间"> |
| | | <el-date-picker |
| | | size="mini" |
| | | v-model="formData.endTime" |
| | | type="datetime" |
| | | placeholder="选择日期时间"/> |
| | | </el-form-item> |
| | | <el-form-item label="预测时间"> |
| | | <el-date-picker |
| | | size="mini" |
| | | v-model="formData.predictTime" |
| | | type="datetime" |
| | | placeholder="选择日期时间"/> |
| | | </el-form-item> |
| | | <el-form-item label="预测频率"> |
| | | <el-input-number size="mini" 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-group> |
| | | </el-form-item> |
| | | |
| | | <div class="his-body"> |
| | | <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"/> |
| | | </div> |
| | | </div> |
| | | <div class="his-body-right"> |
| | | <div class="his-body-chart"> |
| | | <el-form :inline="true" :model="calRateForm" ref="calRateForm" label-width="100px"> |
| | | <el-row> |
| | | <el-col :span="6" > |
| | | <el-form-item label="预测项" prop="calItem" style="width: 90%"> |
| | | <el-select v-model="calRateForm.calItem" @change="calItemBaseVale" placeholder="请选择"> |
| | | <el-option |
| | | v-for="item in formData.checkedItemData" |
| | | :key="item.id" |
| | | :label="item.label" |
| | | :value="item.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" |
| | | :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" |
| | | :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> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="4"> |
| | | <el-form-item label="精准度:"> |
| | | {{calRateForm.IN_ACCURACY_RATE}}% |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item label="预测平均值:"> |
| | | {{calRateForm.itemPreAvg}} |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item label="预测最大值:"> |
| | | {{calRateForm.itemPreMax}} |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item label="预测最小值:"> |
| | | {{calRateForm.itemPreMin}} |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item label="预测累积量:"> |
| | | {{calRateForm.preCumulant}} |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <el-row> |
| | | <el-col :span="4"> |
| | | <el-form-item label="不可信率:"> |
| | | {{calRateForm.OUT_ACCURACY_RATE}}% |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item label="真实平均值:"> |
| | | {{calRateForm.itemAvg}} |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item label="真实最大值:"> |
| | | {{calRateForm.itemMax}} |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item label="真实最小值:"> |
| | | {{calRateForm.itemMin}} |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="4"> |
| | | <el-form-item label="真实累积量:"> |
| | | {{calRateForm.realCumulant}} |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <el-form :inline="true" :model="formData" label-width="100px"> |
| | | <el-row> |
| | | <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> |
| | | </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-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <div id="data-analysis" style="height: 500px;"></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </el-form> |
| | | |
| | | </div> |
| | | </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/predict' |
| | | import * as echarts from "echarts"; |
| | | import { onMounted, ref } from 'vue'; |
| | | import { Search, ArrowLeft, ArrowRight,} from '@element-plus/icons-vue' |
| | | |
| | | 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: '', |
| | | }) |
| | | 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, |
| | | }) |
| | | let calRateForm = ref({ |
| | | calItem: '', |
| | | 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 chartContainer = ref(null); |
| | | const treeData = ref([]) |
| | | const itemDataObject = ref() |
| | | const timer = ref() |
| | | //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 |
| | | } |
| | | } |
| | | |
| | | 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(); |
| | | } |
| | | |
| | | </script> |
| | | <style scoped> |
| | | .el-form-item { |
| | | margin-bottom: 0 !important; |
| | | } |
| | | |
| | | .his-body-chart { |
| | | 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-left { |
| | | width: 20%; |
| | | height: 100%; |
| | | padding: 10px 10px 0 0; |
| | | } |
| | | |
| | | .his-body { |
| | | width: 100%; |
| | | height: calc(calc(100vh - 48px - 38px - 130px)); |
| | | display: flex; |
| | | flex-direction: row; |
| | | justify-content: flex-start; |
| | | align-content: flex-start; |
| | | } |
| | | </style> |