<template>
|
<div class="water-depth-content">
|
<!-- 提示信息 -->
|
<div v-if="showSelectPrompt" style=" font-weight: bold;">
|
请在地图中选取唯一测量点
|
</div>
|
|
<!-- 正常内容 -->
|
<div v-else>
|
<!-- 位置信息 -->
|
<div class="location-info">
|
<h3>位置信息</h3>
|
<p class="coordinates">
|
经度: <strong>{{ safeCurrentInfo.longitude.toFixed(3) }} </strong>
|
纬度:<strong>{{ safeCurrentInfo.latitude.toFixed(3) }}</strong>
|
</p>
|
</div>
|
|
<!-- 水深信息 -->
|
<div class="depth-info">
|
<h3>水深信息 (m)</h3>
|
<p>
|
平均:<strong>2.45</strong>
|
最大:<strong>3.10</strong>
|
最小:<strong>1.80</strong>
|
</p>
|
</div>
|
</div>
|
<div class="chart-placeholder">
|
<div ref="chartDom" style="width: 100%; height:300px;"></div>
|
</div>
|
</div>
|
</template>
|
|
<script setup>
|
import { ref, onMounted, watch, computed, onBeforeUnmount, onBeforeMount } from 'vue';
|
import * as echarts from 'echarts';
|
import { useSimStore } from "@/store/simulation";
|
import { storeToRefs } from "pinia";
|
import { getFlowRate } from "@/api/trApi.js";
|
import { EventBus } from "@/eventBus"; // 引入事件总线
|
|
const simStore = useSimStore();
|
const { currentInfo } = storeToRefs(simStore);
|
|
// 定义图表的 DOM 元素引用
|
const chartDom = ref(null);
|
let myChart = null;
|
|
// 计算属性:安全获取经纬度
|
const safeCurrentInfo = computed(() => {
|
const info = currentInfo.value || {};
|
return {
|
longitude: info.longitude !== undefined ? info.longitude : 0.0,
|
latitude: info.latitude !== undefined ? info.latitude : 0.0
|
};
|
});
|
|
// 判断是否需要显示选择提示
|
const showSelectPrompt = computed(() => {
|
const info = safeCurrentInfo.value;
|
return info.longitude === 0.0 && info.latitude === 0.0;
|
});
|
|
// 防抖函数
|
function debounce(func, wait) {
|
let timeout;
|
return function () {
|
const context = this;
|
const args = arguments;
|
clearTimeout(timeout);
|
timeout = setTimeout(() => {
|
func.apply(context, args);
|
}, wait);
|
};
|
}
|
|
// 简化数据源
|
function generateSampleData() {
|
const now = new Date();
|
const data = [];
|
// 生成7个数据点,每10分钟一个
|
for (let i = 99; i >= 0; i--) {
|
const time = new Date(now.getTime() - i * 10 * 60 * 1000);
|
// 随机生成1.8-3.1之间的水深数据
|
const depth = (1.8 + Math.random() * 1.3).toFixed(2);
|
data.push({
|
time: time,
|
value: parseFloat(depth)
|
});
|
}
|
return data;
|
}
|
|
function initChart(chart) {
|
const data = generateSampleData();
|
|
const option = {
|
title: {
|
text: '水深变化趋势',
|
textStyle: {
|
color: '#fff',
|
fontSize: 16
|
},
|
left: '-1%' // 和组件 A 对齐
|
},
|
tooltip: {
|
trigger: 'axis',
|
formatter: (params) => {
|
const date = new Date(params[0].value[0]);
|
return `${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}<br/>水深:${params[0].value[1]} m`;
|
},
|
backgroundColor: 'rgba(0,0,0,0.7)',
|
textStyle: {
|
color: '#fff',
|
fontSize: 14
|
}
|
},
|
xAxis: {
|
type: 'time',
|
name: '', // 去除X轴单位名称
|
axisLabel: {
|
color: '#fff',
|
fontSize: 12,
|
formatter: function (value) {
|
const date = new Date(value);
|
return `${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`;
|
},
|
interval: 'auto', // 自动计算间隔防止重叠
|
rotate: 45 // 倾斜45度防止重叠
|
},
|
nameTextStyle: {
|
color: '#fff',
|
fontSize: 14
|
}
|
},
|
yAxis: {
|
type: 'value',
|
name: '水深(m)', // 单位简写为小写m
|
min: 1.5,
|
max: 3.5,
|
axisLabel: {
|
color: '#fff',
|
fontSize: 12
|
},
|
nameTextStyle: {
|
color: '#fff',
|
fontSize: 14
|
}
|
},
|
series: [{
|
name: '水深',
|
type: 'line',
|
data: data.map(item => [item.time, item.value]),
|
showSymbol: true,
|
lineStyle: {
|
color: '#f97316', // 改为橙色,与流速一致
|
width: 2
|
},
|
itemStyle: {
|
color: '#f97316'
|
},
|
smooth: false
|
}],
|
// dataZoom: [{
|
// type: 'slider',
|
// start: 0,
|
// end: 100,
|
// bottom: '0%', // 下移缩放控件
|
// textStyle: {
|
// color: '#fff',
|
// fontSize: 12
|
// },
|
// filterMode: 'filter'
|
// }],
|
// 全局文字样式
|
textStyle: {
|
color: '#fff',
|
fontSize: 14
|
},
|
animation: false
|
};
|
|
chart.setOption(option);
|
|
window.addEventListener('resize', debounce(() => {
|
chart.resize();
|
}, 200));
|
}
|
|
watch(
|
() => currentInfo.value,
|
(newVal) => {
|
if (!newVal || showSelectPrompt.value || !chartDom.value) return;
|
|
console.log('经度:', newVal.longitude);
|
console.log('纬度:', newVal.latitude);
|
console.log('服务名称:', newVal.serviceInfo);
|
|
// 销毁旧图表
|
if (myChart) {
|
myChart.dispose();
|
}
|
|
// 创建新图表
|
myChart = echarts.init(chartDom.value);
|
initChart(myChart);
|
},
|
{ deep: true }
|
);
|
|
onMounted(() => {
|
if (!showSelectPrompt.value && chartDom.value) {
|
myChart = echarts.init(chartDom.value);
|
initChart(myChart);
|
}
|
});
|
onBeforeMount(() => {
|
EventBus.on('clear-water-depth', clear);
|
});
|
onBeforeUnmount(() => {
|
if (myChart) {
|
myChart.dispose();
|
myChart = null;
|
}
|
EventBus.off('clear-water-depth', clear);
|
|
});
|
function clear() {
|
// 清空 store 中的经纬度信息
|
currentInfo.value.longitude = 0.0;
|
currentInfo.value.latitude = 0.0;
|
|
// 清除 ECharts 图表
|
if (myChart) {
|
myChart.clear(); // 清除图表数据和图形
|
myChart.dispose(); // 销毁实例,释放资源
|
myChart = null;
|
}
|
}
|
function getFlowRateInfo(lon, lat, serviceInfo) {
|
const params = {
|
lon: lon,
|
lat: lat,
|
serviceName: serviceInfo
|
};
|
return getFlowRate(params).then(data => {
|
console.log('获取到的数据:', data);
|
if (data && data.code === 200) {
|
return {
|
depth: data.data.depth.toFixed(2),
|
velocity: data.data.velocity.toFixed(2)
|
};
|
} else {
|
return { depth: 'N/A', velocity: 'N/A' };
|
}
|
}).catch(error => {
|
console.error('获取数据时发生错误:', error);
|
return { depth: 'N/A', velocity: 'N/A' };
|
});
|
}
|
|
function resizeChart() {
|
if (myChart) {
|
myChart.resize();
|
}
|
}
|
|
defineExpose({ resizeChart });
|
</script>
|
|
<style scoped>
|
.water-depth-content {
|
padding-left: 8px;
|
padding-top: 8px;
|
border-radius: 6px;
|
}
|
|
.chart-placeholder {
|
margin-top: 10px;
|
}
|
|
.location-info,
|
.depth-info {
|
margin-bottom: 10px;
|
}
|
|
.coordinates {
|
font-size: 15px;
|
color: #fff;
|
user-select: all;
|
display: inline-block;
|
border-radius: 4px;
|
transition: background-color 0.2s ease;
|
}
|
|
.depth-info p {
|
font-size: 14px;
|
color: #fff;
|
}
|
|
.depth-info strong {
|
color: #fff;
|
margin: 0 4px;
|
}
|
</style>
|