From c6159b0a5a424250adeca1bc2b475da5324fe038 Mon Sep 17 00:00:00 2001 From: web <candymxq888@outlook.com> Date: 星期五, 18 四月 2025 17:16:30 +0800 Subject: [PATCH] fix:对接报表数据 --- src/views/screen/temperature/graphic/index.vue | 376 ++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 258 insertions(+), 118 deletions(-) diff --git a/src/views/screen/temperature/graphic/index.vue b/src/views/screen/temperature/graphic/index.vue index ef65b59..235ce02 100644 --- a/src/views/screen/temperature/graphic/index.vue +++ b/src/views/screen/temperature/graphic/index.vue @@ -1,57 +1,68 @@ <script setup> -import {ref, reactive, onMounted} from "vue"; +import {ref, onMounted, watch} from "vue"; import * as echarts from 'echarts/core'; -import html2canvas from "html2canvas"; +import {getTemperaturePointList} from '@/api/screen/index.js' +import Quarter from "@/components/Quarter"; +import moment from "moment"; +import { getGraphicData } from '@/api/screen/graphic/index.js' -const startTime = ref() -const endTime = ref() +const menuList = ref([]) +const timeType = ref(1) //时间类型 1日 2周 3月 4季 5年 +const showTime = ref(moment().format('YYYY-MM-DD')); //展示时间 +const timeValue = ref(moment().format('YYYY-MM-DD')) //处理后得时间 const searchVal = ref() -const selectType = ref(1); -const typeOption = ref([ - { label: '水电站流量监测点', value: 1 }, - { label: '新扎口流量监测点', value: 2 }, -]) const graphicRef = ref(null) const chartsRef = ref([]) //动态生成图表ref +const chartData = ref([]) let charts = [] // 动态设置ref -const setChartsRef = (el ,index) => { - if(el){ +const setChartsRef = (el, index) => { + if (el) { chartsRef.value[index] = el charts[index] = 'charts' + index } } -const data = [ - [ {name: '一月', value: 22}, {name: '二月', value: 38}, {name: '三月', value: 31}, ], - [ {name: '一月', value: 22}, {name: '二月', value: 38}, {name: '三月', value: 31}, ], - [ {name: '一月', value: 22}, {name: '二月', value: 38}, {name: '三月', value: 31}, ], - [ {name: '一月', value: 22}, {name: '二月', value: 38}, {name: '三月', value: 31}, ], - [ {name: '一月', value: 22}, {name: '二月', value: 38}, {name: '三月', value: 31}, ], - [ {name: '一月', value: 22}, {name: '二月', value: 38}, {name: '三月', value: 31}, ], -] - // 获取图表配置 -const getChartsOptions = (data, unit, maxData, minData=0) => { +const getChartsOptions = (data, unit) => { let xdata = []; - let sdata = []; - if(data) { - data.forEach(item => { - xdata.push(item.name) - sdata.push(item.value); + let Hdata = []; + let Adata = []; + let Ldata = []; + if (data) { + data.dataVOList.forEach(item => { + xdata.push(item.dataTime) + Hdata.push(item.maxValue); + Adata.push(item.avgValue); + Ldata.push(item.minValue); }) } return { + title: { + text: data.pointName, + left: '3%', + textStyle: { + color: '#fff', + } + }, tooltip: { trigger: 'axis', }, + color: ['#D4B3E3FF', '#00DDFFFF', '#ABFA97FF'], + legend: { + top: 0, + data: ['最高水温', '平均水温', '最低水温'], + textStyle: { + color: '#fff' + } + }, grid: { - top: 50, - left: 50, - right: 50, - bottom: 40 + left: '4%', + right: '5%', + bottom: '3%', + containLabel: true }, xAxis: { type: 'category', @@ -65,6 +76,8 @@ yAxis: { type: 'value', name: unit, + max: 40, + min: 0, nameTextStyle: { color: '#fff', fontSize: '1rem' @@ -76,36 +89,75 @@ }, series: [ { - data: sdata, + name: '最高水温', + data: Hdata, type: 'line', - areaStyle: {}, - } - ], - visualMap: [ + areaStyle: { + opacity: 0.8, + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgb(212,179,227)' + }, + { + offset: 1, + color: 'rgba(212,179,227,0)' + } + ]) + }, + }, { - type: 'piecewise', - show: false, - dimension: 1, - seriesIndex: 0, - pieces: [ - {max: minData, color: 'red'}, - { min: maxData, color: 'red'} - ], - outOfRange: { // 在选中范围外 的视觉元素,这里设置在正常范围内的图形颜色 - color: '#8EE5FA' - } + name: '平均水温', + data: Adata, + type: 'line', + areaStyle: { + opacity: 0.8, + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgb(0, 221, 255)' + }, + { + offset: 1, + color: 'rgba(0,221,255,0)' + } + ]) + }, + }, + { + name: '最低水温', + data: Ldata, + type: 'line', + areaStyle: { + opacity: 0.8, + color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + { + offset: 0, + color: 'rgb(171,250,151)' + }, + { + offset: 1, + color: 'rgba(171,250,151,0)' + } + ]) + }, } - ], + ] } } +// 选择时间类型 +const changeType = (type) => { + timeType.value = type; + showTime.value = '' +} // 初始化图表 const initCharts = () => { - data.forEach((item, index) => { - if(chartsRef.value[index]) { + chartData.value.forEach((item, index) => { + if (chartsRef.value[index]) { charts[index] = echarts.init(chartsRef.value[index]) - const option = getChartsOptions(item, '℃', 35) + const option = getChartsOptions(item, '℃') charts[index].setOption(option) } }) @@ -118,23 +170,77 @@ // 一键导出 const handleExport = () => { - chartsRef.value?.forEach(item => { - html2canvas(item, { - scale: 2, // 提高渲染质量 - useCORS: true, // 如果需要跨域资源 - allowTaint: true, // 如果需要处理跨域图片 - backgroundColor: 'rgba(23, 108, 229, 0.3)' //背景色 - }).then(canvas => { - const link = document.createElement("a"); - link.href = canvas.toDataURL("image/png"); - link.download = '截图.png'; - link.click() - }) + charts?.forEach((chart, index) => { + const imgData = chart.getDataURL({ + type: 'png', // 也可以是 'jpeg' + pixelRatio: 2, // 提高导出图片的分辨率 + backgroundColor: 'rgba(23, 108, 229, 0.3)' + }); + + // 创建下载链接 + const link = document.createElement('a'); + link.href = imgData; + link.download = `chart_${index + 1}.png`; + link.click(); + }) +} + +// 获取时间 +const getTime = (value) => { + const momentValue = moment(value) + const time = momentValue.format('YYYY-MM-DD') + let data = '' + switch (timeType.value) { + case 1: + data = '' + break; + case 2: + data = momentValue.add(1, 'week').format('YYYY-MM-DD') + break; + case 3: + data = momentValue.add(1, 'month').format('YYYY-MM-DD') + break; + case 4: + data = momentValue.add(1, 'quarter').format('YYYY-MM-DD') + break; + case 5: + data = momentValue.add(1, 'year').format('YYYY-MM-DD') + break; + default: + break; + } + if(data) { + timeValue.value = time + '~' + data + } else { + timeValue.value = time + } +} + +// 获取水温监控点菜单 +const getTempMonitor = () => { + getTemperaturePointList().then(res => { + menuList.value = res.data + }) +} + +// 获取报表数据 +const getChartData = (point = '') => { + const data = { + type: timeType.value, + pointId: point, + pointName: searchVal.value, + dataTime: timeValue.value, + } + getGraphicData(data).then(async res => { + chartData.value = res.data + await nextTick() + initCharts() }) } onMounted(() => { - initCharts() + getTempMonitor() + getChartData() }) </script> @@ -143,66 +249,99 @@ <div class="graphic"> <div class="graphic-menu"> <div class="menu-t">监测点列表</div> - <el-menu class="el-menu"> - <el-sub-menu index="1"> - <template #title> - <span>可移动监测点</span> + <el-menu class="el-menu" @select="getChartData"> + <template v-for="(item, index) in menuList" :key="index+1"> + <template v-if="item?.childrenList?.length === 0"> + <el-menu-item :index="item.id">{{ item.pointName }}</el-menu-item> </template> - <el-menu-item index="1-1">水电站流量监测点</el-menu-item> - </el-sub-menu> - <el-sub-menu index="2"> - <template #title> - <span>固定位监测点</span> + <template v-else> + <el-sub-menu :index="item.id"> + <template #title> + <span>{{ item.pointName }}</span> + </template> + <el-menu-item v-for="(child, cidx) in item.childrenList" :key="cidx" :index="child.id"> + {{ child.pointName }} + </el-menu-item> + </el-sub-menu> </template> - <el-menu-item index="2-1">新扎口流量监测点</el-menu-item> - </el-sub-menu> + </template> </el-menu> </div> <div class="graphic-info"> <div class="graphic-tool"> <div class="tool-l"> - <div class="name">开始时间</div> + <div class="name">类型</div> + <el-button-group class="ml-4"> + <el-button :type="timeType === 1 ? 'primary' : ''" @click="changeType(1)">日 + </el-button> + <el-button :type="timeType === 2 ? 'primary' : ''" @click="changeType(2)">周 + </el-button> + <el-button :type="timeType === 3 ? 'primary' : ''" @click="changeType(3)">月 + </el-button> + <el-button :type="timeType === 4 ? 'primary' : ''" @click="changeType(4)">季 + </el-button> + <el-button :type="timeType === 5 ? 'primary' : ''" @click="changeType(5)">年 + </el-button> + </el-button-group> <el-date-picker - v-model="startTime" - type="datetime" - style="width: 12rem" - placeholder="请选择开始时间" + v-if="timeType === 1" + v-model="showTime" + type="date" + placeholder="选择时间" + style="width: 15rem" + @change="getTime" /> - <div class="name">结束时间</div> <el-date-picker - v-model="endTime" - type="datetime" - style="width: 12rem" - placeholder="请选择结束时间" + v-if="timeType === 2" + v-model="showTime" + type="week" + format="YYYY年 ww[周]" + placeholder="选择时间" + style="width: 15rem" + @change="getTime" /> - <div class="name">监测点区域</div> - <el-select - v-model="selectType" - class="tool-select" - placeholder="Select" - style="width: 10rem" - > - <el-option - v-for="item in typeOption" - :key="item.value" - :label="item.label" - :value="item.value" - /> - </el-select> - <el-input v-model="searchVal" style="width: 15rem" placeholder="请输入监测点名称" /> - <el-button><el-icon><Search /></el-icon>搜索</el-button> + <el-date-picker + v-if="timeType === 3" + v-model="showTime" + type="month" + placeholder="选择时间" + style="width: 15rem" + @change="getTime" + /> + <Quarter + v-if="timeType === 4" + placeholder="选择时间" + :default-value="showTime" + clearable + style="width: 15rem" + @change="getTime" + /> + <el-date-picker + v-if="timeType === 5" + v-model="showTime" + type="year" + placeholder="选择时间" + style="width: 15rem" + @change="getTime" + /> + <el-input v-model="searchVal" style="width: 15rem" clearable placeholder="请输入监测点名称"/> + <el-button @click="() => getChartData()"> + <el-icon> + <Search/> + </el-icon> + 搜索 + </el-button> <el-button type="success" @click="handleExport">一键导出</el-button> </div> <div class="tool-r" @click="handleFullScreen"> - <img src="@/assets/images/flow/fullscreen.png" /> + <img src="@/assets/images/flow/fullscreen.png"/> 全屏 </div> </div> <div class="graphic-box" ref="graphicRef"> <div class="chartList"> - <div class="chartItem" v-for="(item, index) in data"> + <div class="chartItem" v-for="(item, index) in chartData"> <div class="charts" :ref="el => setChartsRef(el, index)"></div> - <div class="name">标题</div> </div> </div> </div> @@ -214,6 +353,7 @@ .graphic { height: 100%; display: flex; + &-menu { flex-shrink: 0; width: 20%; @@ -253,11 +393,12 @@ } } } + .graphic-info { flex-shrink: 0; width: 80%; height: 100%; - background: linear-gradient(180deg, #91BDDB 0%, rgba(102, 102, 102, 0.5) 100%); + .graphic-tool { width: 100%; height: 60px; @@ -287,28 +428,27 @@ } } } - .graphic-box{ + + .graphic-box { height: calc(100% - 60px); padding: 10px 30px; - .chartList{ + background: linear-gradient(180deg, #91BDDB 0%, rgba(102, 102, 102, 0.5) 100%); + + .chartList { height: 100%; display: flex; flex-wrap: wrap; gap: 20px; - .chartItem{ - width: 32%; - height: 48%; - background: rgba(23,108,229,0.3); + + .chartItem { + width: 100%; + min-height: 48%; + background: rgba(23, 108, 229, 0.3); border: 1px solid #176CE5; border-radius: 8px; - .charts{ - height: 90%; - } - .name{ - height: 10%; - text-align: center; - font-size: 20px; - color: #fff; + + .charts { + height: 100%; } } } -- Gitblit v1.9.3