<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: {},
|
}
|
],
|
visualMap: [
|
{
|
type: 'piecewise',
|
show: false,
|
dimension: 1,
|
seriesIndex: 0,
|
pieces: [
|
{max: minData, color: 'red'},
|
{ min: maxData, 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>
|
|
<template>
|
<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>
|
</template>
|
<el-menu-item index="1-1">水电站流量监测点</el-menu-item>
|
</el-sub-menu>
|
<el-sub-menu index="2">
|
<template #title>
|
<span>固定位监测点</span>
|
</template>
|
<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>
|
|
<style scoped lang="scss">
|
.graphic {
|
height: 100%;
|
display: flex;
|
&-menu {
|
flex-shrink: 0;
|
width: 20%;
|
height: 100%;
|
padding: 10px 0;
|
background: linear-gradient(135deg, #91BDDB 0%, #9EC2DB 99%);
|
overflow-y: scroll;
|
|
&::-webkit-scrollbar {
|
display: none;
|
}
|
|
.menu-t {
|
height: 40px;
|
line-height: 40px;
|
padding-left: 20px;
|
font-size: 26px;
|
color: #fff;
|
background: url("@/assets/images/flow/monitor-title-bg.png") no-repeat;
|
background-size: 100% 100%;
|
}
|
|
.el-menu {
|
background-color: transparent;
|
border-right: none;
|
|
:deep(.el-menu) {
|
background-color: transparent;
|
}
|
|
:deep(.el-sub-menu__title:hover) {
|
background-color: rgba(0, 0, 0, 0.06);
|
}
|
|
:deep(.el-menu-item.is-active) {
|
color: #fff;
|
}
|
}
|
}
|
.graphic-info {
|
flex-shrink: 0;
|
width: 80%;
|
height: 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;
|
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);
|
border: 1px solid #176CE5;
|
border-radius: 8px;
|
.charts{
|
height: 90%;
|
}
|
.name{
|
height: 10%;
|
text-align: center;
|
font-size: 20px;
|
color: #fff;
|
}
|
}
|
}
|
}
|
}
|
}
|
</style>
|