import React, { useMemo } from 'react'; import { CartesianGrid, ComposedChart, Line, ResponsiveContainer, Tooltip, XAxis, YAxis, } from 'recharts'; import type { ChickenWeight } from '../../types/api.ts'; import { formatDateId } from '../../utils/format.ts'; import { formatWeight, getTargetWeightForAge } from '../../utils/weight.ts'; interface DailyWeightProgressionChartProps { rows: ChickenWeight[]; docWeight: number; } type ChartPoint = { day: number; date: string; actual: number | null; target: number | null; chickenCount: number; }; const DailyWeightProgressionChart: React.FC = ({ rows, docWeight, }) => { const chartData = useMemo( () => [...rows].reverse().map((row) => ({ day: row.age, date: row.date, actual: row.average_weight, target: getTargetWeightForAge(row.age, docWeight), chickenCount: row.chicken_count, })), [rows, docWeight] ); const hasNoData = chartData.length === 0; const CustomTooltip = ({ active, payload, }: { active?: boolean; payload?: Array<{ payload: ChartPoint }>; }) => { if (!active || !payload?.length) return null; const point = payload[0]?.payload; if (!point || point.actual == null) return null; const deviation = point.target != null ? point.actual - point.target : null; return (

Hari ke-{point.day}

{formatDateId(point.date)}

Aktual:{' '} {formatWeight(point.actual, { stripTrailingZeros: true })}

Target:{' '} {formatWeight(point.target, { stripTrailingZeros: true })}

{point.chickenCount > 0 && (

Ayam: {point.chickenCount} ekor

)} {deviation != null && (

Deviasi:{' '} = 0 ? 'text-green-600' : 'text-orange-600'}> {deviation >= 0 ? '+' : ''} {formatWeight(Math.abs(deviation), { stripTrailingZeros: true })}

)}
); }; return (

Grafik Berat Aktual vs Target

{hasNoData ? (

Tidak ada data tersedia

Data berat belum tersedia untuk periode ini

) : ( formatWeight(value, { stripTrailingZeros: true })} /> } /> )}
{!hasNoData && (
Berat Aktual
Target Standar
)}
); }; export default DailyWeightProgressionChart;