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

249 lines
6.6 KiB
Vue
Raw Normal View History

<template>
<SidePanelItem title="水温年内分布">
<div class="water-temp-chart-container">
<div ref="chartRef" class="chart-wrapper"></div>
</div>
<!-- <div v-else>
<a-empty />
</div> -->
</SidePanelItem>
</template>
<script setup lang="ts">
2026-04-22 17:53:20 +08:00
import { ref, onMounted, onBeforeUnmount } from 'vue'
import * as echarts from 'echarts'
import SidePanelItem from '@/components/SidePanelItem/index.vue';
const data = [
{ monthInt: 1, actualTemp: 0.9, naturalTemp: 0 },
{ monthInt: 2, actualTemp: 0.9, naturalTemp: 0.1 },
{ monthInt: 3, actualTemp: 1.0, naturalTemp: 2.0 }
]
const chartRef = ref<HTMLElement | null>(null)
let chartInstance: echarts.ECharts | null = null
2026-04-22 17:53:20 +08:00
const transUnit = (value: number | null) => {
if (value === null) return null
return value
}
2026-04-22 17:53:20 +08:00
const getUnitConfigByCode = (_code: string, _type: string) => {
return {
unit: '℃'
}
}
2026-04-22 17:53:20 +08:00
const getColorByCodeAndType = (_code: string[], _typeKey: string[]) => {
return ['#4b79ab', '#78c300']
}
const getChartOption = () => {
const { unit } = getUnitConfigByCode('Other', 'ACTUALTEMP')
const legendData = ['实测值', '天然']
const xData: string[] = []
const actualData: (number | null)[] = []
const naturalData: (number | null)[] = []
data.forEach((item: any) => {
xData.push(`${item.monthInt}`)
2026-04-22 17:53:20 +08:00
actualData.push(item.actualTemp === null ? null : transUnit(item.actualTemp))
naturalData.push(item.naturalTemp === null ? null : transUnit(item.naturalTemp))
})
const code = ['Other']
const typeKey = ['ACTUALTEMP', 'NATURALTEMP']
const colors = getColorByCodeAndType(code, typeKey)
const options: any = {
color: colors,
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(51, 51, 51, 0.9)',
borderColor: 'transparent',
textStyle: {
color: '#ffffff',
fontSize: 14
},
2026-04-22 17:53:20 +08:00
formatter: function(params: any) {
if (!params || params.length === 0) return '';
let result = `<div style="font-weight: bold; margin-bottom: 8px;">${params[0].axisValue}</div>`;
2026-04-22 17:53:20 +08:00
params.forEach((item: any) => {
result += `<div style="display: flex; align-items: center; margin: 4px 0;">`;
result += `<span style="display: inline-block; width: 10px; height: 10px; border-radius: 50%; background-color: ${item.color}; margin-right: 8px;"></span>`;
result += `<span>${item.seriesName} ${item.value}${unit}</span>`;
result += `</div>`;
});
return result;
}
},
xAxis: {
type: 'category',
boundaryGap: true,
axisPointer: {
type: 'shadow',
shadowStyle: {
color: '#007aff1a'
}
},
axisLine: {
show: true,
lineStyle: {
color: '#8f8f8f'
}
},
axisTick: {
show: false
},
splitLine: {
show: true,
lineStyle: {
color: '#bfbfbf',
type: 'solid'
}
},
axisLabel: {
interval: 0,
color: '#000000',
fontSize: 12,
rotate: 0,
margin: 8,
align: 'center'
},
data: xData
},
yAxis: [
{
name: '水温(℃)',
type: 'value',
splitNumber: 5,
nameTextStyle: {
fontSize: 12,
color: '#000000'
},
lineStyle: {
color: '#6ca4f7',
width: 2
},
axisLine: {
show: true,
lineStyle: {
color: '#000000'
}
},
axisTick: {
show: true,
length: 3,
lineStyle: {
color: '#000000'
}
},
axisLabel: {
color: '#333',
fontSize: 12
},
splitLine: {
show: true,
lineStyle: {
color: '#bfbfbf',
type: 'solid'
}
}
}
],
legend: {
data: legendData
},
grid: {
top: 30,
bottom: 50,
right: 15,
left: 30
},
series: [
{
name: legendData[0],
data: actualData,
connectNulls: true,
smooth: true,
type: 'line',
itemStyle: {
color: colors[0]
}
},
{
name: legendData[1],
data: naturalData,
connectNulls: true,
smooth: true,
type: 'line',
itemStyle: {
color: colors[1]
}
}
]
}
return options
}
const initChart = async () => {
// 延迟初始化,确保容器已完成渲染
await new Promise(resolve => setTimeout(resolve, 100))
if (!chartRef.value) {
console.error('图表容器未找到')
return
}
try {
if (!chartInstance) {
chartInstance = echarts.init(chartRef.value)
}
const option = getChartOption()
chartInstance.setOption(option, false)
// 强制重绘,确保图表尺寸正确
setTimeout(() => {
chartInstance?.resize()
}, 100)
window.addEventListener('resize', handleResize)
} catch (error) {
console.error('图表初始化失败:', error)
}
}
const handleResize = () => {
if (chartInstance) {
chartInstance.resize()
}
}
onMounted(() => {
initChart()
})
onBeforeUnmount(() => {
window.removeEventListener('resize', handleResize)
if (chartInstance) {
chartInstance.dispose()
chartInstance = null
}
})
</script>
<style scoped>
.water-temp-chart-container {
width: 100%;
height: 100%;
min-height: 290px;
}
.chart-wrapper {
width: 100%;
height: 100%;
min-height: 290px;
}
</style>