Преглед изворни кода

[0806] 风速曲线图、温度曲线图、湿度曲线图、气压曲线图、辐照曲线图 | 优化曲线为连续曲线

taosj пре 1 месец
родитељ
комит
dc374a753c

+ 1 - 0
forecast-backend-server/src/main/resources/mybatis/weather/DataShortTermWeatherForecastRawMapper.xml

@@ -150,6 +150,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         where station_id = #{stationId}
           and forecast_time >= #{startTime}
           and forecast_time <= #{endTime}
+        order by forecast_time asc
     </select>
 
     <select id="selectDataShortTermWeatherForecastRawById" parameterType="Long" resultMap="DataShortTermWeatherForecastRawResult">

+ 10 - 14
forecast-backend-vue/src/views/ufo/electricity/weather/HumidityCurve.vue

@@ -119,23 +119,19 @@ const loadStations = async () => {
 };
 
 const buildOption = (forecastStats, localStats) => {
-  const toMap = (stats, key) => {
-    const map = new Map();
-    (stats || []).forEach((item) => map.set(item.time, toNumber(item[key], 0)));
-    return map;
-  };
-  const forecastMap = toMap(forecastStats, 'rhsfc');
-  const localMap = toMap(localStats, 'rhsfc');
-  const times = [...new Set([...forecastMap.keys(), ...localMap.keys()])].sort();
+  // 预测/本地采样时间点不同,用连续时间轴各自按自身采样点绘制,避免线条因对方缺数而中断
+  // 按时间戳排序,保证数组顺序与时间一致,避免后端返回无序导致线条自我交叉
+  const toPairs = (stats, key) => (stats || [])
+    .map((item) => [dayjs(item.time).valueOf(), toNumber(item[key], 0)])
+    .sort((a, b) => a[0] - b[0]);
   return {
     tooltip: {trigger: 'axis'},
     legend: {top: 0, left: 'center', data: ['预测', '本地']},
     grid: {left: 60, right: 24, top: 46, bottom: 60},
     xAxis: {
-      type: 'category',
-      boundaryGap: false,
-      data: times,
-      axisLabel: {color: '#5a6a85'}
+      type: 'time',
+      axisLabel: {color: '#5a6a85'},
+      axisPointer: {snap: true}
     },
     yAxis: {
       type: 'value',
@@ -148,8 +144,8 @@ const buildOption = (forecastStats, localStats) => {
       {type: 'slider', height: 18, bottom: 12, start: 0, end: 100}
     ],
     series: [
-      {name: '预测', type: 'line', smooth: true, showSymbol: false, data: times.map((t) => (forecastMap.has(t) ? forecastMap.get(t) : null))},
-      {name: '本地', type: 'line', smooth: true, showSymbol: false, data: times.map((t) => (localMap.has(t) ? localMap.get(t) : null))}
+      {name: '预测', type: 'line', smooth: true, showSymbol: false, data: toPairs(forecastStats, 'rhsfc')},
+      {name: '本地', type: 'line', smooth: true, showSymbol: false, data: toPairs(localStats, 'rhsfc')}
     ]
   };
 };

+ 10 - 14
forecast-backend-vue/src/views/ufo/electricity/weather/IrradianceCurve.vue

@@ -119,23 +119,19 @@ const loadStations = async () => {
 };
 
 const buildOption = (forecastStats, localStats) => {
-  const toMap = (stats, key) => {
-    const map = new Map();
-    (stats || []).forEach((item) => map.set(item.time, toNumber(item[key], 0)));
-    return map;
-  };
-  const forecastMap = toMap(forecastStats, 'tirr');
-  const localMap = toMap(localStats, 'tirr');
-  const times = [...new Set([...forecastMap.keys(), ...localMap.keys()])].sort();
+  // 预测/本地采样时间点不同,用连续时间轴各自按自身采样点绘制,避免线条因对方缺数而中断
+  // 按时间戳排序,保证数组顺序与时间一致,避免后端返回无序导致线条自我交叉
+  const toPairs = (stats, key) => (stats || [])
+    .map((item) => [dayjs(item.time).valueOf(), toNumber(item[key], 0)])
+    .sort((a, b) => a[0] - b[0]);
   return {
     tooltip: {trigger: 'axis'},
     legend: {top: 0, left: 'center', data: ['预测', '本地']},
     grid: {left: 60, right: 24, top: 46, bottom: 60},
     xAxis: {
-      type: 'category',
-      boundaryGap: false,
-      data: times,
-      axisLabel: {color: '#5a6a85'}
+      type: 'time',
+      axisLabel: {color: '#5a6a85'},
+      axisPointer: {snap: true}
     },
     yAxis: {
       type: 'value',
@@ -148,8 +144,8 @@ const buildOption = (forecastStats, localStats) => {
       {type: 'slider', height: 18, bottom: 12, start: 0, end: 100}
     ],
     series: [
-      {name: '预测', type: 'line', smooth: true, showSymbol: false, data: times.map((t) => (forecastMap.has(t) ? forecastMap.get(t) : null))},
-      {name: '本地', type: 'line', smooth: true, showSymbol: false, data: times.map((t) => (localMap.has(t) ? localMap.get(t) : null))}
+      {name: '预测', type: 'line', smooth: true, showSymbol: false, data: toPairs(forecastStats, 'tirr')},
+      {name: '本地', type: 'line', smooth: true, showSymbol: false, data: toPairs(localStats, 'tirr')}
     ]
   };
 };

+ 10 - 14
forecast-backend-vue/src/views/ufo/electricity/weather/PressureCurve.vue

@@ -119,23 +119,19 @@ const loadStations = async () => {
 };
 
 const buildOption = (forecastStats, localStats) => {
-  const toMap = (stats, key) => {
-    const map = new Map();
-    (stats || []).forEach((item) => map.set(item.time, toNumber(item[key], 0)));
-    return map;
-  };
-  const forecastMap = toMap(forecastStats, 'psfc');
-  const localMap = toMap(localStats, 'psfc');
-  const times = [...new Set([...forecastMap.keys(), ...localMap.keys()])].sort();
+  // 预测/本地采样时间点不同,用连续时间轴各自按自身采样点绘制,避免线条因对方缺数而中断
+  // 按时间戳排序,保证数组顺序与时间一致,避免后端返回无序导致线条自我交叉
+  const toPairs = (stats, key) => (stats || [])
+    .map((item) => [dayjs(item.time).valueOf(), toNumber(item[key], 0)])
+    .sort((a, b) => a[0] - b[0]);
   return {
     tooltip: {trigger: 'axis'},
     legend: {top: 0, left: 'center', data: ['预测', '本地']},
     grid: {left: 60, right: 24, top: 46, bottom: 60},
     xAxis: {
-      type: 'category',
-      boundaryGap: false,
-      data: times,
-      axisLabel: {color: '#5a6a85'}
+      type: 'time',
+      axisLabel: {color: '#5a6a85'},
+      axisPointer: {snap: true}
     },
     yAxis: {
       type: 'value',
@@ -148,8 +144,8 @@ const buildOption = (forecastStats, localStats) => {
       {type: 'slider', height: 18, bottom: 12, start: 0, end: 100}
     ],
     series: [
-      {name: '预测', type: 'line', smooth: true, showSymbol: false, data: times.map((t) => (forecastMap.has(t) ? forecastMap.get(t) : null))},
-      {name: '本地', type: 'line', smooth: true, showSymbol: false, data: times.map((t) => (localMap.has(t) ? localMap.get(t) : null))}
+      {name: '预测', type: 'line', smooth: true, showSymbol: false, data: toPairs(forecastStats, 'psfc')},
+      {name: '本地', type: 'line', smooth: true, showSymbol: false, data: toPairs(localStats, 'psfc')}
     ]
   };
 };

+ 10 - 14
forecast-backend-vue/src/views/ufo/electricity/weather/TemperatureCurve.vue

@@ -119,23 +119,19 @@ const loadStations = async () => {
 };
 
 const buildOption = (forecastStats, localStats) => {
-  const toMap = (stats, key) => {
-    const map = new Map();
-    (stats || []).forEach((item) => map.set(item.time, toNumber(item[key], 0)));
-    return map;
-  };
-  const forecastMap = toMap(forecastStats, 'tsfc');
-  const localMap = toMap(localStats, 'tsfc');
-  const times = [...new Set([...forecastMap.keys(), ...localMap.keys()])].sort();
+  // 预测/本地采样时间点不同,用连续时间轴各自按自身采样点绘制,避免线条因对方缺数而中断
+  // 按时间戳排序,保证数组顺序与时间一致,避免后端返回无序导致线条自我交叉
+  const toPairs = (stats, key) => (stats || [])
+    .map((item) => [dayjs(item.time).valueOf(), toNumber(item[key], 0)])
+    .sort((a, b) => a[0] - b[0]);
   return {
     tooltip: {trigger: 'axis'},
     legend: {top: 0, left: 'center', data: ['预测', '本地']},
     grid: {left: 60, right: 24, top: 46, bottom: 60},
     xAxis: {
-      type: 'category',
-      boundaryGap: false,
-      data: times,
-      axisLabel: {color: '#5a6a85'}
+      type: 'time',
+      axisLabel: {color: '#5a6a85'},
+      axisPointer: {snap: true}
     },
     yAxis: {
       type: 'value',
@@ -148,8 +144,8 @@ const buildOption = (forecastStats, localStats) => {
       {type: 'slider', height: 18, bottom: 12, start: 0, end: 100}
     ],
     series: [
-      {name: '预测', type: 'line', smooth: true, showSymbol: false, data: times.map((t) => (forecastMap.has(t) ? forecastMap.get(t) : null))},
-      {name: '本地', type: 'line', smooth: true, showSymbol: false, data: times.map((t) => (localMap.has(t) ? localMap.get(t) : null))}
+      {name: '预测', type: 'line', smooth: true, showSymbol: false, data: toPairs(forecastStats, 'tsfc')},
+      {name: '本地', type: 'line', smooth: true, showSymbol: false, data: toPairs(localStats, 'tsfc')}
     ]
   };
 };

+ 10 - 14
forecast-backend-vue/src/views/ufo/electricity/weather/WindSpeedCurve.vue

@@ -119,23 +119,19 @@ const loadStations = async () => {
 };
 
 const buildOption = (forecastStats, localStats) => {
-  const toMap = (stats, key) => {
-    const map = new Map();
-    (stats || []).forEach((item) => map.set(item.time, toNumber(item[key], 0)));
-    return map;
-  };
-  const forecastMap = toMap(forecastStats, 'ws');
-  const localMap = toMap(localStats, 'ws');
-  const times = [...new Set([...forecastMap.keys(), ...localMap.keys()])].sort();
+  // 预测/本地采样时间点不同,用连续时间轴各自按自身采样点绘制,避免线条因对方缺数而中断
+  // 按时间戳排序,保证数组顺序与时间一致,避免后端返回无序导致线条自我交叉
+  const toPairs = (stats, key) => (stats || [])
+    .map((item) => [dayjs(item.time).valueOf(), toNumber(item[key], 0)])
+    .sort((a, b) => a[0] - b[0]);
   return {
     tooltip: {trigger: 'axis'},
     legend: {top: 0, left: 'center', data: ['预测', '本地']},
     grid: {left: 60, right: 24, top: 46, bottom: 60},
     xAxis: {
-      type: 'category',
-      boundaryGap: false,
-      data: times,
-      axisLabel: {color: '#5a6a85'}
+      type: 'time',
+      axisLabel: {color: '#5a6a85'},
+      axisPointer: {snap: true}
     },
     yAxis: {
       type: 'value',
@@ -148,8 +144,8 @@ const buildOption = (forecastStats, localStats) => {
       {type: 'slider', height: 18, bottom: 12, start: 0, end: 100}
     ],
     series: [
-      {name: '预测', type: 'line', smooth: true, showSymbol: false, data: times.map((t) => (forecastMap.has(t) ? forecastMap.get(t) : null))},
-      {name: '本地', type: 'line', smooth: true, showSymbol: false, data: times.map((t) => (localMap.has(t) ? localMap.get(t) : null))}
+      {name: '预测', type: 'line', smooth: true, showSymbol: false, data: toPairs(forecastStats, 'ws')},
+      {name: '本地', type: 'line', smooth: true, showSymbol: false, data: toPairs(localStats, 'ws')}
     ]
   };
 };