Immer noch nicht richtig gut, also noch **WIP**
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
.dashboard {
|
||||
width: 100%;
|
||||
max-width: 1900px;
|
||||
/* max-width: 1900px; */
|
||||
max-width: 795px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,19 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
}
|
||||
}, [timeRange])
|
||||
|
||||
// Aggregations-Zusatz für Chart-Titel
|
||||
const aggregationSuffix = useMemo(() => {
|
||||
switch (timeRange) {
|
||||
case '7d':
|
||||
case '30d':
|
||||
return ' (Stundenmittel)'
|
||||
case '365d':
|
||||
return ' (Tagesmittel)'
|
||||
default:
|
||||
return ''
|
||||
}
|
||||
}, [timeRange])
|
||||
|
||||
// Gemeinsame Chart-Optionen (angepasst an Zeitraum)
|
||||
const getCommonOptions = () => {
|
||||
// X-Achsen-Konfiguration basierend auf Zeitraum
|
||||
@@ -46,20 +59,44 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
gridLineColor: 'rgba(0, 0, 0, 0.1)'
|
||||
}
|
||||
|
||||
// Zeitspanne für X-Achse berechnen (für festen Zeitrahmen)
|
||||
const now = new Date().getTime()
|
||||
let xAxisMin, xAxisMax
|
||||
|
||||
switch (timeRange) {
|
||||
case '24h':
|
||||
xAxisConfig.tickInterval = 4 * 3600 * 1000 // 4 Stunden
|
||||
xAxisConfig.labels = { format: '{value:%H:%M}', align: 'center' }
|
||||
xAxisMin = now - 24 * 3600 * 1000
|
||||
xAxisMax = now
|
||||
break
|
||||
case '7d':
|
||||
xAxisConfig.labels = { format: '{value:%d.%m}', align: 'center' }
|
||||
xAxisMin = now - 7 * 24 * 3600 * 1000
|
||||
xAxisMax = now
|
||||
break
|
||||
case '30d':
|
||||
xAxisConfig.labels = { format: '{value:%d.%m}', align: 'center' }
|
||||
xAxisMin = now - 30 * 24 * 3600 * 1000
|
||||
xAxisMax = now
|
||||
break
|
||||
case '365d':
|
||||
xAxisConfig.labels = { format: '{value:%b}', align: 'center' }
|
||||
xAxisConfig.labels = { format: '{value:%b %Y}', align: 'center' }
|
||||
// Bei 365d: Min/Max aus vorhandenen Daten berechnen
|
||||
if (sortedData.length > 0) {
|
||||
xAxisMin = new Date(sortedData[0].datetime).getTime()
|
||||
xAxisMax = new Date(sortedData[sortedData.length - 1].datetime).getTime()
|
||||
} else {
|
||||
xAxisMin = null
|
||||
xAxisMax = null
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
// Min/Max für X-Achse setzen
|
||||
xAxisConfig.min = xAxisMin
|
||||
xAxisConfig.max = xAxisMax
|
||||
|
||||
return {
|
||||
chart: {
|
||||
height: '50%',
|
||||
@@ -105,7 +142,7 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
|
||||
// Temperatur Chart
|
||||
const temperatureOptions = useMemo(() => {
|
||||
const temps = sortedData.map(item => item.temperature)
|
||||
const temps = sortedData.filter(item => item.temperature != null).map(item => item.temperature)
|
||||
const min = Math.min(...temps)
|
||||
const max = Math.max(...temps)
|
||||
const range = max - min
|
||||
@@ -129,7 +166,7 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
},
|
||||
series: [{
|
||||
name: 'Temperatur',
|
||||
data: sortedData.map(item => [new Date(item.datetime).getTime(), item.temperature]),
|
||||
data: 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 },
|
||||
@@ -140,12 +177,15 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
},
|
||||
type: 'areaspline',
|
||||
threshold: null,
|
||||
connectNulls: false,
|
||||
gapSize: 2 * 24 * 3600 * 1000,
|
||||
gapUnit: 'value',
|
||||
tooltip: {
|
||||
valueSuffix: ' °C'
|
||||
}
|
||||
}]
|
||||
}
|
||||
}, [sortedData])
|
||||
}, [sortedData, aggregationSuffix])
|
||||
|
||||
// Luftfeuchtigkeit Chart
|
||||
const humidityOptions = useMemo(() => ({
|
||||
@@ -158,7 +198,7 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
},
|
||||
series: [{
|
||||
name: 'Feuchte',
|
||||
data: sortedData.map(item => [new Date(item.datetime).getTime(), item.humidity]),
|
||||
data: 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 },
|
||||
@@ -168,6 +208,9 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
]
|
||||
},
|
||||
type: 'area',
|
||||
connectNulls: false,
|
||||
gapSize: 2 * 24 * 3600 * 1000,
|
||||
gapUnit: 'value',
|
||||
tooltip: {
|
||||
valueSuffix: ' %'
|
||||
}
|
||||
@@ -176,7 +219,7 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
|
||||
// Luftdruck Chart
|
||||
const pressureOptions = useMemo(() => {
|
||||
const pressures = sortedData.map(item => item.pressure)
|
||||
const pressures = sortedData.filter(item => item.pressure != null).map(item => item.pressure)
|
||||
const min = Math.min(...pressures)
|
||||
const max = Math.max(...pressures)
|
||||
const range = max - min
|
||||
@@ -200,7 +243,7 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
},
|
||||
series: [{
|
||||
name: 'Luftdruck',
|
||||
data: sortedData.map(item => [new Date(item.datetime).getTime(), item.pressure]),
|
||||
data: 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 },
|
||||
@@ -210,6 +253,9 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
]
|
||||
},
|
||||
type: 'area',
|
||||
connectNulls: false,
|
||||
gapSize: 2 * 24 * 3600 * 1000,
|
||||
gapUnit: 'value',
|
||||
tooltip: {
|
||||
valueSuffix: ' hPa'
|
||||
}
|
||||
@@ -227,7 +273,7 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
yAxisTitle = 'Regen (mm) / Rate (mm/h)'
|
||||
series = [{
|
||||
name: 'Regen',
|
||||
data: sortedData.map(item => [new Date(item.datetime).getTime(), item.rain]),
|
||||
data: sortedData.filter(item => item.rain != null).map(item => [new Date(item.datetime).getTime(), item.rain]),
|
||||
color: 'rgb(54, 162, 235)',
|
||||
fillColor: 'rgba(54, 162, 235, 0.3)',
|
||||
type: 'area',
|
||||
@@ -236,7 +282,7 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
}
|
||||
}, {
|
||||
name: 'Regenrate',
|
||||
data: sortedData.map(item => [new Date(item.datetime).getTime(), item.rain_rate]),
|
||||
data: sortedData.filter(item => item.rain_rate != null).map(item => [new Date(item.datetime).getTime(), item.rain_rate]),
|
||||
color: 'rgb(59, 130, 246)',
|
||||
dashStyle: 'Dash',
|
||||
type: 'line',
|
||||
@@ -249,7 +295,7 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
yAxisTitle = 'Regen (mm pro Tag)'
|
||||
series = [{
|
||||
name: 'Regen',
|
||||
data: rainData.map(item => [new Date(item.date).getTime(), item.total_rain || 0]),
|
||||
data: rainData.filter(item => item.total_rain != null && item.total_rain > 0).map(item => [new Date(item.date).getTime(), item.total_rain]),
|
||||
color: 'rgb(54, 162, 235)',
|
||||
type: 'column',
|
||||
tooltip: {
|
||||
@@ -261,7 +307,7 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
yAxisTitle = 'Regen (mm pro Woche)'
|
||||
series = [{
|
||||
name: 'Regen',
|
||||
data: rainData.map(item => [new Date(item.week_start).getTime(), item.total_rain || 0]),
|
||||
data: rainData.filter(item => item.total_rain != null && item.total_rain > 0).map(item => [new Date(item.week_start).getTime(), item.total_rain]),
|
||||
color: 'rgb(54, 162, 235)',
|
||||
type: 'column',
|
||||
tooltip: {
|
||||
@@ -281,48 +327,79 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
}, [sortedData, rainData, timeRange])
|
||||
|
||||
// Windgeschwindigkeit Chart
|
||||
const windSpeedOptions = useMemo(() => ({
|
||||
...getCommonOptions(),
|
||||
plotOptions: {
|
||||
series: {
|
||||
marker: {
|
||||
enabled: false
|
||||
const windSpeedOptions = useMemo(() => {
|
||||
// Bei 365d nur Windgeschwindigkeit, keine Böen
|
||||
const series = timeRange === '365d'
|
||||
? [{
|
||||
name: 'Windgeschwindigkeit',
|
||||
data: sortedData
|
||||
.filter(item => item.wind_speed != null)
|
||||
.map(item => [new Date(item.datetime).getTime(), item.wind_speed]),
|
||||
color: 'rgb(153, 102, 255)',
|
||||
fillColor: 'rgba(153, 102, 255, 0.1)',
|
||||
type: 'area',
|
||||
connectNulls: false,
|
||||
gapSize: 2 * 24 * 3600 * 1000,
|
||||
gapUnit: 'value',
|
||||
tooltip: {
|
||||
valueSuffix: ' km/h'
|
||||
}
|
||||
}]
|
||||
: [{
|
||||
name: 'Windgeschwindigkeit',
|
||||
data: sortedData
|
||||
.filter(item => item.wind_speed != null)
|
||||
.map(item => [new Date(item.datetime).getTime(), item.wind_speed]),
|
||||
color: 'rgb(153, 102, 255)',
|
||||
fillColor: 'rgba(153, 102, 255, 0.1)',
|
||||
type: 'area',
|
||||
connectNulls: false,
|
||||
gapSize: 2 * 24 * 3600 * 1000,
|
||||
gapUnit: 'value',
|
||||
tooltip: {
|
||||
valueSuffix: ' km/h'
|
||||
}
|
||||
}, {
|
||||
name: 'Windböen',
|
||||
data: sortedData
|
||||
.filter(item => item.wind_gust != null)
|
||||
.map(item => [new Date(item.datetime).getTime(), item.wind_gust]),
|
||||
color: 'rgb(255, 159, 64)',
|
||||
fillColor: 'rgba(255, 159, 64, 0.1)',
|
||||
type: 'area',
|
||||
connectNulls: false,
|
||||
gapSize: 2 * 24 * 3600 * 1000,
|
||||
gapUnit: 'value',
|
||||
tooltip: {
|
||||
valueSuffix: ' km/h'
|
||||
}
|
||||
}]
|
||||
|
||||
return {
|
||||
...getCommonOptions(),
|
||||
plotOptions: {
|
||||
series: {
|
||||
marker: {
|
||||
enabled: false
|
||||
},
|
||||
lineWidth: 2
|
||||
},
|
||||
lineWidth: 2
|
||||
},
|
||||
line: {
|
||||
step: 'left' // Keine Glättung
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
...getCommonOptions().yAxis,
|
||||
title: {
|
||||
text: 'Windspeed (km/h)',
|
||||
style: {
|
||||
whiteSpace: 'nowrap'
|
||||
line: {
|
||||
step: 'left' // Keine Glättung
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [{
|
||||
name: 'Windgeschwindigkeit',
|
||||
data: sortedData.map(item => [new Date(item.datetime).getTime(), item.wind_speed]),
|
||||
color: 'rgb(153, 102, 255)',
|
||||
fillColor: 'rgba(153, 102, 255, 0.1)',
|
||||
type: 'area',
|
||||
tooltip: {
|
||||
valueSuffix: ' km/h'
|
||||
}
|
||||
}, {
|
||||
name: 'Windböen',
|
||||
data: sortedData.map(item => [new Date(item.datetime).getTime(), item.wind_gust]),
|
||||
color: 'rgb(255, 159, 64)',
|
||||
fillColor: 'rgba(255, 159, 64, 0.1)',
|
||||
type: 'area',
|
||||
tooltip: {
|
||||
valueSuffix: ' km/h'
|
||||
}
|
||||
}]
|
||||
}), [sortedData])
|
||||
},
|
||||
yAxis: {
|
||||
...getCommonOptions().yAxis,
|
||||
title: {
|
||||
text: 'Windspeed (km/h)',
|
||||
style: {
|
||||
whiteSpace: 'nowrap'
|
||||
}
|
||||
}
|
||||
},
|
||||
series
|
||||
}
|
||||
}, [sortedData, timeRange])
|
||||
|
||||
// Windrichtung Chart
|
||||
const windDirOptions = useMemo(() => ({
|
||||
@@ -359,7 +436,7 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
},
|
||||
series: [{
|
||||
name: 'Windrichtung',
|
||||
data: sortedData.map(item => [new Date(item.datetime).getTime(), item.wind_dir]),
|
||||
data: sortedData.filter(item => item.wind_dir != null).map(item => [new Date(item.datetime).getTime(), item.wind_dir]),
|
||||
color: 'rgb(54, 162, 235)',
|
||||
type: 'scatter',
|
||||
tooltip: {
|
||||
@@ -465,7 +542,7 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
{/* Charts Grid */}
|
||||
<div className="charts-grid">
|
||||
<div className="chart-container">
|
||||
<h3>🌡️ Temperatur - Aktuell: {current.temperature?.toFixed(1) || '-'}°C</h3>
|
||||
<h3>🌡️ Temperatur{aggregationSuffix} - Aktuell: {current.temperature?.toFixed(1) || '-'}°C</h3>
|
||||
<div className="chart-wrapper">
|
||||
<HighchartsReact highcharts={Highcharts} options={temperatureOptions} />
|
||||
</div>
|
||||
@@ -475,7 +552,7 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
</div>
|
||||
|
||||
<div className="chart-container">
|
||||
<h3>🌐 Luftdruck - Aktuell: {current.pressure?.toFixed(1) || '-'} hPa</h3>
|
||||
<h3>🌐 Luftdruck{aggregationSuffix} - Aktuell: {current.pressure?.toFixed(1) || '-'} hPa</h3>
|
||||
<div className="chart-wrapper">
|
||||
<HighchartsReact highcharts={Highcharts} options={pressureOptions} />
|
||||
</div>
|
||||
@@ -485,7 +562,7 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
</div>
|
||||
|
||||
<div className="chart-container">
|
||||
<h3>💧 Luftfeuchtigkeit - Aktuell: {current.humidity || '-'}%</h3>
|
||||
<h3>💧 Luftfeuchtigkeit{aggregationSuffix} - Aktuell: {current.humidity || '-'}%</h3>
|
||||
<div className="chart-wrapper">
|
||||
<HighchartsReact highcharts={Highcharts} options={humidityOptions} />
|
||||
</div>
|
||||
@@ -495,21 +572,21 @@ const WeatherDashboard = ({ data, rainData = [], timeRange = '24h', onTimeRangeC
|
||||
</div>
|
||||
|
||||
<div className="chart-container">
|
||||
<h3>🌧️ Regen - Aktuell: {current.rain?.toFixed(1) || '-'} mm</h3>
|
||||
<h3>🌧️ Regen{aggregationSuffix} - Aktuell: {current.rain?.toFixed(1) || '-'} mm</h3>
|
||||
<div className="chart-wrapper">
|
||||
<HighchartsReact highcharts={Highcharts} options={rainOptions} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="chart-container">
|
||||
<h3>🧭 Windrichtung - Aktuell: {current.wind_dir ?? '-'}°</h3>
|
||||
<h3>🧭 Windrichtung{aggregationSuffix} - Aktuell: {current.wind_dir ?? '-'}°</h3>
|
||||
<div className="chart-wrapper">
|
||||
<HighchartsReact highcharts={Highcharts} options={windDirOptions} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="chart-container">
|
||||
<h3>💨 Windspeed - Aktuell: {current.wind_speed?.toFixed(1) || '-'} km/h</h3>
|
||||
<h3>💨 Windspeed{aggregationSuffix} - Aktuell: {current.wind_speed?.toFixed(1) || '-'} km/h</h3>
|
||||
<div className="chart-wrapper">
|
||||
<HighchartsReact highcharts={Highcharts} options={windSpeedOptions} />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user