<script setup>
|
import {ref, reactive, onMounted} 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";
|
|
|
const menuList = ref([])
|
const timeType = ref('date')
|
const timeRange = ref()
|
const searchVal = ref()
|
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 changeType = (type) => {
|
timeType.value = type;
|
timeRange.value = ''
|
}
|
|
// 初始化图表
|
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, index) => {
|
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 = `图表分析${index}.png`;
|
link.click()
|
})
|
})
|
}
|
|
// 获取水温监控点菜单
|
const getTempMonitor = () => {
|
getTemperaturePointList().then(res => {
|
menuList.value = res.data
|
})
|
}
|
|
// 获取时间
|
const getTime = (value) => {
|
const time = moment(value).format('YYYY-MM-DD')
|
console.log(time)
|
}
|
|
onMounted(() => {
|
getTempMonitor()
|
initCharts()
|
})
|
|
</script>
|
|
<template>
|
<div class="graphic">
|
<div class="graphic-menu">
|
<div class="menu-t">监测点列表</div>
|
<el-menu class="el-menu">
|
<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>
|
<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>
|
</template>
|
</el-menu>
|
</div>
|
<div class="graphic-info">
|
<div class="graphic-tool">
|
<div class="tool-l">
|
<div class="name">类型</div>
|
<el-button-group class="ml-4">
|
<el-button :type="timeType === 'date' ? 'primary' : ''" @click="changeType('date')">日</el-button>
|
<el-button :type="timeType === 'week' ? 'primary' : ''" @click="changeType('week')">周</el-button>
|
<el-button :type="timeType === 'month' ? 'primary' : ''" @click="changeType('month')">月</el-button>
|
<el-button :type="timeType === 'quarter' ? 'primary' : ''" @click="changeType('quarter')">季</el-button>
|
<el-button :type="timeType === 'year' ? 'primary' : ''" @click="changeType('year')">年</el-button>
|
</el-button-group>
|
<el-date-picker
|
v-if="timeType === 'date'"
|
v-model="timeRange"
|
type="date"
|
placeholder="选择时间"
|
style="width: 15rem"
|
@change="getTime"
|
/>
|
<el-date-picker
|
v-if="timeType === 'week'"
|
v-model="timeRange"
|
type="week"
|
format="YYYY年 ww[周]"
|
placeholder="选择时间"
|
style="width: 15rem"
|
@change="getTime"
|
/>
|
<el-date-picker
|
v-if="timeType === 'month'"
|
v-model="timeRange"
|
type="month"
|
placeholder="选择时间"
|
style="width: 15rem"
|
@change="getTime"
|
/>
|
<Quarter
|
v-if="timeType === 'quarter'"
|
placeholder="选择时间"
|
:default-value="timeRange"
|
clearable
|
style="width: 15rem"
|
@change="getTime"
|
/>
|
<el-date-picker
|
v-if="timeType === 'year'"
|
v-model="timeRange"
|
type="year"
|
placeholder="选择时间"
|
style="width: 15rem"
|
@change="getTime"
|
/>
|
<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>
|