import React, { useMemo } from 'react'; import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, } from 'recharts'; import { FeedSackLogEntry, ManualFeedSackEntry, FeedSackColumnConfig, } from '../../types/counting.ts'; interface FeedSackComparisonChartsProps { iotData: FeedSackLogEntry[]; manualEntries: ManualFeedSackEntry[]; cycleStartDate: Date; currentDay: number; columnConfig: FeedSackColumnConfig[]; } const FeedSackComparisonCharts: React.FC = ({ iotData, manualEntries, cycleStartDate, currentDay, columnConfig, }) => { // Aggregate data per camera const chartDataPerCamera = useMemo(() => { const cycleStart = new Date(cycleStartDate); cycleStart.setHours(0, 0, 0, 0); return columnConfig.map((col) => { const dailyMap = new Map(); // Process IOT data for this camera iotData.forEach((log) => { if (log.cameraName !== col.cameraName) return; const logDate = new Date(log.timestamp); logDate.setHours(0, 0, 0, 0); const dayNumber = Math.floor( (logDate.getTime() - cycleStart.getTime()) / (1000 * 60 * 60 * 24) ); if (dayNumber < 0 || dayNumber > currentDay) return; const dateKey = logDate.toISOString().split('T')[0]; if (!dailyMap.has(dateKey)) { dailyMap.set(dateKey, { date: logDate.toLocaleDateString('id-ID', { day: '2-digit', month: 'short', }), manual: 0, iot: 0, }); } const entry = dailyMap.get(dateKey)!; entry.iot += log.count; }); // Process manual data for this camera manualEntries.forEach((manual) => { if (manual.cameraName !== col.cameraName) return; const manualDate = new Date(manual.date); if (isNaN(manualDate.getTime())) return; manualDate.setHours(0, 0, 0, 0); const dateKey = manualDate.toISOString().split('T')[0]; if (!dailyMap.has(dateKey)) { dailyMap.set(dateKey, { date: manualDate.toLocaleDateString('id-ID', { day: '2-digit', month: 'short', }), manual: 0, iot: 0, }); } const entry = dailyMap.get(dateKey)!; entry.manual = manual.count; }); // Fill missing days const filled = []; for (let d = 0; d <= currentDay; d++) { const date = new Date(cycleStart); date.setDate(cycleStart.getDate() + d); const dateKey = date.toISOString().split('T')[0]; if (dailyMap.has(dateKey)) { filled.push(dailyMap.get(dateKey)!); } else { filled.push({ date: date.toLocaleDateString('id-ID', { day: '2-digit', month: 'short', }), manual: 0, iot: 0, }); } } return { camera: col, data: filled, }; }); }, [iotData, manualEntries, cycleStartDate, currentDay, columnConfig]); if (columnConfig.length === 0) { return null; } return (

Perbandingan Manual vs IOT per Kamera

{chartDataPerCamera.map(({ camera, data }) => { const hasData = data.some((d) => d.manual > 0 || d.iot > 0); return (

{camera.label}

{camera.cameraName}

{!hasData ? (

Belum ada data untuk kamera ini

) : (
{ if (dataMin === 0) return 0; return Math.floor(dataMin * 0.9); }, (dataMax: number) => Math.ceil(dataMax * 1.1), ]} tickFormatter={(value) => `${value}`} /> [ `${value} karung`, name === 'manual' ? 'Manual' : 'IOT', ]} /> (value === 'manual' ? 'Manual' : 'IOT')} />
)}
); })}
); }; export default FeedSackComparisonCharts;