WholeProcessPlatform/frontend/src/modules/monthlyAvgWaterTemCompareHistory/index.vue

237 lines
6.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- 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>