| | |
| | | onUnmounted, |
| | | } from "vue"; |
| | | import dayjs from "dayjs"; |
| | | import { getRainfall } from "@/api"; |
| | | import { useSimStore } from "@/store/simulation"; |
| | | const simStore = useSimStore(); |
| | | const { rainFalls } = simStore; |
| | | |
| | | let dataIntervalId = null; // 表格定时器 ID |
| | | const jsonData = ref([]); // JSON 数据 |
| | |
| | | // 触发事件,将当前行的 ID 发送到地图组件 |
| | | EventBus.emit("row-clicked", row.id); |
| | | } |
| | | const listData = cityData.listData; |
| | | const data = ref([ |
| | | 8.16, 15.38, 13.94, 9.46, 86.42, 71.32, 28.52, 25.9, 13.74, 14.54, 15.53, |
| | | 9.17, 0, 0.09, 0.86, 8.15, 44.8, 21.86, 6.2, 4.98, 2.82, 2.36, 3.1, 1.06, |
| | | ]); |
| | | // const listData = cityData.listData; |
| | | // const data = ref([ |
| | | // 8.16, 15.38, 13.94, 9.46, 86.42, 71.32, 28.52, 25.9, 13.74, 14.54, 15.53, |
| | | // 9.17, 0, 0.09, 0.86, 8.15, 44.8, 21.86, 6.2, 4.98, 2.82, 2.36, 3.1, 1.06, |
| | | // ]); |
| | | const rainChangeShow = ref(false); |
| | | const tableContainer = ref(null); |
| | | |
| | |
| | | return timeOnly; |
| | | }; |
| | | |
| | | const setEcharts1 = () => { |
| | | // 1. 初始化图表 |
| | | const chartDom = document.getElementById("echarts1"); |
| | | myChart1 = echarts.init(chartDom); |
| | | // 暂时先不用,主要功能为一分钟插值六十个数据 |
| | | // function processData(originalData) { |
| | | // const processedData = []; |
| | | // let currentTotal = 0; // 动态累加的 total |
| | | |
| | | // 2. 数据定义(完全保持您的原始变量) |
| | | // for (let i = 0; i < originalData.length; i++) { |
| | | // const current = originalData[i]; |
| | | // const targetIntensity = current.intensity; |
| | | // let remainingIntensity = targetIntensity; // 剩余需要分配的 intensity |
| | | |
| | | // // 生成60个点(动态随机填充,允许出现低值和高值) |
| | | // for (let j = 0; j < 60; j++) { |
| | | // // 1. 动态生成 intensity(随机,但最后一点补足剩余值) |
| | | // let intensity; |
| | | // if (j === 59) { |
| | | // intensity = remainingIntensity; // 最后一点强制用完剩余值 |
| | | // } else { |
| | | // // 随机生成一个比例(0.1~0.5之间的低概率 + 偶尔高值) |
| | | // const isLowValue = Math.random() < 0.7; // 70%概率生成低值 |
| | | // const maxAllowed = remainingIntensity / (60 - j); // 确保不超剩余值 |
| | | // intensity = isLowValue |
| | | // ? Math.random() * maxAllowed * 0.3 // 低值范围 |
| | | // : Math.random() * maxAllowed * 1.5; // 偶尔高值 |
| | | // } |
| | | // remainingIntensity -= intensity; |
| | | |
| | | // // 2. 实时累加 total |
| | | // currentTotal += intensity; |
| | | |
| | | // processedData.push({ |
| | | // time: current.time, |
| | | // intensity: intensity, |
| | | // total: currentTotal, |
| | | // }); |
| | | // } |
| | | |
| | | // // 验证当前段的总 intensity 是否匹配原始数据 |
| | | // console.log( |
| | | // `Segment ${i}: Generated intensity sum = ${( |
| | | // targetIntensity - remainingIntensity |
| | | // ).toFixed(2)}, Original = ${targetIntensity}` |
| | | // ); |
| | | // } |
| | | |
| | | // return processedData; |
| | | // } |
| | | |
| | | // 设置降雨图表 |
| | | const setEcharts1 = () => { |
| | | const chartDom = document.getElementById("echarts1"); |
| | | const myChart1 = echarts.init(chartDom); |
| | | |
| | | // 图表数据 |
| | | let rainfallData = ref([]); |
| | | let data1 = ref([]); |
| | | let data2 = ref([]); |
| | | let xAxisData = ref([]); |
| | | let xAxisData = ref(["00:00"]); |
| | | let updateInterval = null; |
| | | let dataIndex = ref(0); |
| | | |
| | | |
| | | // 4. 动态计算Y轴(新增的核心逻辑) |
| | | // 动态计算Y轴范围 |
| | | const getDynamicYAxis = (dataArray) => { |
| | | const currentMax = Math.max(...dataArray, 1); // 确保最小显示范围 |
| | | const currentMax = Math.max(...dataArray, 1); |
| | | const step = Math.ceil(currentMax / 3); |
| | | return { |
| | | max: step * 3, |
| | |
| | | }; |
| | | }; |
| | | |
| | | // 5. 加载数据(完全保持您的逻辑) |
| | | // 加载JSON数据 |
| | | const loadJsonData = async () => { |
| | | try { |
| | | const response = await fetch("/json/rainfall.json"); |
| | | const result = await response.json(); |
| | | |
| | | if (result?.data?.length) { |
| | | rainfallData.value = result.data; |
| | | xAxisData.value = ["00:00"] || syncTimeWithTimeline(); // 初始时间点 |
| | | |
| | | // 这个result是用的上述的插值(暂时先不用) |
| | | // const result = processData(simStore.rainFalls); |
| | | const result = simStore.rainFalls; |
| | | if (result?.length) { |
| | | rainfallData.value = result; |
| | | if (rainfallData.value.length > 0) { |
| | | data1.value = [rainfallData.value[0].value]; |
| | | data2.value = [rainfallData.value[0].total]; |
| | | updateChart(); // 初始化图表 |
| | | // data1.value = [rainfallData.value[0].intensity]; |
| | | // data2.value = [rainfallData.value[0].total]; |
| | | // 默认初始从0开始的 |
| | | data1.value = [0]; |
| | | data2.value = [0]; |
| | | updateChart(); |
| | | } |
| | | } |
| | | } catch (error) { |
| | |
| | | } |
| | | }; |
| | | |
| | | // 6. 图表配置(仅修改Y轴部分) |
| | | // 更新图表配置 |
| | | const updateChart = () => { |
| | | const option = { |
| | | // >>> 保持您原有的所有配置 <<< |
| | | animation: false, |
| | | tooltip: { trigger: "axis" }, |
| | | grid: { left: "1%", right: "1%", bottom: "1%", containLabel: true }, |
| | | // // 调整grid布局解决Y轴标签显示问题 |
| | | grid: { |
| | | // left: "1%", // 左侧留更多空间 |
| | | // right: "1%", // 右侧留更多空间 |
| | | bottom: "1%", |
| | | containLabel: false, |
| | | }, |
| | | legend: { |
| | | data: ["降雨数据", "累计雨量"], |
| | | textStyle: { color: "#fff" }, |
| | | right: "10px", |
| | | // 添加legend点击事件处理 |
| | | selected: { |
| | | 降雨数据: true, |
| | | 累计雨量: true, |
| | | }, |
| | | }, |
| | | |
| | | // >>> 您原来的xAxis配置(完全不变) <<< |
| | | xAxis: [ |
| | | { |
| | | type: "category", |
| | | data: xAxisData.value, // 您的时间数据 |
| | | data: xAxisData.value, |
| | | axisLabel: { color: "#fff", rotate: 0 }, |
| | | }, |
| | | ], |
| | | |
| | | // >>> 修改的Y轴配置(动态范围) <<< |
| | | yAxis: [ |
| | | { |
| | | // 左侧Y轴(降雨) |
| | | type: "value", |
| | | name: "单位:mm", |
| | | min: 0, |
| | | ...getDynamicYAxis(data1.value), // 动态范围 |
| | | ...getDynamicYAxis(data1.value), |
| | | axisLabel: { color: "#fff" }, |
| | | splitLine: { show: false }, |
| | | // 确保名称显示完整 |
| | | nameTextStyle: { |
| | | color: "#fff", |
| | | }, |
| | | }, |
| | | { |
| | | // 右侧Y轴(累计) |
| | | type: "value", |
| | | name: "单位:mm", |
| | | min: 0, |
| | | ...getDynamicYAxis(data2.value), // 动态范围 |
| | | ...getDynamicYAxis(data2.value), |
| | | axisLabel: { color: "#fff" }, |
| | | splitLine: { show: true }, |
| | | nameTextStyle: { |
| | | color: "#fff", |
| | | }, |
| | | }, |
| | | ], |
| | | |
| | | // >>> 保持您原有的series配置 <<< |
| | | series: [ |
| | | { |
| | | name: "降雨数据", |
| | | type: "bar", |
| | | type: "bar", // 明确指定类型 |
| | | data: data1.value, |
| | | itemStyle: { color: "#3268fe" }, |
| | | }, |
| | | { |
| | | name: "累计雨量", |
| | | type: "line", |
| | | type: "line", // 明确指定类型 |
| | | yAxisIndex: 1, |
| | | data: data2.value, |
| | | lineStyle: { color: "#ffb637" }, |
| | |
| | | myChart1.setOption(option, true); |
| | | }; |
| | | |
| | | // 7. 数据更新(保持您的时间逻辑) |
| | | // 数据更新 |
| | | const updateData = () => { |
| | | if (dataIndex.value < rainfallData.value.length) { |
| | | const item = rainfallData.value[dataIndex.value]; |
| | | data1.value.push(item.value); |
| | | data1.value.push(item.intensity); |
| | | data2.value.push(item.total); |
| | | xAxisData.value.push(syncTimeWithTimeline()); // 您的时间生成方法 |
| | | xAxisData.value.push(syncTimeWithTimeline()); |
| | | dataIndex.value++; |
| | | updateChart(); // 动态调整Y轴 |
| | | updateChart(); |
| | | } else { |
| | | stopUpdating(); |
| | | } |
| | | }; |
| | | |
| | | // 8. 控制方法(完全不变) |
| | | const startUpdating = (interval = 1000) => { |
| | | // 控制方法 |
| | | const startUpdating = (interval = 60000) => { |
| | | if (!updateInterval) { |
| | | updateInterval = setInterval(updateData, interval); |
| | | } |
| | | }; |
| | | |
| | | const stopUpdating = () => { |
| | | if (updateInterval) { |
| | | clearInterval(updateInterval); |
| | | updateInterval = null; |
| | | } |
| | | clearInterval(updateInterval); |
| | | updateInterval = null; |
| | | }; |
| | | |
| | | const resetLoading = () => { |
| | |
| | | data2.value = []; |
| | | xAxisData.value = ["00:00"]; |
| | | if (rainfallData.value.length) { |
| | | data1.value = [rainfallData.value[0].value]; |
| | | data1.value = [rainfallData.value[0].intensity]; |
| | | data2.value = [rainfallData.value[0].total]; |
| | | } |
| | | updateChart(); |
| | | }; |
| | | |
| | | // 9. 初始化 |
| | | // 初始化 |
| | | loadJsonData(); |
| | | |
| | | return { |
| | |
| | | |
| | | const setEcharts2 = () => { |
| | | const chartDom = document.getElementById("echarts2"); |
| | | myChart2 = echarts.init(chartDom); |
| | | const myChart2 = echarts.init(chartDom); |
| | | |
| | | let jsonData = ref([]); |
| | | let data1 = ref([]); |
| | | let data2 = ref([]); |
| | | let xAxisData = ref([]); |
| | | let updateInterval = null; |
| | | // 图表数据(与echarts1保持相同结构) |
| | | let flowData = ref([]); // 原始数据 |
| | | let data1 = ref([]); // 实时流量 |
| | | let data2 = ref([]); // 累计流量 |
| | | let xAxisData = ref(["00:00"]); |
| | | let updateInterval = ref(null); |
| | | let dataIndex = ref(0); |
| | | |
| | | // 加载 JSON 数据(完全保持原有逻辑) |
| | | // 动态计算Y轴范围 |
| | | const calculateDynamicYAxis = (dataArray) => { |
| | | const currentMax = Math.max(...dataArray, 1); |
| | | const step = Math.ceil(currentMax / 3); |
| | | return { |
| | | max: step * 3, |
| | | interval: step, |
| | | }; |
| | | }; |
| | | const loadJsonData = async () => { |
| | | try { |
| | | const response = await fetch("/json/于家西沟断面下数据.json"); |
| | | const result = await response.json(); |
| | | if (result && result.data && Array.isArray(result.data)) { |
| | | jsonData.value = result.data; |
| | | xAxisData.value = ["00:00"] || syncTimeWithTimeline(); // 保持您的时间初始化 |
| | | |
| | | if (jsonData.value.length > 0) { |
| | | data1.value.push(jsonData.value[0].value); |
| | | data2.value.push(jsonData.value[0].total); |
| | | if (result?.data?.length) { |
| | | flowData.value = result.data; |
| | | if (flowData.value.length > 0) { |
| | | data1.value = [flowData.value[0].value]; |
| | | data2.value = [flowData.value[0].total]; |
| | | updateChart(); |
| | | } |
| | | updateChart(); // 初始化时自动计算Y轴范围 |
| | | } |
| | | } catch (error) { |
| | | console.error("数据加载失败:", error); |
| | | } |
| | | }; |
| | | |
| | | // 动态计算Y轴参数(新增核心功能) |
| | | const calculateDynamicYAxis = (dataArray) => { |
| | | const currentMax = Math.max(...dataArray, 1); // 确保最小显示范围 |
| | | const step = Math.ceil(currentMax / 3); |
| | | return { |
| | | max: step * 3, |
| | | interval: step |
| | | }; |
| | | }; |
| | | |
| | | // 更新图表配置(仅修改Y轴部分) |
| | | // 图表配置(与echarts1保持相同结构和样式) |
| | | const updateChart = () => { |
| | | const option = { |
| | | // >>> 保持您原有的所有配置 <<< |
| | | animation: false, |
| | | tooltip: { |
| | | trigger: "axis", |
| | | axisPointer: { type: "cross" } |
| | | axisPointer: { type: "cross" }, |
| | | }, |
| | | grid: { |
| | | left: "1%", |
| | | right: "1%", |
| | | // 注释是因为 y轴上的单位被覆盖掉了 |
| | | // left: "1%", |
| | | // right: "1%", |
| | | bottom: "1%", |
| | | containLabel: true |
| | | containLabel: false, |
| | | }, |
| | | legend: { |
| | | data: ["实时流量", "累计流量"], |
| | | textStyle: { color: "#fff" }, |
| | | right: "10px" |
| | | right: "10px", |
| | | selected: { |
| | | 实时流量: true, |
| | | 累计流量: true, |
| | | }, |
| | | }, |
| | | |
| | | // >>> 您原来的xAxis配置(完全不变) <<< |
| | | xAxis: [{ |
| | | type: "category", |
| | | data: xAxisData.value, |
| | | axisLabel: { color: "#fff", rotate: 0 } |
| | | }], |
| | | |
| | | // >>> 修改的Y轴配置(动态范围) <<< |
| | | xAxis: [ |
| | | { |
| | | type: "category", |
| | | data: xAxisData.value, |
| | | axisLabel: { |
| | | color: "#fff", |
| | | rotate: 0, |
| | | }, |
| | | }, |
| | | ], |
| | | yAxis: [ |
| | | { // 左侧Y轴(实时流量) |
| | | { |
| | | type: "value", |
| | | name: "单位:m³/min", |
| | | min: 0, |
| | | ...calculateDynamicYAxis(data1.value), |
| | | axisLabel: { |
| | | formatter: "{value}", |
| | | color: "#fff", |
| | | align: "right" |
| | | }, |
| | | axisLabel: { color: "#fff" }, |
| | | splitLine: { show: false }, |
| | | nameTextStyle: { |
| | | padding: [0, 0, 0, 20], |
| | | color: "#fff" |
| | | color: "#fff", |
| | | }, |
| | | splitLine: { show: false } |
| | | }, |
| | | { // 右侧Y轴(累计流量) |
| | | { |
| | | type: "value", |
| | | name: "单位:m³", |
| | | min: 0, |
| | | ...calculateDynamicYAxis(data2.value), |
| | | axisLabel: { |
| | | formatter: "{value}", |
| | | color: "#fff", |
| | | align: "left" |
| | | }, |
| | | axisLabel: { color: "#fff" }, |
| | | splitLine: { show: true }, |
| | | nameTextStyle: { |
| | | padding: [0, 10, 0, 0], |
| | | color: "#fff" |
| | | color: "#fff", |
| | | }, |
| | | splitLine: { show: true } |
| | | } |
| | | }, |
| | | ], |
| | | |
| | | // >>> 保持您原有的series配置 <<< |
| | | series: [ |
| | | { |
| | | name: "实时流量", |
| | | type: "bar", |
| | | tooltip: { valueFormatter: value => value + " m³/min" }, |
| | | data: data1.value, |
| | | itemStyle: { color: "blue" } |
| | | itemStyle: { |
| | | color: "#3268fe", |
| | | }, |
| | | }, |
| | | { |
| | | name: "累计流量", |
| | | type: "line", |
| | | yAxisIndex: 1, |
| | | tooltip: { valueFormatter: value => value + " m³" }, |
| | | data: data2.value, |
| | | lineStyle: { color: "#ffb637" } |
| | | } |
| | | ] |
| | | lineStyle: { |
| | | color: "#ffb637", |
| | | }, |
| | | }, |
| | | ], |
| | | }; |
| | | myChart2.setOption(option, true); // 强制刷新 |
| | | myChart2.setOption(option, true); |
| | | }; |
| | | |
| | | // 数据更新(保持您的时间逻辑) |
| | | // 数据更新(与echarts1相同逻辑) |
| | | const updateData = () => { |
| | | if (dataIndex.value < jsonData.value.length) { |
| | | const newItem = jsonData.value[dataIndex.value]; |
| | | data1.value.push(newItem.value); |
| | | data2.value.push(newItem.total); |
| | | xAxisData.value.push(syncTimeWithTimeline()); // 您的时间生成方法 |
| | | dataIndex.value += 2; // 保持您的索引步长 |
| | | updateChart(); // 自动调整Y轴 |
| | | if (dataIndex.value < flowData.value.length) { |
| | | const item = flowData.value[dataIndex.value]; |
| | | data1.value.push(item.value); |
| | | data2.value.push(item.total); |
| | | xAxisData.value.push(syncTimeWithTimeline()); |
| | | dataIndex.value++; |
| | | updateChart(); |
| | | } else { |
| | | stopUpdating(); |
| | | } |
| | | }; |
| | | |
| | | // 控制方法(完全不变) |
| | | // 控制方法(与echarts1完全一致) |
| | | const startUpdating = (interval = 1000) => { |
| | | if (!updateInterval) { |
| | | updateInterval = setInterval(updateData, interval); |
| | |
| | | data1.value = []; |
| | | data2.value = []; |
| | | xAxisData.value = ["00:00"]; |
| | | if (jsonData.value.length) { |
| | | data1.value.push(jsonData.value[0].value); |
| | | data2.value.push(jsonData.value[0].total); |
| | | if (flowData.value.length > 0) { |
| | | data1.value = [flowData.value[0].value]; |
| | | data2.value = [flowData.value[0].total]; |
| | | } |
| | | updateChart(); |
| | | }; |
| | |
| | | myChart2, |
| | | startUpdating, |
| | | stopUpdating, |
| | | resetLoading |
| | | resetLoading, |
| | | }; |
| | | }; |
| | | |