Files
dashboard/components/feedSack/FeedTrendChart.tsx
T
2026-07-29 10:48:03 +07:00

111 lines
3.4 KiB
TypeScript

import React, { useMemo } from 'react';
import {
BarChart,
Bar,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
ResponsiveContainer,
} from 'recharts';
import { FeedSackLogEntry, FeedSackColumnConfig } from '../../types/counting.ts';
interface FeedTrendChartProps {
data: FeedSackLogEntry[];
cycleStartDate: Date;
currentDay: number;
columnConfig: FeedSackColumnConfig[];
}
const FeedTrendChart: React.FC<FeedTrendChartProps> = ({
data,
cycleStartDate,
currentDay,
columnConfig,
}) => {
const cameraNames = useMemo(() => columnConfig.map((c) => c.cameraName), [columnConfig]);
const chartData = useMemo(() => {
const cycleStart = new Date(cycleStartDate);
cycleStart.setHours(0, 0, 0, 0);
const cycleEnd = new Date(cycleStart);
cycleEnd.setDate(cycleStart.getDate() + currentDay);
cycleEnd.setHours(23, 59, 59, 999);
// Initialize daily buckets
const dailyData: { [key: number]: Record<string, any> } = {};
for (let d = 0; d <= currentDay; d++) {
const date = new Date(cycleStart);
date.setDate(cycleStart.getDate() + d);
const formattedDate = date.toLocaleDateString('id-ID', { day: '2-digit', month: 'short' });
const entry: Record<string, any> = { day: `H${d}`, date: formattedDate };
cameraNames.forEach((name) => {
entry[name] = 0;
});
dailyData[d] = entry;
}
// Aggregate data by day
data.forEach((log) => {
if (log.timestamp >= cycleStart && log.timestamp <= cycleEnd) {
const diffTime = log.timestamp.getTime() - cycleStart.getTime();
const dayNumber = Math.floor(diffTime / (1000 * 60 * 60 * 24));
if (dayNumber >= 0 && dayNumber <= currentDay && dailyData[dayNumber]) {
if (log.cameraName && cameraNames.includes(log.cameraName)) {
dailyData[dayNumber][log.cameraName] += log.count;
}
}
}
});
return Object.values(dailyData);
}, [data, cycleStartDate, currentDay, cameraNames]);
return (
<div className="bg-white p-6 rounded-xl shadow-sm">
<h2 className="text-xl font-bold text-gray-800 mb-4">Tren Harian Karung Pakan</h2>
<div className="h-60">
<ResponsiveContainer width="100%" height="100%">
<BarChart data={chartData} margin={{ top: 5, right: 20, left: -15, bottom: 5 }}>
<CartesianGrid strokeDasharray="3 3" stroke="#e0e0e0" />
<XAxis
dataKey="date"
fontSize={11}
tick={{ fill: '#6b7280' }}
angle={-45}
textAnchor="end"
height={70}
/>
<YAxis fontSize={12} tick={{ fill: '#6b7280' }} />
<Tooltip
contentStyle={{
backgroundColor: 'rgba(255, 255, 255, 0.9)',
border: '1px solid #ccc',
borderRadius: '8px',
}}
formatter={(value: number) => [`${value} karung`]}
labelFormatter={(label) => `Tanggal: ${label}`}
/>
<Legend />
{columnConfig.map((col) => (
<Bar
key={col.id}
dataKey={col.cameraName}
name={col.label}
fill={col.color}
barSize={8}
/>
))}
</BarChart>
</ResponsiveContainer>
</div>
</div>
);
};
export default FeedTrendChart;