second version

This commit is contained in:
Dusan Vojacek
2026-04-03 14:23:16 +02:00
parent 897b95f728
commit 9f4126946d
105 changed files with 9738 additions and 1470 deletions

View File

@@ -0,0 +1,90 @@
import { useEffect, useRef } from 'react'
import type { SlotData } from '../../types/dashboard'
type Props = {
slots: SlotData[]
nowIndex: number
chartPaddingLeft: number
chartPaddingRight: number
/** Pixely plot oblasti z EnergyChart (chartArea), pokud známe přesnější zarovnání. */
chartArea: { left: number; right: number } | null
}
const REGIME_STYLES: Record<
string,
{ bg: string; fg: string; bgPlan: string; fgPlan: string }
> = {
AUTO: { bg: '#1D9E7518', fg: '#0F6E56', bgPlan: '#1D9E7510', fgPlan: '#0F6E5699' },
SELF_SUSTAIN: { bg: '#E24B4A18', fg: '#993C1D', bgPlan: '#E24B4A10', fgPlan: '#993C1D99' },
CHARGE_CHEAP: { bg: '#EF9F2718', fg: '#854F0B', bgPlan: '#EF9F2710', fgPlan: '#854F0B99' },
PRESERVE: { bg: '#53B0AA18', fg: '#185FA5', bgPlan: '#53B0AA10', fgPlan: '#185FA599' },
MANUAL: { bg: '#88878018', fg: '#5F5E5A', bgPlan: '#88878010', fgPlan: '#5F5E5A99' },
}
const DEFAULT_STYLE = { bg: '#88878018', fg: '#5F5E5A', bgPlan: '#88878010', fgPlan: '#5F5E5A99' }
function normCode(code: string | null): string {
return (code ?? 'AUTO').toUpperCase().replace(/-/g, '_')
}
export function RegimeBar({ slots, nowIndex, chartPaddingLeft, chartPaddingRight, chartArea }: Props) {
const canvasRef = useRef<HTMLCanvasElement>(null)
useEffect(() => {
const canvas = canvasRef.current
if (!canvas || !slots.length) return
const ctx = canvas.getContext('2d')
if (!ctx) return
const dpr = window.devicePixelRatio || 1
const h = 28
const w = canvas.clientWidth || canvas.parentElement?.clientWidth || 300
canvas.width = Math.floor(w * dpr)
canvas.height = Math.floor(h * dpr)
canvas.style.height = `${h}px`
canvas.style.width = `${w}px`
ctx.setTransform(dpr, 0, 0, dpr, 0, 0)
const plotLeft = chartArea?.left ?? chartPaddingLeft
const plotRight = chartArea?.right ?? w - chartPaddingRight
const plotW = Math.max(1, plotRight - plotLeft)
const n = slots.length
const segW = plotW / n
ctx.clearRect(0, 0, w, h)
for (let i = 0; i < n; i++) {
const s = slots[i]!
const code = normCode(s.regime_code)
const st = REGIME_STYLES[code] ?? DEFAULT_STYLE
const planned = s.regime_is_planned
ctx.fillStyle = planned ? st.bgPlan : st.bg
const x0 = plotLeft + i * segW
ctx.fillRect(x0, 0, segW + 0.5, h)
}
if (nowIndex >= 0 && nowIndex < n) {
const x = plotLeft + nowIndex * segW
ctx.save()
ctx.strokeStyle = '#378ADD'
ctx.setLineDash([4, 3])
ctx.lineWidth = 1.5
ctx.beginPath()
ctx.moveTo(x, 0)
ctx.lineTo(x, h)
ctx.stroke()
ctx.restore()
}
}, [slots, nowIndex, chartPaddingLeft, chartPaddingRight, chartArea])
return (
<canvas
ref={canvasRef}
className="block w-full"
style={{ height: 28 }}
aria-hidden
height={28}
/>
)
}