From 524451ef93534fdfc7084501ddd4a1d649859783 Mon Sep 17 00:00:00 2001 From: web <candymxq888@outlook.com> Date: 星期六, 22 三月 2025 17:25:03 +0800 Subject: [PATCH] feat: 添加图形分析,汇总统计功能 --- src/main.js | 4 jsconfig.json | 8 + src/views/screen/temperature/monitor/index.vue | 92 +++++++----- src/views/screen/temperature/report/index.vue | 4 src/views/screen/temperature/graphic/index.vue | 268 ++++++++++++++++++++++++++++++++++++++ src/components/Pagination/index.vue | 5 6 files changed, 334 insertions(+), 47 deletions(-) diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..2c8ee2b --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["src/*"] + } + } +} diff --git a/src/components/Pagination/index.vue b/src/components/Pagination/index.vue index 03fa929..72038a1 100644 --- a/src/components/Pagination/index.vue +++ b/src/components/Pagination/index.vue @@ -19,8 +19,9 @@ const props = defineProps({ total: { - required: true, - type: Number + required: true, + type: Number, + default: 0 }, page: { type: Number, diff --git a/src/main.js b/src/main.js index 8786be8..5c07bd6 100644 --- a/src/main.js +++ b/src/main.js @@ -36,12 +36,12 @@ // 按需引入echarts import * as echarts from 'echarts/core'; -import { GridComponent, ToolboxComponent, TooltipComponent, TitleComponent } from 'echarts/components'; +import { GridComponent, ToolboxComponent, TooltipComponent, TitleComponent, VisualMapComponent, } from 'echarts/components'; import { LineChart, BarChart } from 'echarts/charts'; import { UniversalTransition } from 'echarts/features'; import { CanvasRenderer } from 'echarts/renderers'; -echarts.use([GridComponent, LineChart, BarChart, CanvasRenderer, UniversalTransition, ToolboxComponent, TooltipComponent, TitleComponent]); +echarts.use([GridComponent, LineChart, BarChart, CanvasRenderer, UniversalTransition, ToolboxComponent, TooltipComponent, TitleComponent, VisualMapComponent,]); // 分页组件 import Pagination from '@/components/Pagination' diff --git a/src/views/screen/temperature/graphic/index.vue b/src/views/screen/temperature/graphic/index.vue index fa5c4cb..13c8dad 100644 --- a/src/views/screen/temperature/graphic/index.vue +++ b/src/views/screen/temperature/graphic/index.vue @@ -1,4 +1,162 @@ <script setup> +import {ref, reactive, onMounted} from "vue"; +import * as echarts from 'echarts/core'; +import html2canvas from "html2canvas"; + +const startTime = ref() +const endTime = ref() +const searchVal = ref() +const selectType = ref(1); +const typeOption = ref([ + { label: '水电站流量监测点', value: 1 }, + { label: '新扎口流量监测点', value: 2 }, +]) +const graphicRef = ref(null) +const chartsRef = ref([]) //动态生成图表ref +let charts = [] + +// 动态设置ref +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) => { + let xdata = []; + let sdata = []; + if(data) { + data.forEach(item => { + xdata.push(item.name) + sdata.push(item.value); + }) + } + return { + tooltip: { + trigger: 'axis', + }, + grid: { + top: 50, + left: 50, + right: 50, + bottom: 40 + }, + xAxis: { + type: 'category', + boundaryGap: false, + data: xdata, + axisLabel: { + color: '#fff', + fontSize: '1rem' + } + }, + yAxis: { + type: 'value', + name: unit, + nameTextStyle: { + color: '#fff', + fontSize: '1rem' + }, + axisLabel: { + color: '#fff', + fontSize: '1rem' + } + }, + series: [ + { + data: sdata, + type: 'line', + areaStyle: {}, + markLine: { + symbol: 'none', + label: { + show: false + }, + data: [ + { + yAxis: maxData + }, + { + yAxis: minData + } + ] + }, + } + ], + visualMap: [ + { + type: 'piecewise', + show: false, + dimension: 1, + seriesIndex: 0, + pieces: [ + { + // 不指定 min,表示 min 为无限大(-Infinity)。 + max: minData, // 没有设置最小值,表明当前范围 [-Infinity, max] 变色 + color: 'red' + }, + { + // 不指定 max,表示 max 为无限大(Infinity)。 + min: maxData, // 没有设置最大值,表明当前范围 [min, Infinity] 变色 + color: 'red' + } + ], + outOfRange: { // 在选中范围外 的视觉元素,这里设置在正常范围内的图形颜色 + color: '#8EE5FA' + } + } + ], + } +} + + +// 初始化图表 +const initCharts = () => { + data.forEach((item, index) => { + if(chartsRef.value[index]) { + charts[index] = echarts.init(chartsRef.value[index]) + const option = getChartsOptions(item, '℃', 35) + charts[index].setOption(option) + } + }) +} + +// 全屏操作 +const handleFullScreen = () => { + graphicRef.value.requestFullscreen() +} + +// 一键导出 +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() + }) + }) +} + +onMounted(() => { + initCharts() +}) </script> @@ -20,6 +178,55 @@ <el-menu-item index="2-1">新扎口流量监测点</el-menu-item> </el-sub-menu> </el-menu> + </div> + <div class="graphic-info"> + <div class="graphic-tool"> + <div class="tool-l"> + <div class="name">开始时间</div> + <el-date-picker + v-model="startTime" + type="datetime" + style="width: 12rem" + placeholder="请选择开始时间" + /> + <div class="name">结束时间</div> + <el-date-picker + v-model="endTime" + type="datetime" + style="width: 12rem" + placeholder="请选择结束时间" + /> + <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-button type="success" @click="handleExport">一键导出</el-button> + </div> + <div class="tool-r" @click="handleFullScreen"> + <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="charts" :ref="el => setChartsRef(el, index)"></div> + <div class="name">标题</div> + </div> + </div> + </div> </div> </div> </template> @@ -67,5 +274,66 @@ } } } + .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; + padding: 0 30px; + background: linear-gradient(90deg, #91BDDB 0%, #DADFE3 100%); + display: flex; + align-items: center; + justify-content: space-between; + + .tool-l { + display: flex; + align-items: center; + gap: 1rem; + + .name { + font-size: 1.1rem; + } + } + + .tool-r { + display: flex; + align-items: center; + + img { + width: 25px; + margin-right: 10px; + } + } + } + .graphic-box{ + height: calc(100% - 60px); + padding: 10px 30px; + .chartList{ + height: 100%; + display: flex; + flex-wrap: wrap; + gap: 20px; + .chartItem{ + width: 32%; + 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; + } + } + } + } + } } </style> \ No newline at end of file diff --git a/src/views/screen/temperature/monitor/index.vue b/src/views/screen/temperature/monitor/index.vue index 5ac61ee..d13c74a 100644 --- a/src/views/screen/temperature/monitor/index.vue +++ b/src/views/screen/temperature/monitor/index.vue @@ -1,6 +1,7 @@ <script setup> import {ref} from "vue"; import {getUserType} from '@/utils/auth.js' + const userType = ref(getUserType()) const monitorRef = ref() const searchVal = ref('') @@ -9,7 +10,16 @@ { label: '水电站流量监测点', value: 1 }, { label: '新扎口流量监测点', value: 2 }, ]) - const video = ref() + const setData = reactive({ + licheng: '', + toufang: '', + gaocheng: '', + shuiwei: '', + shuiwen: '', + shuiweiji: '', + jilu: '', + shuju: '' + }) // 全屏操作 const handleFullScreen = () => { @@ -84,49 +94,49 @@ <div class="item-set"> <div class="setbox"> <div class="name">里程设置:</div> - <el-input /> + <el-input v-model="setData.licheng" /> </div> <div class="setbox"> <div class="name">投放度设置:</div> - <el-input /> + <el-input v-model="setData.toufang" /> </div> <div class="setbox"> <div class="name">高程设置:</div> - <el-input /> + <el-input v-model="setData.gaocheng" /> </div> <div class="setbox"> <div class="name">水位下限设置:</div> - <el-input /> + <el-input v-model="setData.shuiwei" /> </div> <div class="setbox"> <div class="name">水温下限设置:</div> - <el-input /> + <el-input v-model="setData.shuiwen" /> </div> <div class="setbox"> <div class="name">水位计采集间隔设置:</div> - <el-select> - <el-option>60s</el-option> - <el-option>120s</el-option> - <el-option>300s</el-option> - <el-option>600s</el-option> + <el-select v-model="setData.shuiweiji"> + <el-option value="60">60s</el-option> + <el-option value="120">120s</el-option> + <el-option value="300">300s</el-option> + <el-option value="600">600s</el-option> </el-select> </div> <div class="setbox"> <div class="name">记录上报间隔设置:</div> - <el-select> - <el-option>60s</el-option> - <el-option>120s</el-option> - <el-option>300s</el-option> - <el-option>600s</el-option> + <el-select v-model="setData.jilu"> + <el-option value="60">60s</el-option> + <el-option value="120">120s</el-option> + <el-option value="300">300s</el-option> + <el-option value="600">600s</el-option> </el-select> </div> <div class="setbox"> <div class="name">实时数据上报间隔设置:</div> - <el-select> - <el-option>60s</el-option> - <el-option>120s</el-option> - <el-option>300s</el-option> - <el-option>600s</el-option> + <el-select v-model="setData.shuju"> + <el-option value="60">60s</el-option> + <el-option value="120">120s</el-option> + <el-option value="300">300s</el-option> + <el-option value="600">600s</el-option> </el-select> </div> </div> @@ -151,49 +161,49 @@ <div class="item-set"> <div class="setbox"> <div class="name">里程设置:</div> - <el-input /> + <el-input v-model="setData.licheng" /> </div> <div class="setbox"> <div class="name">投放度设置:</div> - <el-input /> + <el-input v-model="setData.toufang" /> </div> <div class="setbox"> <div class="name">高程设置:</div> - <el-input /> + <el-input v-model="setData.gaocheng" /> </div> <div class="setbox"> <div class="name">水位下限设置:</div> - <el-input /> + <el-input v-model="setData.shuiwei" /> </div> <div class="setbox"> <div class="name">水温下限设置:</div> - <el-input /> + <el-input v-model="setData.shuiwen" /> </div> <div class="setbox"> <div class="name">水位计采集间隔设置:</div> - <el-select> - <el-option>60s</el-option> - <el-option>120s</el-option> - <el-option>300s</el-option> - <el-option>600s</el-option> + <el-select v-model="setData.shuiweiji"> + <el-option value="60">60s</el-option> + <el-option value="120">120s</el-option> + <el-option value="300">300s</el-option> + <el-option value="600">600s</el-option> </el-select> </div> <div class="setbox"> <div class="name">记录上报间隔设置:</div> - <el-select> - <el-option>60s</el-option> - <el-option>120s</el-option> - <el-option>300s</el-option> - <el-option>600s</el-option> + <el-select v-model="setData.jilu"> + <el-option value="60">60s</el-option> + <el-option value="120">120s</el-option> + <el-option value="300">300s</el-option> + <el-option value="600">600s</el-option> </el-select> </div> <div class="setbox"> <div class="name">实时数据上报间隔设置:</div> - <el-select> - <el-option>60s</el-option> - <el-option>120s</el-option> - <el-option>300s</el-option> - <el-option>600s</el-option> + <el-select v-model="setData.shuju"> + <el-option value="60">60s</el-option> + <el-option value="120">120s</el-option> + <el-option value="300">300s</el-option> + <el-option value="600">600s</el-option> </el-select> </div> </div> diff --git a/src/views/screen/temperature/report/index.vue b/src/views/screen/temperature/report/index.vue index 061c394..8c58523 100644 --- a/src/views/screen/temperature/report/index.vue +++ b/src/views/screen/temperature/report/index.vue @@ -31,9 +31,9 @@ { code: '208', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 2 }, { code: '209', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 3 }, { code: '2010', shebei: '雷达水位计', content: '设备离线', time: '2025-02-08', sure: 3 }, - ] + ], + total: 30, }, - total: 30, } resolve(arr) }) -- Gitblit v1.9.3