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