diff --git a/web/src/dashboard/cards.jsx b/web/src/dashboard/cards.jsx
index 58ef4ba..df25077 100644
--- a/web/src/dashboard/cards.jsx
+++ b/web/src/dashboard/cards.jsx
@@ -462,14 +462,16 @@ function KarteAblaufRing() {
);
}
-function KarteKategorienRing() {
+function KarteKategorienRing({ props: karteProps }) {
const { daten, fehler } = useDaten(() => api.dashboardByCategory());
if (fehler) return
{fehler}
;
if (!daten) return Lädt…
;
+ // Detailansicht: jede Kategorie einzeln statt der Bündelung zu „Andere“.
const segmente = mitFarben(
daten.map((k) => ({ name: k.name, value: k.article_units })),
istDunkel(),
+ { alle: !!karteProps?.detail },
);
return ;
}
@@ -687,6 +689,7 @@ export const KARTEN = {
titel: "Kategorien-Anteile", icon: "tag", vorschau: "ring",
beschreibung: "Ring: welche Kategorie wie viel ausmacht",
standard: { w: 4, h: 6 }, min: { w: 3, h: 5 },
+ config: [{ key: "detail", type: "boolean", label: "Detailansicht (alle Kategorien einzeln, keine Gruppe „Andere“)" }],
komponente: KarteKategorienRing,
},
"category-bars": {
diff --git a/web/src/dashboard/palette.js b/web/src/dashboard/palette.js
index 10c5c92..24ccff7 100644
--- a/web/src/dashboard/palette.js
+++ b/web/src/dashboard/palette.js
@@ -58,13 +58,36 @@ export function andereFarbe(dunkel) {
}
/**
- * Bündelt eine sortierte Liste auf SERIES_MAX Einträge plus „Andere“ und
- * vergibt die Farben in fester Reihenfolge.
- * Erwartet Objekte mit { name, value }.
+ * Zusätzliche Farben für die Detailansicht (mehr Kategorien als die geprüfte
+ * Palette hat). Bewusst nur für den Detail-Fall: gleichmäßig verteilte Farbtöne
+ * (Goldener Winkel) statt der farbfehlsicht-geprüften Festfarben.
*/
-export function mitFarben(eintraege, dunkel) {
+function extraFarben(anzahl, dunkel) {
+ const s = dunkel ? 62 : 66;
+ const l = dunkel ? 58 : 46;
+ return Array.from({ length: anzahl }, (_, j) => {
+ const ton = Math.round((28 + j * 137.508) % 360);
+ return `hsl(${ton}, ${s}%, ${l}%)`;
+ });
+}
+
+/**
+ * Vergibt Farben für eine sortierte Anteilsliste (Objekte mit { name, value }).
+ *
+ * Standard: höchstens SERIES_MAX Einträge in fester Reihenfolge, der Rest zu
+ * „Andere“ gebündelt. Mit `alle` (Detailansicht) bekommt JEDE Kategorie eine
+ * eigene Farbe (Festpalette vorne, danach erzeugte Töne) – ohne „Andere“.
+ */
+export function mitFarben(eintraege, dunkel, { alle = false } = {}) {
const farben = kategorieFarben(dunkel);
const sortiert = [...eintraege].sort((a, b) => b.value - a.value);
+ if (alle) {
+ const extra = extraFarben(Math.max(0, sortiert.length - farben.length), dunkel);
+ return sortiert.map((e, i) => ({
+ ...e,
+ color: i < farben.length ? farben[i] : extra[i - farben.length],
+ }));
+ }
const vorne = sortiert.slice(0, SERIES_MAX).map((e, i) => ({ ...e, color: farben[i] }));
const rest = sortiert.slice(SERIES_MAX);
if (rest.length === 0) return vorne;