import Card from '@/components/Card'; import { Dashboard, DashboardOverviewCharts, DashboardComparisonCharts, DashboardChartsSeries, DashboardChartsDataset, } from '@/types/api/dashboard/dashboard'; import { Icon } from '@iconify/react'; import { forwardRef, useImperativeHandle, useRef } from 'react'; import { CartesianGrid, Line, LineChart, ResponsiveContainer, XAxis, YAxis, } from 'recharts'; type DashboardExportChartsProps = { data: Dashboard; analysisMode: string; }; export type DashboardExportChartsRef = { getChartRefs: () => { key: string; ref: HTMLDivElement | null; label: string; }[]; }; // Type guard to check if charts is DashboardOverviewCharts function isOverviewCharts( charts: DashboardOverviewCharts | DashboardComparisonCharts | undefined ): charts is DashboardOverviewCharts { if (!charts) return false; return ( 'deplesi' in charts || 'body_weight' in charts || 'fcr' in charts || 'performance' in charts || 'quality_control' in charts ); } // Type guard to check if charts is DashboardComparisonCharts function isComparisonCharts( charts: DashboardOverviewCharts | DashboardComparisonCharts | undefined ): charts is DashboardComparisonCharts { if (!charts) return false; return 'farm' in charts || 'flock' in charts || 'kandang' in charts; } const lineColors: Record = { body_weight: '#10B981', std_body_weight: '#10B981', act_laying: '#1062B9', std_laying: '#1062B9', act_egg_weight: '#10B981', std_egg_weight: '#10B981', act_feed_intake: '#F52419', std_feed_intake: '#F52419', act_uniformity: '#F59E0B', std_uniformity: '#F59E0B', act_fcr: '#10B981', std_fcr: '#10B981', act_fcr_cum: '#F52419', std_fcr_cum: '#F52419', normal: '#10B981', abnormal: '#F52419', act_deplesi: '#10B981', std_deplesi: '#10B981', }; const defaultLineColors: string[] = [ '#10B981', '#1062B9', '#F52419', '#F59E0B', '#7F56D9', ]; // Helper function to get line color const getLineColor = (seriesId: string | number, index: number): string => { const predefinedColor = lineColors[seriesId]; if (predefinedColor) { return predefinedColor; } return defaultLineColors[index % defaultLineColors.length]; }; // Mapping for chart type labels const chartTypeLabels: Record = { body_weight: 'Body Weight', performance: 'Performance', fcr: 'FCR', quality_control: 'Quality Control', deplesi: 'Deplesi', }; const DashboardExportCharts = forwardRef< DashboardExportChartsRef, DashboardExportChartsProps >(({ data, analysisMode }, ref) => { // Create refs for charts - use string keys for flexibility const chartRefs = useRef<{ [key: string]: HTMLDivElement | null; }>({}); // Determine chart keys and labels based on analysis mode const getChartConfig = () => { if (analysisMode === 'OVERVIEW' && isOverviewCharts(data.charts)) { const overviewKeys: (keyof DashboardOverviewCharts)[] = [ 'body_weight', 'performance', 'fcr', 'quality_control', 'deplesi', ]; return overviewKeys.map((key) => ({ key, label: chartTypeLabels[key], chartData: (data.charts as DashboardOverviewCharts)[key], })); } else if ( analysisMode === 'COMPARISON' && isComparisonCharts(data.charts) ) { // For comparison mode, find which comparison type has data const comparisonKey = data.charts.farm ? 'farm' : data.charts.flock ? 'flock' : 'kandang'; const comparisonLabels: Record = { farm: 'Farm Comparison', flock: 'Flock Comparison', kandang: 'Kandang Comparison', }; return [ { key: comparisonKey, label: comparisonLabels[comparisonKey], chartData: data.charts[comparisonKey], }, ]; } return []; }; const chartConfig = getChartConfig(); // Expose method to get all chart refs useImperativeHandle(ref, () => ({ getChartRefs: () => { return chartConfig .map(({ key, label }) => ({ key, ref: chartRefs.current[key] || null, label, })) .filter((item) => item.ref !== null); }, })); return (
{chartConfig.map(({ key, label, chartData }) => { if ( !chartData || !chartData.dataset || chartData.dataset.length === 0 ) { return null; } const seriesData: DashboardChartsSeries[] = chartData.series || []; const dataset: DashboardChartsDataset[] = chartData.dataset || []; return (
{ chartRefs.current[key] = el; }} >
{label}{' '}
{/* Legend */}
{seriesData.map((series, index) => { const isStandard = series.id .toString() .toLowerCase() .includes('std'); return (
{series.label}
); })}
{/* Chart */} { const allValues: number[] = []; dataset.forEach((item: DashboardChartsDataset) => { seriesData.forEach((series) => { const value = item[series.id]; if (typeof value === 'number') { allValues.push(value); } }); }); if (allValues.length === 0) return [0, 100]; const minValue = Math.min(...allValues); const maxValue = Math.max(...allValues); const padding = (maxValue - minValue) * 0.1; const domainMin = Math.floor( Math.max(0, minValue - padding) ); const domainMax = Math.ceil(maxValue + padding); return [domainMin, domainMax]; })()} /> {seriesData.map((series, index) => { const isStandard = series.id .toString() .toLowerCase() .includes('std'); const dataKey = series.id.toString(); return ( ); })}
); })}
); }); DashboardExportCharts.displayName = 'DashboardExportCharts'; export default DashboardExportCharts;