"use client"; import { useMemo } from "react"; import { Bar, BarChart, CartesianGrid, Legend, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts"; import { formatChf } from "@/lib/format"; import type { PlanComputed } from "@/lib/calculations"; export const CHART_PALETTE = ["#4f46e5", "#0ea5e9", "#16a34a", "#d97706", "#dc2626", "#7c3aed"]; const ASSET_CATS = ["PENSION_FUND", "PILLAR_3A", "REAL_ESTATE", "OTHER_ASSET"]; // Gestapelte Vermögensaufteilung je Phase (Beginn und Ende). Eigene Komponente, weil sie // sowohl im Grafiken-Dialog als auch in der Live-Simulation gebraucht wird. export function AllocationChart({ computed, height = 288 }: { computed: PlanComputed; height?: number }) { // Asset-Elemente (nach id, damit gleiche Namen nicht kollidieren), die irgendwann einen // positiven Wert haben -- in Reihenfolge ihres ersten Auftretens. const assetEls = useMemo(() => { const info = new Map(); for (const phase of computed.phases) { for (const el of phase.elements) { if (!ASSET_CATS.includes(el.category)) continue; const cur = info.get(el.elementId) ?? { name: el.name, any: false }; cur.name = el.name; if (el.startValue > 0 || el.endValue > 0) cur.any = true; info.set(el.elementId, cur); } } return [...info.entries()].filter(([, v]) => v.any).map(([id, v]) => ({ id, name: v.name })); }, [computed]); // Je Phase zwei Kategorien auf der x-Achse: Beginn und Ende. const barData = useMemo( () => computed.phases.flatMap((phase) => { const beginn: Record = { label: `${phase.name} · Beginn` }; const ende: Record = { label: `${phase.name} · Ende` }; for (const el of phase.elements) { if (!ASSET_CATS.includes(el.category)) continue; beginn[el.elementId] = Math.max(0, Math.round(el.startValue)); ende[el.elementId] = Math.max(0, Math.round(el.endValue)); } return [beginn, ende]; }), [computed] ); if (assetEls.length === 0) { return

Dieser Plan enthält keine Vermögenselemente.

; } return (
Intl.NumberFormat("de-CH", { notation: "compact" }).format(v)} /> (typeof v === "number" ? formatChf(v) : v)} /> {assetEls.map((el, i) => ( ))}
); }