web
2025-03-22 524451ef93534fdfc7084501ddd4a1d649859783
feat: 添加图形分析,汇总统计功能
已修改5个文件
已添加1个文件
379 ■■■■ 文件已修改
jsconfig.json 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Pagination/index.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/temperature/graphic/index.vue 268 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/temperature/monitor/index.vue 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/screen/temperature/report/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jsconfig.json
对比新文件
@@ -0,0 +1,8 @@
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}
src/components/Pagination/index.vue
@@ -20,7 +20,8 @@
const props = defineProps({
  total: {
    required: true,
    type: Number
      type: Number,
      default: 0
  },
  page: {
    type: Number,
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'
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>
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>
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,
            },
        }
        resolve(arr)
    })