Student Performance Analytics

Student Performance Analytics

Visualize and analyze student data to drive educational insights.

Total Students

Class Average Grade

Average Attendance

Students At-Risk

Grade Distribution

Attendance Trends

${student.grade}%

Attendance

${student.attendance}%

Avg. Assignment

${student.avgAssignment.toFixed(1)}%

Assignment Score Trend

`; renderIndividualAssignmentChart(student); }; // --- CHART RENDERING --- const renderGradeDistributionChart = () => { const ctx = document.getElementById('grade-dist-chart').getContext('2d'); if (charts.grade) charts.grade.destroy(); const grades = studentData.map(s => s.grade); const bins = { 'F (0-59)': 0, 'D (60-69)': 0, 'C (70-79)': 0, 'B (80-89)': 0, 'A (90-100)': 0 }; grades.forEach(g => { if (g < 60) bins['F (0-59)']++; else if (g < 70) bins['D (60-69)']++; else if (g < 80) bins['C (70-79)']++; else if (g < 90) bins['B (80-89)']++; else bins['A (90-100)']++; }); charts.grade = new Chart(ctx, { type: 'bar', data: { labels: Object.keys(bins), datasets: [{ label: 'Number of Students', data: Object.values(bins), backgroundColor: 'rgba(59, 130, 246, 0.5)', borderColor: 'rgba(59, 130, 246, 1)', borderWidth: 1 }] }, options: { animation: false, scales: { y: { beginAtZero: true, stepSize: 1 } } } }); }; const renderAttendanceChart = () => { const ctx = document.getElementById('attendance-chart').getContext('2d'); if (charts.attendance) charts.attendance.destroy(); charts.attendance = new Chart(ctx, { type: 'line', data: { labels: studentData.map(s => s.name), datasets: [{ label: 'Attendance %', data: studentData.map(s => s.attendance), fill: false, borderColor: 'rgb(75, 192, 192)', tension: 0.1 }] }, options: { animation: false } }); }; const renderIndividualAssignmentChart = (student) => { const ctx = document.getElementById('individual-assignment-chart').getContext('2d'); if (charts.individual) charts.individual.destroy(); charts.individual = new Chart(ctx, { type: 'line', data: { labels: student.assignments.map((_, i) => `Assign. ${i+1}`), datasets: [{ label: 'Score %', data: student.assignments, borderColor: 'rgb(239, 68, 68)', tension: 0.1 }] }, options: { animation: false } }); }; // --- TAB NAVIGATION --- window.changeTab = (tabIndex) => { tabs[currentTab].classList.remove('active'); tabContents[currentTab].classList.add('hidden'); currentTab = tabIndex; tabs[currentTab].classList.add('active'); tabContents[currentTab].classList.remove('hidden'); }; // --- EVENT LISTENERS --- updateDataBtn.addEventListener('click', renderAll); studentSelect.addEventListener('change', renderIndividualReport); // --- PDF DOWNLOAD --- downloadPdfBtn.addEventListener('click', () => { // **FIX:** Add a small delay to ensure charts are fully rendered before capturing setTimeout(() => { generatePdfReport(); }, 200); }); const generatePdfReport = async () => { try { const { jsPDF } = window.jspdf; const doc = new jsPDF('p', 'mm', 'a4'); const selectedStudent = studentData.find(s => s.id === parseInt(studentSelect.value, 10)); doc.setFontSize(24); doc.setFont('helvetica', 'bold'); doc.text('Student Performance Report', 105, 20, { align: 'center' }); doc.setFontSize(12); doc.text(`Report Date: ${new Date().toLocaleDateString()}`, 105, 28, { align: 'center' }); doc.setFontSize(16); doc.text('Class-wide Analytics', 15, 45); const gradeChartImg = document.getElementById('grade-dist-chart').toDataURL('image/png', 1.0); const attendanceChartImg = document.getElementById('attendance-chart').toDataURL('image/png', 1.0); doc.addImage(gradeChartImg, 'PNG', 15, 50, 85, 45); doc.addImage(attendanceChartImg, 'PNG', 110, 50, 85, 45); if (selectedStudent) { doc.addPage(); doc.setFontSize(20); doc.text(`Individual Report: ${selectedStudent.name}`, 105, 20, { align: 'center' }); // **FIX:** Simplified and more robust capture logic for the individual report const reportElement = document.getElementById('individual-report-view'); await html2canvas(reportElement, { scale: 2, backgroundColor: '#f8fafc' }).then(canvas => { const imgData = canvas.toDataURL('image/png'); const imgProps = doc.getImageProperties(imgData); const pdfWidth = doc.internal.pageSize.getWidth() - 30; // with margin const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width; doc.addImage(imgData, 'PNG', 15, 30, pdfWidth, pdfHeight); }); } doc.save('student-performance-report.pdf'); } catch (error) { console.error("PDF Generation Error:", error); alert("An error occurred while generating the PDF. Please try again."); } }; // --- INITIALIZATION --- dataInputArea.value = "John Doe, 85, 95, 90,80,88,92\nJane Smith, 92, 98, 95,90,89,94\nPeter Jones, 55, 65, 50,60,58,42\nMary Williams, 78, 88, 75,82,79,80"; renderAll(); });
Scroll to Top