first commit
This commit is contained in:
commit
367533c02b
171 files changed
+101175
No files matched your search
@@ -0,0 +1,100 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import {
|
||||
BarChart,
|
||||
Bar,
|
||||
XAxis,
|
||||
YAxis,
|
||||
CartesianGrid,
|
||||
Tooltip,
|
||||
Legend,
|
||||
ResponsiveContainer,
|
||||
} from 'recharts';
|
||||
import type { Karung } from '../../types/api.ts';
|
||||
|
||||
interface FeedTrendChartProps {
|
||||
rows: Karung[];
|
||||
cycleStartDate: string;
|
||||
currentDay: number;
|
||||
}
|
||||
|
||||
const FeedTrendChart: React.FC<FeedTrendChartProps> = ({ rows, cycleStartDate, currentDay }) => {
|
||||
const chartData = useMemo(() => {
|
||||
const cycleStart = new Date(`${cycleStartDate}T00:00:00`);
|
||||
|
||||
const dailyData: { label: string; masuk: number; dituang: number }[] = [];
|
||||
for (let d = 0; d <= currentDay; d++) {
|
||||
const date = new Date(cycleStart);
|
||||
date.setDate(cycleStart.getDate() + d);
|
||||
dailyData.push({
|
||||
label: date.toLocaleDateString('id-ID', { day: '2-digit', month: 'short' }),
|
||||
masuk: 0,
|
||||
dituang: 0,
|
||||
});
|
||||
}
|
||||
|
||||
const byKey = new Map<string, { masuk: number; dituang: number }>();
|
||||
for (const row of rows) {
|
||||
const bucket = byKey.get(row.date) ?? { masuk: 0, dituang: 0 };
|
||||
bucket.masuk += row.in_today;
|
||||
bucket.dituang += row.out_today;
|
||||
byKey.set(row.date, bucket);
|
||||
}
|
||||
|
||||
for (let d = 0; d <= currentDay; d++) {
|
||||
const date = new Date(cycleStart);
|
||||
date.setDate(cycleStart.getDate() + d);
|
||||
const key = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(
|
||||
date.getDate()
|
||||
).padStart(2, '0')}`;
|
||||
const bucket = byKey.get(key);
|
||||
const entry = dailyData[d];
|
||||
if (bucket && entry) {
|
||||
entry.masuk = bucket.masuk;
|
||||
entry.dituang = bucket.dituang;
|
||||
}
|
||||
}
|
||||
|
||||
return dailyData;
|
||||
}, [rows, cycleStartDate, currentDay]);
|
||||
|
||||
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 IOT</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="label"
|
||||
fontSize={11}
|
||||
tick={{ fill: '#6b7280' }}
|
||||
angle={-45}
|
||||
textAnchor="end"
|
||||
height={70}
|
||||
/>
|
||||
<YAxis fontSize={12} tick={{ fill: '#6b7280' }} allowDecimals={false} />
|
||||
<Tooltip
|
||||
contentStyle={{
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.9)',
|
||||
border: '1px solid #ccc',
|
||||
borderRadius: '8px',
|
||||
}}
|
||||
formatter={(value: unknown, name: unknown) => [
|
||||
`${Number(value ?? 0)} karung`,
|
||||
name === 'masuk' ? 'Karung Masuk' : 'Karung Dituang',
|
||||
]}
|
||||
labelFormatter={(label) => `Tanggal: ${label}`}
|
||||
/>
|
||||
<Legend
|
||||
formatter={(value) => (value === 'masuk' ? 'Karung Masuk' : 'Karung Dituang')}
|
||||
/>
|
||||
<Bar dataKey="masuk" name="masuk" fill="#3b82f6" barSize={8} />
|
||||
<Bar dataKey="dituang" name="dituang" fill="#dc2626" barSize={8} />
|
||||
</BarChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FeedTrendChart;
|
||||
Reference in new issue
Block a user