222 lines
4.6 KiB
Vue
222 lines
4.6 KiB
Vue
|
|
<!-- SidePanelItem.vue -->
|
|||
|
|
<template>
|
|||
|
|
<SidePanelItem title="沿程水温变化" :prompt="prompts">
|
|||
|
|
<div ref="chartRef" class="chart-container"></div>
|
|||
|
|
</SidePanelItem>
|
|||
|
|
</template>
|
|||
|
|
|
|||
|
|
<script lang="ts" setup>
|
|||
|
|
import { ref, onMounted, onBeforeUnmount } from 'vue';
|
|||
|
|
import * as echarts from 'echarts';
|
|||
|
|
import type { ECharts } from 'echarts';
|
|||
|
|
import SidePanelItem from '@/components/SidePanelItem/index.vue';
|
|||
|
|
|
|||
|
|
// 定义组件名(便于调试和递归)
|
|||
|
|
defineOptions({
|
|||
|
|
name: 'yanchengshuiwenChangeMod'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const prompts = ref({
|
|||
|
|
show: true,
|
|||
|
|
value: '注:最新数据时间为2026-04-08 23',
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const chartRef = ref<HTMLElement | null>(null);
|
|||
|
|
let chartInstance: ECharts | null = null;
|
|||
|
|
|
|||
|
|
// 静态数据 - 站点名称
|
|||
|
|
const stationNames = ref([
|
|||
|
|
'班多',
|
|||
|
|
'龙羊峡',
|
|||
|
|
'拉西瓦',
|
|||
|
|
'李家峡',
|
|||
|
|
'公伯峡',
|
|||
|
|
'苏只',
|
|||
|
|
'积石峡'
|
|||
|
|
]);
|
|||
|
|
|
|||
|
|
// 静态数据 - 水温值 (°C),班多无数据设为 null
|
|||
|
|
const waterTemperatures = ref([
|
|||
|
|
null,
|
|||
|
|
5.7,
|
|||
|
|
5.7,
|
|||
|
|
6.5,
|
|||
|
|
7.2,
|
|||
|
|
7.8,
|
|||
|
|
8.4
|
|||
|
|
]);
|
|||
|
|
|
|||
|
|
// 静态时间数据
|
|||
|
|
const currentTime = '2026-04-08 23';
|
|||
|
|
|
|||
|
|
// 初始化图表
|
|||
|
|
const initChart = () => {
|
|||
|
|
if (!chartRef.value) return;
|
|||
|
|
|
|||
|
|
chartInstance = echarts.init(chartRef.value);
|
|||
|
|
|
|||
|
|
const option = {
|
|||
|
|
title: {
|
|||
|
|
text: '水温(°C)',
|
|||
|
|
left: 5,
|
|||
|
|
top: 0,
|
|||
|
|
textStyle: {
|
|||
|
|
color: '#000000',
|
|||
|
|
fontSize: 12,
|
|||
|
|
fontWeight: 'normal',
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
tooltip: {
|
|||
|
|
trigger: 'axis',
|
|||
|
|
formatter: (params: any) => {
|
|||
|
|
if (params && params.length > 0) {
|
|||
|
|
const data = params[0];
|
|||
|
|
// 过滤掉 null 值的数据点
|
|||
|
|
if (data.value !== null && data.value !== undefined) {
|
|||
|
|
return `${currentTime}<br/>${data.name}:${data.value}°C`;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return '';
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
grid: {
|
|||
|
|
left: '3%',
|
|||
|
|
right: '4%',
|
|||
|
|
bottom: '3%',
|
|||
|
|
top: '15%',
|
|||
|
|
containLabel: true
|
|||
|
|
},
|
|||
|
|
xAxis: {
|
|||
|
|
type: 'category',
|
|||
|
|
data: stationNames.value,
|
|||
|
|
boundaryGap: true,
|
|||
|
|
axisLine: {
|
|||
|
|
show: true,
|
|||
|
|
lineStyle: {
|
|||
|
|
color: '#8f8f8f'
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
axisTick: {
|
|||
|
|
show: false
|
|||
|
|
},
|
|||
|
|
axisLabel: {
|
|||
|
|
color: '#333',
|
|||
|
|
fontSize: 12,
|
|||
|
|
margin: 8,
|
|||
|
|
interval: 0,
|
|||
|
|
formatter: (value: string, index: number) => {
|
|||
|
|
// 偶数索引(0, 2, 4, 6)的标签在上方
|
|||
|
|
// 奇数索引(1, 3, 5)的标签在下方
|
|||
|
|
// 通过添加空行实现上下错位
|
|||
|
|
if (index % 2 === 0) {
|
|||
|
|
return `${value}\n `; // 上方标签:文字 + 换行 + 空格占位
|
|||
|
|
} else {
|
|||
|
|
return ` \n${value}`; // 下方标签:空格占位 + 换行 + 文字
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
splitLine: {
|
|||
|
|
show: true,
|
|||
|
|
lineStyle: {
|
|||
|
|
color: '#e0e0e0',
|
|||
|
|
type: 'solid'
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
yAxis: {
|
|||
|
|
type: 'value',
|
|||
|
|
min: 0,
|
|||
|
|
max: 10,
|
|||
|
|
interval: 2,
|
|||
|
|
axisLine: {
|
|||
|
|
show: true,
|
|||
|
|
lineStyle: {
|
|||
|
|
color: '#8f8f8f'
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
axisTick: {
|
|||
|
|
show: true,
|
|||
|
|
length: 3,
|
|||
|
|
lineStyle: {
|
|||
|
|
color: '#8f8f8f'
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
axisLabel: {
|
|||
|
|
color: '#333',
|
|||
|
|
fontSize: 12
|
|||
|
|
},
|
|||
|
|
splitLine: {
|
|||
|
|
show: true,
|
|||
|
|
lineStyle: {
|
|||
|
|
color: '#e0e0e0',
|
|||
|
|
type: 'solid'
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
series: [
|
|||
|
|
{
|
|||
|
|
name: '水温',
|
|||
|
|
type: 'line',
|
|||
|
|
smooth: true,
|
|||
|
|
symbol: 'circle',
|
|||
|
|
symbolSize: 6,
|
|||
|
|
lineStyle: {
|
|||
|
|
color: '#6ca4f7',
|
|||
|
|
width: 2
|
|||
|
|
},
|
|||
|
|
itemStyle: {
|
|||
|
|
color: '#6ca4f7'
|
|||
|
|
},
|
|||
|
|
areaStyle: {
|
|||
|
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|||
|
|
{
|
|||
|
|
offset: 0,
|
|||
|
|
color: 'rgba(108, 164, 247, 0.3)'
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
offset: 1,
|
|||
|
|
color: 'rgba(108, 164, 247, 0.05)'
|
|||
|
|
}
|
|||
|
|
])
|
|||
|
|
},
|
|||
|
|
data: waterTemperatures.value
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
chartInstance.setOption(option);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 处理窗口大小变化
|
|||
|
|
const handleResize = () => {
|
|||
|
|
chartInstance?.resize();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 页面加载时执行的逻辑
|
|||
|
|
onMounted(() => {
|
|||
|
|
// 延迟初始化,确保 DOM 渲染完成
|
|||
|
|
setTimeout(() => {
|
|||
|
|
initChart();
|
|||
|
|
// 强制重绘,确保尺寸正确
|
|||
|
|
setTimeout(() => {
|
|||
|
|
chartInstance?.resize();
|
|||
|
|
}, 100);
|
|||
|
|
}, 50);
|
|||
|
|
|
|||
|
|
window.addEventListener('resize', handleResize);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 组件卸载前清理
|
|||
|
|
onBeforeUnmount(() => {
|
|||
|
|
window.removeEventListener('resize', handleResize);
|
|||
|
|
chartInstance?.dispose();
|
|||
|
|
});
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<style lang="scss" scoped>
|
|||
|
|
.chart-container {
|
|||
|
|
width: 100%;
|
|||
|
|
height: 252px;
|
|||
|
|
}
|
|||
|
|
</style>
|