fix: Datenlücken in Charts korrekt darstellen, Version 1.5.1

- withGaps()-Hilfsfunktion: fügt null-Punkte bei Datenlücken ein
- Betrifft: Temperatur, Luftdruck, Feuchte, Wind, Böen
- restore-db.sh: mapfile durch while-read ersetzt (zsh-kompatibel)
This commit is contained in:
2026-05-03 13:42:30 +02:00
parent cc663487e0
commit 634a6d31a4
3 changed files with 38 additions and 17 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "wetterstation-frontend",
"private": true,
"version": "1.5.0",
"version": "1.5.1",
"type": "module",
"scripts": {
"dev": "vite",
+33 -15
View File
@@ -1,4 +1,4 @@
import { useMemo, useState } from 'react'
import { useMemo, useState, useCallback } from 'react'
import Highcharts from 'highcharts'
import { HighchartsReact } from 'highcharts-react-official'
import { format } from 'date-fns'
@@ -24,6 +24,24 @@ const WeatherDashboard = ({ data, currentData = [], rainData = [], timeRange = '
// State für Anleitung
const [showAnleitung, setShowAnleitung] = useState(false)
// Schwellwert für Datenlücken (abhängig vom Zeitraum)
const gapThresholdMs = useMemo(() => {
if (timeRange === '24h') return 2 * 60 * 60 * 1000 // 2 Stunden
return 1.5 * 24 * 3600 * 1000 // 1,5 Tage
}, [timeRange])
// Fügt null-Einträge in Lücken ein, damit Highcharts die Linie unterbricht
const withGaps = useCallback((pairs) => {
const result = []
for (let i = 0; i < pairs.length; i++) {
result.push(pairs[i])
if (i < pairs.length - 1 && pairs[i + 1][0] - pairs[i][0] > gapThresholdMs) {
result.push([(pairs[i][0] + pairs[i + 1][0]) / 2, null])
}
}
return result
}, [gapThresholdMs])
// State für benutzerdefinierten Zeitbereich
const [showCustomRangeModal, setShowCustomRangeModal] = useState(false)
const [customStartDate, setCustomStartDate] = useState('')
@@ -405,7 +423,7 @@ const WeatherDashboard = ({ data, currentData = [], rainData = [], timeRange = '
series: [
{
name: 'Maximaltemperatur',
data: sortedData.filter(item => item.max_temperature != null).map(item => [new Date(item.datetime).getTime(), item.max_temperature]),
data: withGaps(sortedData.filter(item => item.max_temperature != null).map(item => [new Date(item.datetime).getTime(), item.max_temperature])),
color: 'rgb(255, 99, 132)',
type: 'line',
lineWidth: 2,
@@ -419,7 +437,7 @@ const WeatherDashboard = ({ data, currentData = [], rainData = [], timeRange = '
},
{
name: 'Minimaltemperatur',
data: sortedData.filter(item => item.min_temperature != null).map(item => [new Date(item.datetime).getTime(), item.min_temperature]),
data: withGaps(sortedData.filter(item => item.min_temperature != null).map(item => [new Date(item.datetime).getTime(), item.min_temperature])),
color: 'rgb(54, 162, 235)',
type: 'line',
lineWidth: 2,
@@ -461,7 +479,7 @@ const WeatherDashboard = ({ data, currentData = [], rainData = [], timeRange = '
},
series: [{
name: 'Temperatur',
data: sortedData.filter(item => item.temperature != null).map(item => [new Date(item.datetime).getTime(), item.temperature]),
data: withGaps(sortedData.filter(item => item.temperature != null).map(item => [new Date(item.datetime).getTime(), item.temperature])),
color: 'rgb(255, 99, 132)',
fillColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
@@ -481,7 +499,7 @@ const WeatherDashboard = ({ data, currentData = [], rainData = [], timeRange = '
}
}]
}
}, [sortedData, temperatureSuffix, timeRange])
}, [sortedData, temperatureSuffix, timeRange, withGaps])
// Luftfeuchtigkeit Chart
const humidityOptions = useMemo(() => {
@@ -497,7 +515,7 @@ const WeatherDashboard = ({ data, currentData = [], rainData = [], timeRange = '
},
series: [{
name: 'Feuchte',
data: sortedData.filter(item => item.humidity != null).map(item => [new Date(item.datetime).getTime(), item.humidity]),
data: withGaps(sortedData.filter(item => item.humidity != null).map(item => [new Date(item.datetime).getTime(), item.humidity])),
color: 'rgb(54, 162, 235)',
fillColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
@@ -516,7 +534,7 @@ const WeatherDashboard = ({ data, currentData = [], rainData = [], timeRange = '
}
}]
}
}, [sortedData, timeRange])
}, [sortedData, timeRange, withGaps])
// Luftdruck Chart
const pressureOptions = useMemo(() => {
@@ -545,7 +563,7 @@ const WeatherDashboard = ({ data, currentData = [], rainData = [], timeRange = '
},
series: [{
name: 'Luftdruck',
data: sortedData.filter(item => item.pressure != null).map(item => [new Date(item.datetime).getTime(), item.pressure]),
data: withGaps(sortedData.filter(item => item.pressure != null).map(item => [new Date(item.datetime).getTime(), item.pressure])),
color: 'rgb(75, 192, 192)',
fillColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
@@ -564,7 +582,7 @@ const WeatherDashboard = ({ data, currentData = [], rainData = [], timeRange = '
}
}]
}
}, [sortedData, timeRange])
}, [sortedData, timeRange, withGaps])
// Regen Chart (angepasst an Zeitraum)
const rainOptions = useMemo(() => {
@@ -645,7 +663,7 @@ const WeatherDashboard = ({ data, currentData = [], rainData = [], timeRange = '
},
series
}
}, [sortedData, rainData, timeRange])
}, [sortedData, rainData, timeRange, withGaps])
// Windgeschwindigkeit Chart
const windSpeedOptions = useMemo(() => {
@@ -655,9 +673,9 @@ const WeatherDashboard = ({ data, currentData = [], rainData = [], timeRange = '
const hideGusts = (timeRange === '365d') || (isCustomRange && customDays >= 365)
const windSpeedSeries = {
name: 'Windgeschwindigkeit',
data: sortedData
data: withGaps(sortedData
.filter(item => item.wind_speed != null)
.map(item => [new Date(item.datetime).getTime(), item.wind_speed]),
.map(item => [new Date(item.datetime).getTime(), item.wind_speed])),
color: 'rgb(153, 102, 255)',
fillColor: 'rgba(153, 102, 255, 0.1)',
type: 'area',
@@ -674,9 +692,9 @@ const WeatherDashboard = ({ data, currentData = [], rainData = [], timeRange = '
? [windSpeedSeries]
: [windSpeedSeries, {
name: 'Böe' + windGustSuffix,
data: sortedData
data: withGaps(sortedData
.filter(item => item.wind_gust != null)
.map(item => [new Date(item.datetime).getTime(), item.wind_gust]),
.map(item => [new Date(item.datetime).getTime(), item.wind_gust])),
color: 'rgb(255, 100, 0)',
fillColor: 'rgba(255, 100, 0, 0.15)',
type: 'area',
@@ -716,7 +734,7 @@ const WeatherDashboard = ({ data, currentData = [], rainData = [], timeRange = '
},
series
}
}, [sortedData, timeRange, windGustSuffix])
}, [sortedData, timeRange, windGustSuffix, withGaps])
// Windrichtung Chart
const windDirOptions = useMemo(() => ({