import type { CSSProperties } from "react" import { cn } from "cn" import type { Bereich } from "@/lib/navigation" import { type Einheit, wertText } from "@/lib/messung" import type { Messpunkt } from "@/lib/typen" import { Sparkline } from "./Sparkline" // Ein Messwert als Ring (Design v5, 25.09.2026): der Bogen füllt sich bis zum Wert, im Normalfall in der Farbe des // Bereichs, ab der gelben Grenze bernstein, ab der roten rot — dazu das Wort („hoch“, „kritisch“), damit es nicht // nur an der Farbe hängt. Zwei feine Striche am Rand zeigen, wo die Grenzen liegen; darunter die Linie der Stunde. const ZUSTAND = { ruhig: { wert: "text-foreground", marke: null }, gelb: { wert: "text-bernstein", marke: "hoch" }, rot: { wert: "text-rot-text", marke: "kritisch" }, } as const const MITTE = 48 const RADIUS = 37 const UMFANG = 2 * Math.PI * RADIUS const BOGEN = UMFANG * 0.75 /** Punkt auf dem Rand für einen Anteil 0…1 des 270°-Bogens (Beginn unten links, im Uhrzeigersinn). */ function randpunkt(anteil: number, r: number) { const winkel = ((135 + 270 * anteil) * Math.PI) / 180 return { x: MITTE + r * Math.cos(winkel), y: MITTE + r * Math.sin(winkel) } } export function Messring({ label, wert, einheit, punkte, zustand = "ruhig", bereich, grenzen, max = 100, zeitraumText, i = 0 }: { label: string wert: number | null | undefined einheit: Einheit punkte?: Messpunkt[] zustand?: keyof typeof ZUSTAND bereich: Bereich /** Gelbe und rote Grenze in der Einheit des Werts. */ grenzen: [number, number] max?: number zeitraumText: string /** Reihenfolge für das Auftauchen. */ i?: number }) { const z = ZUSTAND[zustand] const farbe = zustand === "rot" ? "var(--rot)" : zustand === "gelb" ? "var(--bernstein)" : bereich === "box" ? "var(--box)" : "var(--lab)" const anteil = wert == null ? 0 : Math.min(Math.max(wert / max, 0), 1) const [zahl, einheitText] = wertText(wert, einheit).split(" ") return (
{grenzen.map((g, n) => { const a = randpunkt(Math.min(g / max, 1), RADIUS + 6) const b = randpunkt(Math.min(g / max, 1), RADIUS + 9.5) return })} {wert != null && anteil > 0 && ( )} {zahl} {einheitText && {einheitText}}
{label} {z.marke && · {z.marke}}
{punkte && punkte.length > 1 ? : }
) }