fix graf v sql
Some checks failed
CI and deploy / migration-check (push) Failing after 9s
CI and deploy / deploy (push) Has been skipped

This commit is contained in:
Dusan Vojacek
2026-04-22 19:50:49 +02:00
parent faf948d75b
commit bd7d6a1b99
4 changed files with 41 additions and 17 deletions

View File

@@ -84,17 +84,19 @@ function DayChart({
strokeWidth={2}
dot={false}
connectNulls
isAnimationActive={false}
/>
{showForecast ? (
<Line
type="monotone"
dataKey="forecast_kw"
name="Předpověď"
stroke="#ef9f27"
stroke="#fbbf24"
strokeWidth={1.5}
dot={false}
connectNulls
strokeDasharray="5 4"
isAnimationActive={false}
/>
) : null}
{showCorrected ? (
@@ -102,11 +104,12 @@ function DayChart({
type="monotone"
dataKey="corrected_kw"
name="Korigovaná"
stroke="#ef9f27"
stroke="#fde68a"
strokeWidth={1.5}
dot={false}
connectNulls
strokeDasharray="2 3"
isAnimationActive={false}
/>
) : null}
</LineChart>
@@ -167,9 +170,15 @@ export default function ForecastVsActual() {
const byInterval = useMemo(() => {
const map = new Map<string, { tel?: Telemetry15mRow; pv?: ForecastPvSlotCorrectedRow; base?: BaselineLoadSlotRow }>()
for (const r of telemetry) map.set(r.slot_start, { ...(map.get(r.slot_start) ?? {}), tel: r })
for (const r of pvSlots) map.set(r.interval_start, { ...(map.get(r.interval_start) ?? {}), pv: r })
for (const r of baselineSlots) map.set(r.interval_start, { ...(map.get(r.interval_start) ?? {}), base: r })
for (const r of telemetry) {
map.set(r.slot_start, { ...(map.get(r.slot_start) ?? {}), tel: r })
}
for (const r of pvSlots) {
map.set(r.interval_start, { ...(map.get(r.interval_start) ?? {}), pv: r })
}
for (const r of baselineSlots) {
map.set(r.interval_start, { ...(map.get(r.interval_start) ?? {}), base: r })
}
return map
}, [telemetry, pvSlots, baselineSlots])
@@ -211,8 +220,11 @@ export default function ForecastVsActual() {
byDay.set(day, arr)
}
return [...byDay.entries()]
.sort((a, b) => a[0].localeCompare(b[0]))
.map(([day, points]) => ({ day, points }))
.sort((a, b) => b[0].localeCompare(a[0]))
.map(([day, points]) => ({
day,
points: points.sort((p, q) => new Date(p.k).getTime() - new Date(q.k).getTime()),
}))
}, [byInterval, metric])
const title = metric === 'pv' ? 'FVE (výroba)' : metric === 'load' ? 'Spotřeba (bazál)' : 'Síť (signed)'
@@ -270,6 +282,15 @@ export default function ForecastVsActual() {
</div>
)}
{siteReady && siteId != null ? (
<p className="text-xs text-slate-500">
Legenda: <span className="text-slate-200">plná šedá</span> = skutečnost z telemetrie (15m CA),{' '}
<span className="text-amber-200">čárkovaná žlutá</span> = předpověď (FVE: OpenMeteo/pvlib; spotřeba: baseline
z historie), <span className="text-yellow-100">tečkovaná světlá</span> = korigovaná FVE (delta profil z historie).
U sítě zatím nemáme samostatnou předpověď řady (jen skutečnost).
</p>
) : null}
{error ? (
<div className="rounded-xl border border-red-500/40 bg-red-950/40 px-4 py-3 text-sm text-red-200" role="alert">
{error}