import React, { useEffect, useRef, useState } from "react"; import ChartWithDropdown from "./approved"; import Cards from "./cards"; import "./cards.css"; import { Bar, Pie } from "react-chartjs-2"; import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, BarElement, ArcElement, Title, Tooltip, Legend, } from "chart.js"; import ChartDataLabels from "chartjs-plugin-datalabels"; import Table from "./Table"; import { PDFDownloadLink, PDFViewer } from "@react-pdf/renderer"; import ApprovalVsRejectionTrends from "./map"; import ReportPDF from "./ReportPDF"; // Register chart components for all three types (Line, Bar, Pie) ChartJS.register( CategoryScale, LinearScale, PointElement, LineElement, BarElement, ArcElement, Title, Tooltip, Legend, ChartDataLabels ); function Charts({ reportData }) { const { data, query } = reportData; if (!data) { return (
No Data Found
); } const { acceptedApplications, rejectedApplications, pendingApplications } = data; const tableData = []; const groupedData = {}; // --- Data Processing for Table --- (Simple aggregation logic) if (acceptedApplications) { for (const item of acceptedApplications) { const { institute, department, formData } = item; const { totalExpense } = formData; // Initialize institute object if not exists if (!groupedData[institute]) { groupedData[institute] = {}; } // If filtering by specific institute, we group by Department (e.g. Computer, IT, Mech) if (query.institute) { if (!groupedData[institute][department]) { groupedData[institute][department] = { totalExpense: 0, applications: 0, }; } // Add expense and increment count groupedData[institute][department].totalExpense += parseFloat(totalExpense); groupedData[institute][department].applications += 1; } else { // If viewing all institutes, we group by Institute (e.g. KJSCE, KJSIM) if (!groupedData[institute].applications) { groupedData[institute] = { totalExpense: 0, applications: 0, }; } // Add expense and increment count groupedData[institute].totalExpense += parseFloat(totalExpense); groupedData[institute].applications += 1; } } } // --- Transform Groups to Array for Display --- if (query.institute) { // Loop through departments for the selected institute for (const institute in groupedData) { for (const department in groupedData[institute]) { const departmentData = groupedData[institute][department]; tableData.push({ id: tableData.length + 1, Stream: department, // 'Stream' here refers to the Department name Scholarship: departmentData.applications, // Number of applications Purpose_of_Travel: departmentData.purposeOfTravel, // (Placeholder) Funds: departmentData.totalExpense.toFixed(2), // Total money spent }); } } } else { // Loop through all institutes for (const institute in groupedData) { const instituteData = groupedData[institute]; tableData.push({ id: tableData.length + 1, Stream: institute, // 'Stream' here is the Institute name Scholarship: instituteData.applications, // Number of applications Purpose_of_Travel: instituteData.purposeOfTravel, Funds: instituteData.totalExpense.toFixed(2), // Total money spent }); } } const [chartImages, setChartImages] = useState({ barChart: null, pieChart1: null, pieChart2: null, isLoading: false, }); // --- Chart Configuration (Preserved for future use) --- // Line Chart Data and Options const lineOptions = { responsive: true, plugins: { title: { display: true, text: "Number of Applications Over the Years ", }, }, scales: { x: { title: { display: true, text: "Year", }, }, y: { title: { display: true, text: "Number of Applications", }, ticks: { beginAtZero: true, }, }, }, }; const lineData = { labels: [2020, 2021, 2022, 2023, 2024], datasets: [ { label: "Applications", data: [1200, 1500, 1800, 2200, 2500], // Updated data for number of applications borderColor: "rgb(75, 192, 192)", fill: false, tension: 0.1, }, ], }; // Bar Chart Data and Options const barOptions = { responsive: true, plugins: { title: { display: true, text: "Number of Applications Over the Years ", }, }, scales: { x: { title: { display: true, text: "Month", }, }, y: { title: { display: true, text: "Number of Applications", }, ticks: { beginAtZero: true, }, }, }, }; const barData = { labels: [ "Jan", "Feb", "Mar", "April", "May", "June", "July", "Aug", "Sep", "Nov", "Dec", ], datasets: [ { label: "Applications", data: [ 1200, 1500, 1800, 2200, 200, 800, 1235, 604, 2345, 2523, 3453, 6453, ], // Updated data for number of applications backgroundColor: "rgba(75, 192, 192, 0.5)", borderColor: "rgb(75, 192, 192)", borderWidth: 1, }, ], }; // Pie Chart Data and Options const pieOptions = { responsive: true, plugins: { title: { display: true, text: "Purpose of Travel", }, }, }; const pieData = { labels: ["Academic", "Research", "Personal", "Other"], datasets: [ { data: [1200, 1500, 1800, 2200], // Updated data for number of applications backgroundColor: [ "rgba(75, 192, 192, 0.5)", "rgba(255, 99, 132, 0.5)", "rgba(54, 162, 235, 0.5)", "rgba(153, 102, 255, 0.5)", ], borderColor: [ "rgb(75, 192, 192)", "rgb(255, 99, 132)", "rgb(54, 162, 235)", "rgb(153, 102, 255)", ], borderWidth: 1, }, ], }; const pie_Options = { responsive: true, plugins: { title: { display: true, text: "Travel", }, }, }; const pie_Data = { labels: ["Domestic", "International", "Local"], datasets: [ { data: [1200, 1500, 1800], // Updated data for number of applications backgroundColor: [ "rgba(79, 246, 96, 0.5)", "rgba(255, 99, 132, 0.5)", "rgba(54, 162, 235, 0.5)", ], borderColor: [ "rgb(79, 246, 96)", "rgb(255, 99, 132)", "rgb(54, 162, 235)", ], borderWidth: 1, }, ], }; const barChartRef = useRef(); const pieChartRef1 = useRef(); const pieChartRef2 = useRef(); // Note: Chart generation logic for PDF is currently disabled as we focus on the Table view. // Uncomment this when we are ready to integrate charts into the PDF report. /* const loadChartsInPdf = () => { const barChartInstance = barChartRef.current; const pieChartInstance1 = pieChartRef1.current; const pieChartInstance2 = pieChartRef2.current; if (barChartInstance) { const barBase64Image = barChartInstance.toBase64Image(); setChartImages((prevImages) => ({ ...prevImages, barChart: barBase64Image, })); } if (pieChartInstance1) { const pieBase64Image = pieChartInstance1.toBase64Image(); setChartImages((prevImages) => ({ ...prevImages, pieChart1: pieBase64Image, })); } if (pieChartInstance2) { const pieBase64Image = pieChartInstance2.toBase64Image(); setChartImages((prevImages) => ({ ...prevImages, pieChart2: pieBase64Image, })); } }; useEffect(() => { setChartImages((prevImages) => ({ ...prevImages, isLoading: true })); const handleRender = () => { loadChartsInPdf(); setChartImages((prevImages) => ({ ...prevImages, isLoading: false })); }; const barChartInstance = barChartRef.current; const pieChartInstance1 = pieChartRef1.current; const pieChartInstance2 = pieChartRef2.current; if (barChartInstance) { barChartInstance.options.animation.onComplete = handleRender; } if (pieChartInstance1) { pieChartInstance1.options.animation.onComplete = handleRender; } if (pieChartInstance2) { pieChartInstance2.options.animation.onComplete = handleRender; } return () => { if (barChartInstance) { barChartInstance.options.animation.onComplete = null; } if (pieChartInstance1) { pieChartInstance1.options.animation.onComplete = null; } if (pieChartInstance2) { pieChartInstance2.options.animation.onComplete = null; } }; }, []); */ return (

Travel Policy Report

{/* Container for all three charts */} {/*
*/} {/*
*/} {/*
*/} {/* Line Chart */} {/*
*/}
{/* Reuse the Table component to show aggregated data */} {/*
*/} {chartImages.isLoading ? (
Generating PDF Report...
) : (
} fileName={`report_${query.institute || "allInstitutes"}_${ query.department || "allDepartments" }_${query.year || "allYears"}_${ query.applicationType || "allApplications" }.pdf`} > {({ blob, url, loading, error }) => loading ? (
Getting Your PDF Report Ready...
) : ( ) }
)} ); } export default Charts;