| | |
| | | serviceName: serviceInfo |
| | | }; |
| | | return getFlowRate(params).then(data => { |
| | | console.log('获取到的数据:', data); |
| | | // console.log('获取到的数据:', data); |
| | | if (data && data.code === 200) { |
| | | return { |
| | | depth: data.data.depth.toFixed(2), |
| | |
| | | <template> |
| | | <div class="water-depth-content"> |
| | | <!-- 提示信息 --> |
| | | <div v-if="showSelectPrompt" style=" font-weight: bold;"> |
| | | <div v-if="showSelectPrompt" style="font-weight: bold;"> |
| | | 请在地图中选取唯一测量点 |
| | | </div> |
| | | |
| | |
| | | <div class="depth-info"> |
| | | <h3>水深信息 (m)</h3> |
| | | <p> |
| | | 平均:<strong>2.45</strong> |
| | | 最大:<strong>3.10</strong> |
| | | 最小:<strong>1.80</strong> |
| | | 平均:<strong>{{ avgDepth }}</strong> |
| | | 最大:<strong>{{ maxDepth }}</strong> |
| | | 最小:<strong>{{ minDepth }}</strong> |
| | | </p> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 图表容器 --> |
| | | <div class="chart-placeholder"> |
| | | <div ref="chartDom" style="width: 100%; height:300px;"></div> |
| | | <div ref="chartDom" style="width: 100%; height: 300px;"></div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted, watch, computed, onBeforeUnmount, onBeforeMount } from 'vue'; |
| | | import { ref, onMounted, watch, computed, onBeforeUnmount } 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"; // 引入事件总线 |
| | | 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 元素引用 |
| | | // 图表 DOM 引用 |
| | | const chartDom = ref(null); |
| | | let myChart = null; |
| | | |
| | | // 计算属性:安全获取经纬度 |
| | | // 安全获取经纬度 |
| | | const safeCurrentInfo = computed(() => { |
| | | const info = currentInfo.value || {}; |
| | | return { |
| | |
| | | }; |
| | | }); |
| | | |
| | | // 判断是否需要显示选择提示 |
| | | // 是否显示选择提示 |
| | | const showSelectPrompt = computed(() => { |
| | | const info = safeCurrentInfo.value; |
| | | return info.longitude === 0.0 && info.latitude === 0.0; |
| | | }); |
| | | |
| | | // 计算平均、最大、最小水深 |
| | | const avgDepth = computed(() => { |
| | | if (!myData.value.length) return '--'; |
| | | const sum = myData.value.reduce((acc, cur) => acc + cur.depth, 0); |
| | | return (sum / myData.value.length).toFixed(2); |
| | | }); |
| | | const maxDepth = computed(() => { |
| | | if (!myData.value.length) return '--'; |
| | | return Math.max(...myData.value.map(d => d.depth)).toFixed(2); |
| | | }); |
| | | const minDepth = computed(() => { |
| | | if (!myData.value.length) return '--'; |
| | | return Math.min(...myData.value.map(d => d.depth)).toFixed(2); |
| | | }); |
| | | |
| | | // 数据缓存 |
| | | const myData = ref([]); |
| | | |
| | | // 防抖函数 |
| | | function debounce(func, 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; |
| | | } |
| | | // 获取并更新图表 |
| | | async function fetchDataAndUpdateChart(chart) { |
| | | const info = currentInfo.value; |
| | | if (!info || showSelectPrompt.value || !chartDom.value) return; |
| | | |
| | | function initChart(chart) { |
| | | const data = generateSampleData(); |
| | | const { longitude, latitude, serviceInfo } = info; |
| | | const result = await getFlowRateInfo(longitude, latitude, serviceInfo); |
| | | |
| | | 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')}`; |
| | | if (result && Array.isArray(result)) { |
| | | myData.value = result; |
| | | |
| | | const option = { |
| | | title: { |
| | | text: '水深变化趋势', |
| | | textStyle: { |
| | | color: '#fff', |
| | | fontSize: 16 |
| | | }, |
| | | interval: 'auto', // 自动计算间隔防止重叠 |
| | | rotate: 45 // 倾斜45度防止重叠 |
| | | left: '-1%' |
| | | }, |
| | | nameTextStyle: { |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | formatter: (params) => { |
| | | const date = new Date(params[0].value[0]); |
| | | const year = date.getFullYear(); |
| | | const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始 |
| | | const day = String(date.getDate()).padStart(2, '0'); |
| | | const hours = String(date.getHours()).padStart(2, '0'); |
| | | const minutes = String(date.getMinutes()).padStart(2, '0'); |
| | | const seconds = String(date.getSeconds()).padStart(2, '0'); |
| | | |
| | | const formattedDate = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; |
| | | |
| | | return `${formattedDate}<br/>水深:${params[0].value[1].toFixed(4)} m`; |
| | | }, |
| | | backgroundColor: 'rgba(0,0,0,0.7)', |
| | | textStyle: { |
| | | color: '#fff', |
| | | fontSize: 14 |
| | | } |
| | | }, |
| | | xAxis: { |
| | | type: 'time', |
| | | name: '', |
| | | axisLabel: { |
| | | color: '#fff', |
| | | fontSize: 12, |
| | | formatter: function (value) { |
| | | const date = new Date(value); |
| | | const year = date.getFullYear(); |
| | | const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始 |
| | | const day = String(date.getDate()).padStart(2, '0'); |
| | | const hours = String(date.getHours()).padStart(2, '0'); |
| | | const minutes = String(date.getMinutes()).padStart(2, '0'); |
| | | const seconds = String(date.getSeconds()).padStart(2, '0'); |
| | | |
| | | return `${month}-${day} \n${hours}:${minutes}`; |
| | | }, |
| | | interval: 'auto', |
| | | rotate: 45 |
| | | }, |
| | | nameTextStyle: { |
| | | color: '#fff', |
| | | fontSize: 14 |
| | | } |
| | | }, |
| | | yAxis: { |
| | | type: 'value', |
| | | name: '水深(m)', |
| | | min: 0, |
| | | max: Math.max(...result.map(i => i.depth)) + 0.05, |
| | | axisLabel: { |
| | | color: '#fff', |
| | | fontSize: 12, |
| | | formatter: value => value.toFixed(2) |
| | | }, |
| | | nameTextStyle: { |
| | | color: '#fff', |
| | | fontSize: 14 |
| | | } |
| | | }, |
| | | dataZoom: [ |
| | | { |
| | | type: 'slider', // 滑块型缩放条 |
| | | start: 0, // 初始显示从 0% 开始 |
| | | end: 100, // 到 100% |
| | | height: 20, // 缩放条高度 |
| | | bottom: 10, // 距离底部距离 |
| | | borderColor: 'rgba(255,255,255,0.3)', |
| | | backgroundColor: 'rgba(50,50,50,0.3)', |
| | | fillerColor: 'rgba(70,130,180,0.6)', |
| | | textStyle: { |
| | | color: '#fff' |
| | | } |
| | | }, |
| | | { |
| | | type: 'inside', // 内部滚动(支持鼠标滚轮和手势) |
| | | start: 0, |
| | | end: 100 |
| | | } |
| | | ], |
| | | series: [{ |
| | | name: '水深', |
| | | type: 'line', |
| | | data: result.map(item => [new Date(item.time), item.depth]), |
| | | showSymbol: true, |
| | | lineStyle: { |
| | | color: '#3268fe', |
| | | width: 2 |
| | | }, |
| | | itemStyle: { |
| | | color: '#3268fe' |
| | | }, |
| | | smooth: false |
| | | }], |
| | | textStyle: { |
| | | 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 |
| | | }; |
| | | animation: false |
| | | }; |
| | | |
| | | chart.setOption(option); |
| | | |
| | | window.addEventListener('resize', debounce(() => { |
| | | chart.resize(); |
| | | }, 200)); |
| | | chart.setOption(option, true); // 合并配置 |
| | | } |
| | | } |
| | | |
| | | // 初始化图表 |
| | | function initChart(chart) { |
| | | fetchDataAndUpdateChart(chart); |
| | | } |
| | | |
| | | // 获取真实数据 |
| | | function getFlowRateInfo(lon, lat, serviceInfo) { |
| | | const params = { |
| | | lon: lon, |
| | | lat: lat, |
| | | serviceName: serviceInfo |
| | | }; |
| | | return getFlowRate(params).then(data => { |
| | | console.log('获取到的数据1111111111111111111111:', data); |
| | | if (data && data.code === 200) { |
| | | return data.data; // 返回原始数据数组 |
| | | } else { |
| | | return []; |
| | | } |
| | | }).catch(error => { |
| | | console.error('获取数据时发生错误:', error); |
| | | return []; |
| | | }); |
| | | } |
| | | |
| | | // 监听 currentInfo 变化 |
| | | watch( |
| | | () => currentInfo.value, |
| | | (newVal) => { |
| | | async (newVal) => { |
| | | if (!newVal || showSelectPrompt.value || !chartDom.value) return; |
| | | |
| | | console.log('经度:', newVal.longitude); |
| | | console.log('纬度:', newVal.latitude); |
| | | console.log('服务名称:', newVal.serviceInfo); |
| | | |
| | | // console.log('经度:', newVal.longitude); |
| | | // console.log('纬度:', newVal.latitude); |
| | | // console.log('服务名称:', newVal.serviceInfo); |
| | | // 销毁旧图表 |
| | | if (myChart) { |
| | | myChart.dispose(); |
| | | } |
| | | |
| | | // 创建新图表 |
| | | myChart = echarts.init(chartDom.value); |
| | | initChart(myChart); |
| | | await fetchDataAndUpdateChart(myChart); |
| | | }, |
| | | { deep: true } |
| | | ); |
| | |
| | | if (!showSelectPrompt.value && chartDom.value) { |
| | | myChart = echarts.init(chartDom.value); |
| | | initChart(myChart); |
| | | |
| | | // 添加 resize 监听器 |
| | | window.addEventListener('resize', debounce(() => { |
| | | if (myChart) myChart.resize(); |
| | | }, 200)); |
| | | } |
| | | }); |
| | | onBeforeMount(() => { |
| | | |
| | | // 注册事件总线监听 |
| | | EventBus.on('clear-water-depth', clear); |
| | | }); |
| | | |
| | | onBeforeUnmount(() => { |
| | | // 移除 resize 监听 |
| | | window.removeEventListener('resize', debounce(() => { |
| | | if (myChart) myChart.resize(); |
| | | }, 200)); |
| | | |
| | | // 清理图表 |
| | | if (myChart) { |
| | | myChart.dispose(); |
| | | myChart = null; |
| | | } |
| | | EventBus.off('clear-water-depth', clear); |
| | | |
| | | // 移除事件监听 |
| | | EventBus.off('clear-water-depth', clear); |
| | | }); |
| | | |
| | | // 清空方法 |
| | | function clear() { |
| | | // 清空 store 中的经纬度信息 |
| | | currentInfo.value.longitude = 0.0; |
| | |
| | | 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' }; |
| | | }); |
| | | } |
| | | |
| | | // 暴露 resize 方法供外部调用 |
| | | function resizeChart() { |
| | | if (myChart) { |
| | | myChart.resize(); |
| | | } |
| | | } |
| | | |
| | | defineExpose({ resizeChart }); |
| | | defineExpose({ resizeChart }); |
| | | </script> |
| | | |
| | | <style scoped> |
| | |
| | | <template> |
| | | <div class="water-velocity-content"> |
| | | <!-- 提示信息 --> |
| | | <div v-if="showSelectPrompt" style=" font-weight: bold;"> |
| | | <div v-if="showSelectPrompt" style="font-weight: bold;"> |
| | | 请在地图中选取唯一测量点 |
| | | </div> |
| | | |
| | |
| | | <div class="velocity-info"> |
| | | <h3>流速信息 (m/s)</h3> |
| | | <p> |
| | | 平均:<strong>1.25</strong> |
| | | 最大:<strong>1.80</strong> |
| | | 最小:<strong>0.70</strong> |
| | | 平均:<strong>{{ avgVelocity }}</strong> |
| | | 最大:<strong>{{ maxVelocity }}</strong> |
| | | 最小:<strong>{{ minVelocity }}</strong> |
| | | </p> |
| | | </div> |
| | | </div> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, onMounted, watch, computed, onBeforeUnmount,onBeforeMount } from 'vue'; |
| | | import { ref, onMounted, watch, computed, onBeforeUnmount } from 'vue'; |
| | | import * as echarts from 'echarts'; |
| | | import { useSimStore } from "@/store/simulation"; |
| | | import { storeToRefs } from "pinia"; |
| | | import { EventBus } from "@/eventBus"; // 引入事件总线 |
| | | 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 元素引用 |
| | | // 图表 DOM 引用 |
| | | const chartDom = ref(null); |
| | | let myChart = null; |
| | | |
| | | // 计算属性:安全获取经纬度 |
| | | // 安全获取经纬度 |
| | | const safeCurrentInfo = computed(() => { |
| | | const info = currentInfo.value || {}; |
| | | return { |
| | |
| | | }; |
| | | }); |
| | | |
| | | // 判断是否需要显示选择提示 |
| | | // 是否显示选择提示 |
| | | const showSelectPrompt = computed(() => { |
| | | const info = safeCurrentInfo.value; |
| | | return info.longitude === 0.0 && info.latitude === 0.0; |
| | | }); |
| | | |
| | | // 计算平均、最大、最小流速 |
| | | const avgVelocity = computed(() => { |
| | | if (!myData.value.length) return '--'; |
| | | const sum = myData.value.reduce((acc, cur) => acc + cur.velocity, 0); |
| | | return (sum / myData.value.length).toFixed(2); |
| | | }); |
| | | const maxVelocity = computed(() => { |
| | | if (!myData.value.length) return '--'; |
| | | return Math.max(...myData.value.map(d => d.velocity)).toFixed(2); |
| | | }); |
| | | const minVelocity = computed(() => { |
| | | if (!myData.value.length) return '--'; |
| | | return Math.min(...myData.value.map(d => d.velocity)).toFixed(2); |
| | | }); |
| | | |
| | | // 数据缓存 |
| | | const myData = ref([]); |
| | | |
| | | // 防抖函数 |
| | | function debounce(func, wait) { |
| | |
| | | }, wait); |
| | | }; |
| | | } |
| | | // 时间格式化工具函数 |
| | | function formatDateTime(date) { |
| | | const d = new Date(date); |
| | | const year = d.getFullYear(); |
| | | const month = String(d.getMonth() + 1).padStart(2, '0'); // 月份从 0 开始 |
| | | const day = String(d.getDate()).padStart(2, '0'); |
| | | const hours = String(d.getHours()).padStart(2, '0'); |
| | | const minutes = String(d.getMinutes()).padStart(2, '0'); |
| | | const seconds = String(d.getSeconds()).padStart(2, '0'); |
| | | |
| | | // 简化数据源 |
| | | function generateSampleData() { |
| | | const now = new Date(); |
| | | const data = []; |
| | | // 生成7个数据点,每10分钟一个 |
| | | for (let i = 100; i >= 0; i--) { |
| | | const time = new Date(now.getTime() - i * 10 * 60 * 1000); |
| | | // 随机生成0.7-1.8之间的流速数据 |
| | | const velocity = (0.7 + Math.random() * 3).toFixed(2); |
| | | data.push({ |
| | | time: time, |
| | | value: parseFloat(velocity) |
| | | }); |
| | | } |
| | | return data; |
| | | return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; |
| | | } |
| | | // 获取并更新图表 |
| | | async function fetchDataAndUpdateChart(chart) { |
| | | const info = currentInfo.value; |
| | | if (!info || showSelectPrompt.value || !chartDom.value) return; |
| | | |
| | | function initChart(chart) { |
| | | const data = generateSampleData(); |
| | | const { longitude, latitude, serviceInfo } = info; |
| | | const result = await getFlowRateInfo(longitude, latitude, serviceInfo); |
| | | |
| | | const option = { |
| | | // grid: { |
| | | // top: '5%', // 上边距减少 => 折线图变高 |
| | | // bottom: '%', // 下边距减少 => 折线图变高 |
| | | // left: '10%', // 左边距减少 => 折线图变宽 |
| | | // right: '10%' // 右边距减少 => 折线图变宽 |
| | | // }, |
| | | title: { |
| | | text: '流速变化趋势', |
| | | textStyle: { |
| | | color: '#fff', |
| | | fontSize: 16 |
| | | }, |
| | | // 将标题向左移动 1% |
| | | left: '-1%' |
| | | }, |
| | | 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/s`; |
| | | }, |
| | | backgroundColor: 'rgba(0,0,0,0.7)', |
| | | textStyle: { |
| | | color: '#fff', |
| | | fontSize: 14 |
| | | } |
| | | }, |
| | | xAxis: { |
| | | type: 'time', |
| | | // 取消 X 轴单位 |
| | | name: '', |
| | | axisLabel: { |
| | | color: '#fff', |
| | | fontSize: 12, |
| | | formatter: function (value) { |
| | | const date = new Date(value); |
| | | return `${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`; |
| | | if (result && Array.isArray(result)) { |
| | | myData.value = result; |
| | | |
| | | const option = { |
| | | title: { |
| | | text: '流速变化趋势', |
| | | textStyle: { |
| | | color: '#fff', |
| | | fontSize: 16 |
| | | }, |
| | | interval: 'auto', // 自动计算间隔防止重叠 |
| | | rotate: 45 // 倾斜45度防止重叠 |
| | | left: '-1%' |
| | | }, |
| | | nameTextStyle: { |
| | | color: '#fff', |
| | | fontSize: 14 |
| | | } |
| | | }, |
| | | yAxis: { |
| | | type: 'value', |
| | | name: '流速(m/s)', |
| | | min: 0.5, // 设置最小值 |
| | | max: 6.0, // 设置最大值 |
| | | axisLabel: { |
| | | color: '#fff', |
| | | fontSize: 12, |
| | | tooltip: { |
| | | trigger: 'axis', |
| | | formatter: (params) => { |
| | | const dateStr = formatDateTime(params[0].value[0]); |
| | | return `${dateStr}<br/>流速:${params[0].value[1].toFixed(4)} m/s`; |
| | | }, |
| | | backgroundColor: 'rgba(0,0,0,0.7)', |
| | | textStyle: { |
| | | color: '#fff', |
| | | fontSize: 14 |
| | | } |
| | | }, |
| | | nameTextStyle: { |
| | | xAxis: { |
| | | type: 'time', |
| | | name: '', |
| | | axisLabel: { |
| | | color: '#fff', |
| | | fontSize: 12, |
| | | formatter: function (value) { |
| | | const date = new Date(value); |
| | | const year = date.getFullYear(); |
| | | const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始 |
| | | const day = String(date.getDate()).padStart(2, '0'); |
| | | const hours = String(date.getHours()).padStart(2, '0'); |
| | | const minutes = String(date.getMinutes()).padStart(2, '0'); |
| | | const seconds = String(date.getSeconds()).padStart(2, '0'); |
| | | |
| | | return `${month}-${day} \n${hours}:${minutes}`; |
| | | }, |
| | | interval: 'auto', |
| | | rotate: 45 |
| | | }, |
| | | nameTextStyle: { |
| | | color: '#fff', |
| | | fontSize: 14 |
| | | } |
| | | }, |
| | | yAxis: { |
| | | type: 'value', |
| | | name: '流速(m/s)', |
| | | min: 0, |
| | | max: Math.max(...result.map(i => i.velocity)) + 0.05, |
| | | axisLabel: { |
| | | color: '#fff', |
| | | fontSize: 12, |
| | | formatter: value => value.toFixed(2) |
| | | }, |
| | | nameTextStyle: { |
| | | color: '#fff', |
| | | fontSize: 14 |
| | | } |
| | | }, |
| | | dataZoom: [ |
| | | { |
| | | type: 'slider', // 滑块型缩放条 |
| | | start: 0, // 初始显示从 0% 开始 |
| | | end: 100, // 到 100% |
| | | height: 20, // 缩放条高度 |
| | | bottom: 10, // 距离底部距离 |
| | | borderColor: 'rgba(255,255,255,0.3)', |
| | | backgroundColor: 'rgba(50,50,50,0.3)', |
| | | fillerColor: 'rgba(70,130,180,0.6)', |
| | | textStyle: { |
| | | color: '#fff' |
| | | } |
| | | }, |
| | | { |
| | | type: 'inside', // 内部滚动(支持鼠标滚轮和手势) |
| | | start: 0, |
| | | end: 100 |
| | | } |
| | | ], |
| | | series: [{ |
| | | name: '流速', |
| | | type: 'line', |
| | | data: result.map(item => [new Date(item.time), item.velocity]), |
| | | showSymbol: true, |
| | | lineStyle: { |
| | | color: '#3268fe', |
| | | width: 2 |
| | | }, |
| | | itemStyle: { |
| | | color: '#3268fe' |
| | | }, |
| | | smooth: false, |
| | | progressive: 0 // 禁止异步渲染以提升大数据量下的响应速度 |
| | | }], |
| | | textStyle: { |
| | | 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: true // 平滑曲线 |
| | | }], |
| | | // dataZoom: [{ |
| | | // type: 'slider', |
| | | // start: 0, |
| | | // end: 100, |
| | | // textStyle: { |
| | | // color: '#fff', |
| | | // fontSize: 12 |
| | | // }, |
| | | // filterMode: 'filter', // 避免重复渲染 |
| | | // // 缩放控件向下移动 2% |
| | | // bottom: '0%' |
| | | // }], |
| | | // 全局文字样式 |
| | | textStyle: { |
| | | color: '#fff', |
| | | fontSize: 14 |
| | | }, |
| | | animation: false // 禁用动画,提高性能 |
| | | }; |
| | | animation: false |
| | | }; |
| | | |
| | | chart.setOption(option); |
| | | |
| | | // 添加防抖的resize监听 |
| | | window.addEventListener('resize', debounce(() => { |
| | | chart.resize(); |
| | | }, 200)); |
| | | chart.setOption(option, true); // 合并配置 |
| | | } |
| | | } |
| | | |
| | | // 初始化图表 |
| | | function initChart(chart) { |
| | | fetchDataAndUpdateChart(chart); |
| | | } |
| | | |
| | | // 获取真实数据 |
| | | function getFlowRateInfo(lon, lat, serviceInfo) { |
| | | const params = { |
| | | lon: lon, |
| | | lat: lat, |
| | | serviceName: serviceInfo |
| | | }; |
| | | return getFlowRate(params).then(data => { |
| | | console.log('222222222222222222获取到的数据:', data); |
| | | if (data && data.code === 200) { |
| | | return data.data; // 返回原始数据数组 |
| | | } else { |
| | | return []; |
| | | } |
| | | }).catch(error => { |
| | | console.error('获取数据时发生错误:', error); |
| | | return []; |
| | | }); |
| | | } |
| | | |
| | | // 监听 currentInfo 变化 |
| | | watch( |
| | | () => currentInfo.value, |
| | | (newVal) => { |
| | | async (newVal) => { |
| | | if (!newVal || showSelectPrompt.value || !chartDom.value) return; |
| | | |
| | | console.log('经度:', newVal.longitude); |
| | | console.log('纬度:', newVal.latitude); |
| | | console.log('服务名称:', newVal.serviceInfo); |
| | | |
| | | // console.log('经度:', newVal.longitude); |
| | | // console.log('纬度:', newVal.latitude); |
| | | // console.log('服务名称:', newVal.serviceInfo); |
| | | // 销毁旧图表 |
| | | if (myChart) { |
| | | myChart.dispose(); |
| | |
| | | |
| | | // 创建新图表 |
| | | myChart = echarts.init(chartDom.value); |
| | | initChart(myChart); |
| | | await fetchDataAndUpdateChart(myChart); |
| | | }, |
| | | { deep: true } |
| | | ); |
| | |
| | | if (!showSelectPrompt.value && chartDom.value) { |
| | | myChart = echarts.init(chartDom.value); |
| | | initChart(myChart); |
| | | |
| | | // 添加 resize 监听器 |
| | | window.addEventListener('resize', debounce(() => { |
| | | if (myChart) myChart.resize(); |
| | | }, 200)); |
| | | } |
| | | }); |
| | | onBeforeMount(() => { |
| | | |
| | | // 注册事件总线监听 |
| | | EventBus.on('clear-water-velocity', clear); |
| | | }); |
| | | |
| | | onBeforeUnmount(() => { |
| | | // 移除 resize 监听 |
| | | window.removeEventListener('resize', debounce(() => { |
| | | if (myChart) myChart.resize(); |
| | | }, 200)); |
| | | |
| | | // 清理图表 |
| | | if (myChart) { |
| | | myChart.dispose(); |
| | | myChart = null; |
| | | } |
| | | EventBus.off('clear-water-velocity', clear); |
| | | |
| | | // 移除事件监听 |
| | | EventBus.off('clear-water-velocity', clear); |
| | | }); |
| | | |
| | | // 清空方法 |
| | | function clear() { |
| | | // 清空 store 中的经纬度信息 |
| | | currentInfo.value.longitude = 0.0; |
| | |
| | | myChart = null; |
| | | } |
| | | } |
| | | // 添加 resizeChart 方法 |
| | | |
| | | // 暴露 resize 方法供外部调用 |
| | | function resizeChart() { |
| | | if (myChart) { |
| | | myChart.resize(); |
| | | } |
| | | } |
| | | |
| | | // 暴露方法给父组件调用 |
| | | defineExpose({ resizeChart }); |
| | | </script> |
| | | |
| | |
| | | .water-velocity-content { |
| | | padding-left: 8px; |
| | | padding-top: 8px; |
| | | padding-bottom: -8px; |
| | | border-radius: 6px; |
| | | } |
| | | |
| | | .chart-placeholder { |
| | | margin-top: 10px; |
| | | } |
| | | |
| | | .location-info, |
| | |
| | | .velocity-info strong { |
| | | color: #fff; |
| | | margin: 0 4px; |
| | | } |
| | | |
| | | .chart-placeholder { |
| | | overflow: hidden; |
| | | height: 284px; |
| | | /* margin-top: 10px; */ |
| | | } |
| | | </style> |