237 lines
6.6 KiB
Vue
237 lines
6.6 KiB
Vue
|
|
<!-- NEW_FILE_CODE -->
|
|||
|
|
<template>
|
|||
|
|
<SidePanelItem title="月平均水温历史对比">
|
|||
|
|
<div>
|
|||
|
|
<div class="water-temp-compare-chart" ref="chartRef"></div>
|
|||
|
|
</div>
|
|||
|
|
<!-- <div v-else>
|
|||
|
|
<a-empty />
|
|||
|
|
</div> -->
|
|||
|
|
</SidePanelItem>
|
|||
|
|
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script setup lang="ts">
|
|||
|
|
import { ref, onMounted, onBeforeUnmount } from 'vue'
|
|||
|
|
import * as echarts from 'echarts'
|
|||
|
|
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
|||
|
|
defineOptions({
|
|||
|
|
name: 'monthlyAvgWaterTemCompareHistory'
|
|||
|
|
});
|
|||
|
|
const chartRef = ref<HTMLElement | null>(null)
|
|||
|
|
let chartInstance: echarts.ECharts | null = null
|
|||
|
|
|
|||
|
|
const unit = '°C'
|
|||
|
|
|
|||
|
|
const initChart = () => {
|
|||
|
|
if (!chartRef.value) return
|
|||
|
|
|
|||
|
|
chartInstance = echarts.init(chartRef.value)
|
|||
|
|
|
|||
|
|
const legendData = ['实测值', '去年同期', '天然']
|
|||
|
|
|
|||
|
|
// x轴数据 - 保持与原始配置一致的结构 { value, stnm }
|
|||
|
|
const xData = [
|
|||
|
|
{ value: '两河口', stnm: '两河口' },
|
|||
|
|
{ value: '锦屏一级', stnm: '锦屏一级' },
|
|||
|
|
{ value: '桐子林', stnm: '桐子林' }
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
// 根据图片数据提取的静态数据
|
|||
|
|
const actualData = [9, 11.5, 14] // 实测值(蓝色线)
|
|||
|
|
const lastData = [8.8, 10.5, 13.2] // 去年同期(紫色线)
|
|||
|
|
const naturalData = [9.2, 12, 15.5] // 天然(绿色线)
|
|||
|
|
|
|||
|
|
// 计算Y轴范围:最小值向下取整,最大值向上取整
|
|||
|
|
const allData = [...actualData, ...lastData, ...naturalData].filter(val => val !== null && val !== undefined)
|
|||
|
|
const dataMin = Math.min(...allData)
|
|||
|
|
const dataMax = Math.max(...allData)
|
|||
|
|
const yAxisMin = Math.floor(dataMin)
|
|||
|
|
const yAxisMax = Math.ceil(dataMax)
|
|||
|
|
|
|||
|
|
// 完全按照原始React代码中的options配置
|
|||
|
|
const options: any = {
|
|||
|
|
noShowToolbox: true,
|
|||
|
|
yAxisSplit: 5,
|
|||
|
|
xData,
|
|||
|
|
dataZoom: [
|
|||
|
|
{
|
|||
|
|
type: 'inside',
|
|||
|
|
show: false
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
type: 'slider',
|
|||
|
|
show: false
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
tooltip: {
|
|||
|
|
show: true,
|
|||
|
|
trigger: 'axis',
|
|||
|
|
confine: true,
|
|||
|
|
formatter: (params: any) => {
|
|||
|
|
const label = xData.filter((item: any) => item.value === params[0].axisValueLabel)?.[0]?.stnm
|
|||
|
|
let elm = ``
|
|||
|
|
for (const item of params) {
|
|||
|
|
elm += `
|
|||
|
|
<div>
|
|||
|
|
${item.marker}
|
|||
|
|
<span>${item.seriesName}:</span>
|
|||
|
|
<span>${item.value === null || item.value === undefined ? '-' : item.value}${unit}</span>
|
|||
|
|
</div>
|
|||
|
|
`
|
|||
|
|
}
|
|||
|
|
return `<div>${label}</div>` + elm
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
legend: {
|
|||
|
|
data: legendData
|
|||
|
|
},
|
|||
|
|
grid: {
|
|||
|
|
top: 30,
|
|||
|
|
bottom: 50,
|
|||
|
|
right: 15,
|
|||
|
|
left: 30
|
|||
|
|
},
|
|||
|
|
xAxis: {
|
|||
|
|
axisPointer: {
|
|||
|
|
type: 'shadow',
|
|||
|
|
lineStyle: {
|
|||
|
|
color: '#007aff1a',
|
|||
|
|
width: 1,
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
axisLine: {
|
|||
|
|
show: true,
|
|||
|
|
lineStyle: {
|
|||
|
|
color: '#8f8f8f'
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
axisTick: {
|
|||
|
|
show: false
|
|||
|
|
},
|
|||
|
|
axisLabel: {
|
|||
|
|
color: '#000000',
|
|||
|
|
fontSize: 12,
|
|||
|
|
interval: xData.length < 5 ? 0 : 2,
|
|||
|
|
rotate: 0,
|
|||
|
|
formatter: (value: any) => {
|
|||
|
|
const label = xData.filter((item: any) => item.value === value)?.[0]?.stnm
|
|||
|
|
return `{a|${label.substring(0, 6)}}` + (label.length > 6 ? '...\n{b|}' : '\n{b|}')
|
|||
|
|
},
|
|||
|
|
rich: {
|
|||
|
|
a: {
|
|||
|
|
height: 30,
|
|||
|
|
align: 'center'
|
|||
|
|
},
|
|||
|
|
b: {
|
|||
|
|
height: 30,
|
|||
|
|
align: 'center'
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
data: xData,
|
|||
|
|
splitLine: {
|
|||
|
|
show: false
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
yAxis: [
|
|||
|
|
{
|
|||
|
|
type: 'value',
|
|||
|
|
name: `水温(${unit})`,
|
|||
|
|
min: yAxisMin,
|
|||
|
|
max: yAxisMax,
|
|||
|
|
nameTextStyle: {
|
|||
|
|
fontSize: 12,
|
|||
|
|
color: '#000000'
|
|||
|
|
},
|
|||
|
|
lineStyle: {
|
|||
|
|
color: '#6ca4f7',
|
|||
|
|
width: 2
|
|||
|
|
},
|
|||
|
|
axisLine: {
|
|||
|
|
show: true,
|
|||
|
|
lineStyle: {
|
|||
|
|
color: '#bfbfbf'
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
axisTick: {
|
|||
|
|
show: true,
|
|||
|
|
length: 3,
|
|||
|
|
lineStyle: {
|
|||
|
|
color: '#8f8f8f'
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
axisLabel: {
|
|||
|
|
color: '#333',
|
|||
|
|
fontSize: 12
|
|||
|
|
},
|
|||
|
|
splitLine: {
|
|||
|
|
show: true,
|
|||
|
|
lineStyle: {
|
|||
|
|
color: '#bfbfbf',
|
|||
|
|
type: 'solid'
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
series: [
|
|||
|
|
{
|
|||
|
|
name: legendData[0],
|
|||
|
|
data: actualData,
|
|||
|
|
type: 'line',
|
|||
|
|
connectNulls: true,
|
|||
|
|
smooth: true
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: legendData[1],
|
|||
|
|
data: lastData,
|
|||
|
|
type: 'line',
|
|||
|
|
connectNulls: true,
|
|||
|
|
smooth: true
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
name: legendData[2],
|
|||
|
|
data: naturalData,
|
|||
|
|
type: 'line',
|
|||
|
|
connectNulls: true,
|
|||
|
|
smooth: true
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 颜色配置 - 对应 getColorByCodeAndType(['Other'], ['ACTUALTEMP', 'LASTTEMP', 'NATURALTEMP'])
|
|||
|
|
// 根据图片:实测值(蓝)、去年同期(紫)、天然(绿)
|
|||
|
|
options.color = ['#5470c6', '#9b59b6', '#91cc75']
|
|||
|
|
|
|||
|
|
chartInstance.setOption(options)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
onMounted(() => {
|
|||
|
|
// 延迟初始化,确保容器尺寸已就绪
|
|||
|
|
setTimeout(() => {
|
|||
|
|
initChart()
|
|||
|
|
// 初始化完成后再次调用 resize 确保尺寸正确
|
|||
|
|
chartInstance?.resize()
|
|||
|
|
}, 100)
|
|||
|
|
|
|||
|
|
window.addEventListener('resize', () => {
|
|||
|
|
chartInstance?.resize()
|
|||
|
|
})
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
onBeforeUnmount(() => {
|
|||
|
|
chartInstance?.dispose()
|
|||
|
|
window.removeEventListener('resize', () => {
|
|||
|
|
chartInstance?.resize()
|
|||
|
|
})
|
|||
|
|
})
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style scoped>
|
|||
|
|
.water-temp-compare-chart {
|
|||
|
|
width: 100%;
|
|||
|
|
height: 100%;
|
|||
|
|
height: 260px;
|
|||
|
|
}
|
|||
|
|
</style>
|