From 606c1047f67c9db54ba474247367f6111ad71308 Mon Sep 17 00:00:00 2001 From: Syasya Date: Thu, 31 Jul 2025 13:59:09 +0800 Subject: [PATCH] update monthlybarchart to extract from db --- app/(admin)/adminDashboard/page.tsx | 2 +- components/dashboards/MonthlyBarChart.tsx | 186 ++++++++++++++-------- 2 files changed, 117 insertions(+), 71 deletions(-) diff --git a/app/(admin)/adminDashboard/page.tsx b/app/(admin)/adminDashboard/page.tsx index 989a10a..244aa57 100644 --- a/app/(admin)/adminDashboard/page.tsx +++ b/app/(admin)/adminDashboard/page.tsx @@ -194,7 +194,7 @@ const AdminDashboard = () => {
- +
diff --git a/components/dashboards/MonthlyBarChart.tsx b/components/dashboards/MonthlyBarChart.tsx index f771363..542312c 100644 --- a/components/dashboards/MonthlyBarChart.tsx +++ b/components/dashboards/MonthlyBarChart.tsx @@ -1,93 +1,139 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { - BarChart, - Bar, - XAxis, - YAxis, - Tooltip, - ResponsiveContainer, - Legend, + BarChart, + Bar, + XAxis, + YAxis, + Tooltip, + ResponsiveContainer, + Legend, } from 'recharts'; -import { SiteDetails } from '@/types/SiteData'; +import { format } from 'date-fns'; +import { fetchPowerTimeseries } from '@/app/utils/api'; interface MonthlyBarChartProps { - siteData: SiteDetails | null; + siteId: string; } +interface TimeSeriesEntry { + time: string; + value: number; +} + +const groupTimeSeries = ( + data: TimeSeriesEntry[], + mode: 'monthly' +): TimeSeriesEntry[] => { + const groupMap = new Map(); + + for (const entry of data) { + const date = new Date(entry.time); + const key = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`; + if (!groupMap.has(key)) groupMap.set(key, []); + groupMap.get(key)!.push(entry.value); + } + + return Array.from(groupMap.entries()).map(([time, values]) => ({ + time, + value: values.reduce((sum, v) => sum + v, 0), + })); +}; + const consumptionColor = '#003049'; const generationColor = '#669bbc'; -// Month names for X-axis labels -const MONTHS = [ - 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', -]; +const MonthlyBarChart: React.FC = ({ siteId }) => { + const [chartData, setChartData] = useState< + { month: string; consumption: number; generation: number }[] + >([]); + const [loading, setLoading] = useState(true); -const MonthlyBarChart: React.FC = ({ siteData }) => { - const chartData = React.useMemo(() => { - if ( - !siteData || - siteData.consumptionData.length === 0 || - siteData.generationData.length === 0 - ) { - return []; + useEffect(() => { + if (!siteId) return; + + const fetchMonthlyData = async () => { + setLoading(true); + const start = '2025-01-01T00:00:00+08:00'; + const end = '2025-12-31T23:59:59+08:00'; + + try { + const res = await fetchPowerTimeseries(siteId, start, end); + + const groupedConsumption = groupTimeSeries(res.consumption, 'monthly'); + const groupedGeneration = groupTimeSeries(res.generation, 'monthly'); + + const monthMap = new Map(); + + for (const entry of groupedConsumption) { + if (!monthMap.has(entry.time)) { + monthMap.set(entry.time, { consumption: 0, generation: 0 }); + } + monthMap.get(entry.time)!.consumption = entry.value; } - // Initialize totals - const monthlyData = Array.from({ length: 12 }, (_, month) => ({ - month: MONTHS[month], - consumption: 0, - generation: 0, - })); - - // Group daily data into months (assume data is in order from Jan 1 to Dec 31) - // Group daily data into months (assume data is in order from Jan 1 to Dec 31) - for (let i = 0; i < siteData.consumptionData.length; i++) { - const monthIndex = Math.floor(i / 30.42); // Rough approximation - if (monthIndex < 12) { - monthlyData[monthIndex].consumption += siteData.consumptionData[i]; - monthlyData[monthIndex].generation += siteData.generationData[i]; - } + for (const entry of groupedGeneration) { + if (!monthMap.has(entry.time)) { + monthMap.set(entry.time, { consumption: 0, generation: 0 }); + } + monthMap.get(entry.time)!.generation = entry.value; } - // ✅ Only return the last 6 months - return monthlyData.slice(-6); + const formatted = Array.from(monthMap.entries()) + .sort(([a], [b]) => a.localeCompare(b)) + .map(([key, val]) => ({ + month: format(new Date(`${key}-01`), 'MMM'), + consumption: val.consumption, + generation: val.generation, + })); - }, [siteData]); + setChartData(formatted.slice(-6)); // last 6 months + } catch (error) { + console.error('Failed to fetch monthly power data:', error); + setChartData([]); + } finally { + setLoading(false); + } + }; - if (!siteData || chartData.length === 0) { - return ( -
-
-

Monthly Energy Yield

-
-
-

No data available for chart. Please select a site.

-
-
- ); - } + fetchMonthlyData(); + }, [siteId]); + if (loading || !siteId || chartData.length === 0) { return ( -
-
-

Monthly Energy Yield

-
- -
- - - - - - - - - - -
+
+
+

Monthly Energy Yield

+
+

+ {loading ? 'Loading data...' : 'No data available for chart.'} +

+
+
); + } + + return ( +
+
+

Monthly Energy Yield

+
+ +
+ + + + + + + + + + +
+
+ ); }; export default MonthlyBarChart; +