Der User: „Viel zu dünn. Und den Graphen kann ja kein Mensch lesen.“ Vorher drei Balken und ein winziges Stunden-Histogramm ohne lesbare Achsen, halb so breit neben dem Radar. - Eigene Ansicht views/ModellNutzung.tsx in voller Breite (Radar darunter, ebenfalls volle Breite). - Kennzahlen: Anfragen mit Schnitt je vollem Tag, heute/gestern, typische Antwort mit „9 von 10 bis“, Fehler (ab 1 % bernstein, ab 5 % rot, immer mit Wort dazu, nie nur Farbe). - Tabelle je Absender: Anfragen mit Anteil-Balken, Antwortzeiten, Rechenzeit mit Anteil (NerdQuiz stellt 92 % der Anfragen, aber nur 75 % der Rechenzeit), Fehler in Worten („Modell nicht erreichbar (502)“), letzte Anfrage. Schmal als Karten mit Beschriftung. - Neuer Baustein components/diagramme/Saeulen.tsx für „je Tag (7 Tage)“ und „je Stunde (24 h)“: gestapelt je Absender, glatte y-Achse, Wochentag/Datum bzw. Uhrzeit an der x-Achse (Stunden ausgedünnt auf 3 bzw. 6 h), Legende, Summen auf den Tagessäulen (bei den Stunden nur die höchste), Anzeige per Zeiger, Finger und Pfeiltasten, darunter „Werte als Tabelle“. Auf dem Handy steht die Anzeige unter dem Diagramm, sonst verdeckte sie das halbe Bild. Säulen höchstens 24 px, 2 px Luft zwischen den Stücken statt Rändern. - Farben: neue Tokens --reihe-3 (Gelb) und --reihe-weitere (Grau; ab der vierten Farbe fasst „Weitere“ zusammen). Mit dem Paletten-Prüfer gegen #15181b gemessen: jedes Paar auch bei Rot-Grün-Schwäche getrennt. Türkis fiel durch (neben Magenta bei Grünschwäche ΔE 1,6), Violett gleicht der KI-Box-Farbe. Die Farbe folgt dem Absender (feste Reihe der Box), nicht dem Rang. - „Wann welches Modell geladen wurde“ eingeklappt darunter: Anzahl, zuletzt, davor — mit Rolle (Hirn, Coder, Bild-Zwilling) statt nur Dateiname. - useBreite aus Verlauf.tsx nach lib/breite.ts, damit beide Diagramme ihn teilen. - Ältere Stände der Box ohne die neuen Felder zeigen weiter Anzahlen und Verläufe, Zeiten als „–“ — die Homelab-Instanz fragt über den Partner und kann einen anderen Stand haben. frontend/dist ist bewusst nicht gebaut (kommt beim Zusammenführen). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
59 lines
2.7 KiB
TypeScript
59 lines
2.7 KiB
TypeScript
import { fireEvent, render, screen, within } from "@testing-library/react"
|
|
import type { Saeule } from "@/lib/diagramm"
|
|
import { Saeulen } from "./Saeulen"
|
|
|
|
const REIHEN = [{ name: "A", farbe: "var(--reihe-1)" }, { name: "B", farbe: "var(--reihe-2)" }, { name: "C", farbe: "var(--reihe-3)" }]
|
|
|
|
const stunden = Array.from({ length: 24 }, (_, i): Saeule => {
|
|
const h = (15 + i) % 24
|
|
return {
|
|
schluessel: String(i), achse: `${String(h).padStart(2, "0")}:00`, raster: h, lang: `${h} Uhr`,
|
|
werte: h === 3 ? { A: 139 } : { A: 5, B: i % 2 },
|
|
}
|
|
})
|
|
|
|
/** Der Behälter meldet eine feste Breite, wie ein Handy (jsdom kennt keinen ResizeObserver). */
|
|
function breiteVortaeuschen(px: number) {
|
|
vi.stubGlobal("ResizeObserver", class {
|
|
constructor(private melden: (e: { contentRect: { width: number } }[]) => void) {}
|
|
observe() { this.melden([{ contentRect: { width: px } }]) }
|
|
disconnect() {}
|
|
})
|
|
}
|
|
|
|
afterEach(() => vi.unstubAllGlobals())
|
|
|
|
describe("Saeulen", () => {
|
|
it("dünnt die Stundenbeschriftung aus und nennt nur die höchste Summe", () => {
|
|
const { container } = render(<Saeulen saeulen={stunden} reihen={REIHEN} titel="Je Stunde" summen="hoechste" />)
|
|
const texte = [...container.querySelectorAll("svg text")].map((t) => t.textContent)
|
|
expect(texte).toEqual(expect.arrayContaining(["15:00", "18:00", "00:00", "03:00", "139"]))
|
|
expect(texte).not.toContain("16:00")
|
|
expect(texte.filter((t) => t === "6")).toHaveLength(0) // die übrigen Summen stehen nur in Anzeige und Tabelle
|
|
})
|
|
|
|
it("zeigt in der Legende nur Reihen mit Werten", () => {
|
|
render(<Saeulen saeulen={stunden} reihen={REIHEN} titel="Je Stunde" />)
|
|
expect(within(screen.getByRole("list", { name: "Legende" })).getAllByRole("listitem").map((l) => l.textContent))
|
|
.toEqual(["A", "B"])
|
|
})
|
|
|
|
it("stellt die Anzeige auf dem Handy unter das Diagramm statt darüber", () => {
|
|
breiteVortaeuschen(300)
|
|
render(<Saeulen saeulen={stunden} reihen={REIHEN} titel="Je Stunde" />)
|
|
const bild = screen.getByRole("img", { name: "Je Stunde" })
|
|
expect(bild).toHaveAttribute("width", "300")
|
|
fireEvent.focus(bild)
|
|
const anzeige = screen.getByRole("status")
|
|
expect(anzeige).not.toHaveClass("absolute")
|
|
expect(anzeige).toHaveTextContent("14 Uhr")
|
|
expect(bild.compareDocumentPosition(anzeige) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy()
|
|
})
|
|
|
|
it("sagt es, wenn es nichts zu zeigen gibt", () => {
|
|
render(<Saeulen saeulen={[{ schluessel: "x", achse: "Sa", lang: "Samstag", werte: {} }]} reihen={REIHEN} titel="Leer" />)
|
|
expect(screen.getByText("Keine Anfragen in diesem Zeitraum")).toBeInTheDocument()
|
|
expect(screen.queryByRole("list", { name: "Legende" })).not.toBeInTheDocument()
|
|
})
|
|
})
|