import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid, } from 'recharts' import dayjs from 'dayjs' import 'dayjs/locale/de' dayjs.locale('de') function rollingAvg(arr, key, w = 7) { return arr.map((d, i) => { const s = arr .slice(Math.max(0, i - w + 1), i + 1) .map((x) => x[key]) .filter((v) => v != null) return s.length ? { ...d, [`${key}_avg`]: Math.round((s.reduce((a, b) => a + b) / s.length) * 10) / 10, } : d }) } /** * Kalorien + Gewicht im Zeitfenster (wie Dashboard-Trends). * @param {{ weights: any[], nutrition: any[], windowDays?: number }} props */ export default function TrendKcalWeightChart({ weights, nutrition, windowDays = 30 }) { const n = Math.max(7, Math.min(90, Number(windowDays) || 30)) const days = [] for (let i = n - 1; i >= 0; i--) days.push(dayjs().subtract(i, 'day').format('YYYY-MM-DD')) const wMap = {} ;(weights || []).forEach((w) => { wMap[w.date] = w.weight }) const nMap = {} ;(nutrition || []).forEach((x) => { nMap[x.date] = Math.round(x.kcal || 0) }) let lastW = null const combined = days .map((date) => { if (wMap[date]) lastW = wMap[date] return { date: dayjs(date).format('DD.MM'), kcal: nMap[date] || null, weight: wMap[date] || null, weightLine: lastW, } }) .filter((d) => d.kcal || d.weightLine) const withAvg = rollingAvg(combined, 'kcal') const hasKcal = combined.some((d) => d.kcal) const hasW = combined.some((d) => d.weightLine) if (!hasKcal && !hasW) { return (
Mehr Ernährungs- und Gewichtsdaten für den Chart nötig
) } return ( {hasKcal && ( )} {hasW && ( )} [ v == null ? '–' : `${Math.round(v)} ${name === 'weightLine' || name === 'weight' ? 'kg' : 'kcal'}`, name === 'kcal_avg' ? 'Ø Kalorien (7T)' : name === 'kcal' ? 'Kalorien' : name === 'weightLine' ? 'Gewicht (interpoliert)' : 'Gewicht Messung', ]} /> {hasKcal && ( )} {hasKcal && ( )} {hasW && ( )} {hasW && ( { const { cx, cy, value } = props return value != null ? ( ) : ( ) }} connectNulls={false} name="weight" /> )} ) }