Error: Could not load required libraries.
';
return;
}
let session_barChart;
let session_data = [];
let session_sortState = { key: 'attendees', direction: 'desc' };
const TABS = ['dashboardTab', 'dataInputTab'];
let session_currentTabIndex = 0;
const sampleData = [
{ sessionName: "Keynote: The Future of AI in Marketing", speaker: "Jane Doe", date: "2025-07-10", time: "09:00", registrants: 550, attendees: 480 },
{ sessionName: "Mastering SEO in 2025", speaker: "John Smith", date: "2025-07-10", time: "10:30", registrants: 320, attendees: 280 },
{ sessionName: "Content Strategy for Hyper-Growth", speaker: "Emily White", date: "2025-07-10", time: "10:30", registrants: 280, attendees: 210 },
{ sessionName: "Social Media Engagement Secrets", speaker: "Michael Lee", date: "2025-07-11", time: "11:30", registrants: 410, attendees: 310 },
{ sessionName: "Data-Driven Decisions Workshop", speaker: "Dr. Chen", date: "2025-07-11", time: "14:00", registrants: 150, attendees: 145 },
];
function session_initialize() {
sampleData.forEach(d => session_add_row(d));
session_updateDashboard();
session_updateNavButtons();
}
window.session_add_row = function(data = {}) {
const tableBody = document.getElementById('session-input-table-body');
const row = tableBody.insertRow();
row.innerHTML = `
|
|
|
|
|
|
|
`;
}
function session_collectAndProcessData() {
const rows = document.getElementById('session-input-table-body').rows;
let processedData = [];
for (let row of rows) {
const inputs = row.querySelectorAll('input');
const registrants = parseInt(inputs[4].value) || 0;
const attendees = parseInt(inputs[5].value) || 0;
const attendanceRate = registrants > 0 ? (attendees / registrants) * 100 : 0;
processedData.push({
sessionName: inputs[0].value,
speaker: inputs[1].value,
date: inputs[2].value,
time: inputs[3].value,
registrants: registrants,
attendees: attendees,
attendanceRate: parseFloat(attendanceRate.toFixed(1))
});
}
return processedData;
}
window.session_updateDashboard = function() {
session_data = session_collectAndProcessData();
session_updateSummaryMetrics();
session_updateBarChart();
session_renderTable();
session_changeTab('dashboardTab');
}
function session_updateSummaryMetrics() {
const totalSessions = session_data.length;
const totalRegistrants = session_data.reduce((sum, s) => sum + s.registrants, 0);
const totalAttendees = session_data.reduce((sum, s) => sum + s.attendees, 0);
const avgRate = totalRegistrants > 0 ? (totalAttendees / totalRegistrants) * 100 : 0;
document.getElementById('summary-sessions').textContent = totalSessions.toLocaleString();
document.getElementById('summary-registrants').textContent = totalRegistrants.toLocaleString();
document.getElementById('summary-attendees').textContent = totalAttendees.toLocaleString();
document.getElementById('summary-avg-rate').textContent = `${avgRate.toFixed(1)}%`;
}
function session_updateBarChart() {
const ctx = document.getElementById('session-bar-chart');
if (session_barChart) session_barChart.destroy();
const sortedByAttendees = [...session_data].sort((a, b) => b.attendees - a.attendees);
session_barChart = new Chart(ctx, {
type: 'bar',
data: {
labels: sortedByAttendees.map(s => s.sessionName),
datasets: [
{
label: 'Attendees',
data: sortedByAttendees.map(s => s.attendees),
backgroundColor: '#3182ce',
borderColor: '#2b6cb0',
borderWidth: 1
},
{
label: 'Registrants',
data: sortedByAttendees.map(s => s.registrants),
backgroundColor: '#a0aec0',
borderColor: '#718096',
borderWidth: 1
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: { y: { beginAtZero: true } },
plugins: { legend: { position: 'top' } }
}
});
}
window.session_sortTableBy = function(key) {
if (session_sortState.key === key) {
session_sortState.direction = session_sortState.direction === 'asc' ? 'desc' : 'asc';
} else {
session_sortState.key = key;
session_sortState.direction = 'desc';
}
session_renderTable();
}
function session_renderTable() {
const { key, direction } = session_sortState;
const sortedData = [...session_data].sort((a, b) => {
const valA = a[key];
const valB = b[key];
if (typeof valA === 'string') {
return direction === 'asc' ? valA.localeCompare(valB) : valB.localeCompare(valA);
} else {
return direction === 'asc' ? valA - valB : valB - valA;
}
});
const tableBody = document.getElementById('session-table-body');
tableBody.innerHTML = '';
sortedData.forEach(s => {
const row = tableBody.insertRow();
row.innerHTML = `
${s.sessionName} |
${s.speaker} |
${s.attendees.toLocaleString()} |
${s.registrants.toLocaleString()} |
|
`;
});
// Update sort indicators
document.querySelectorAll('.sort-indicator').forEach(el => {
if (el.dataset.sortKey === key) {
el.textContent = direction === 'asc' ? 'â–²' : 'â–¼';
} else {
el.textContent = '';
}
});
}
window.session_downloadPDF = function() {
const { jsPDF } = window.jspdf;
const doc = new jsPDF('landscape');
doc.setFontSize(20);
doc.text("Session Popularity Report", 148, 20, { align: 'center' });
const totalSessions = session_data.length;
const totalRegistrants = session_data.reduce((sum, s) => sum + s.registrants, 0);
const totalAttendees = session_data.reduce((sum, s) => sum + s.attendees, 0);
const avgRate = totalRegistrants > 0 ? (totalAttendees / totalRegistrants) * 100 : 0;
const summaryText = `Total Sessions: ${totalSessions} | Total Registrants: ${totalRegistrants.toLocaleString()} | Total Attendees: ${totalAttendees.toLocaleString()} | Average Attendance: ${avgRate.toFixed(1)}%`;
doc.setFontSize(10);
doc.text(summaryText, 148, 28, { align: 'center' });
const chartCanvas = document.getElementById('session-bar-chart').toDataURL('image/png', 1.0);
doc.addImage(chartCanvas, 'PNG', 15, 40, 267, 80);
const tableHead = [['Session Name', 'Speaker', 'Attendees', 'Registrants', 'Attendance Rate (%)']];
const tableBody = session_data.map(s => [s.sessionName, s.speaker, s.attendees, s.registrants, s.attendanceRate]);
doc.autoTable({
head: tableHead,
body: tableBody,
startY: 125,
theme: 'grid',
headStyles: { fillColor: '#2c5282' }
});
doc.save('Session_Popularity_Report.pdf');
}
// --- TABBING & NAVIGATION ---
window.session_changeTab = function(tabId) {
document.querySelectorAll('.session-tab-content').forEach(c => c.classList.remove('active'));
document.querySelectorAll('.session-tab-button').forEach(b => b.classList.remove('active'));
document.getElementById(tabId).classList.add('active');
const activeButton = Array.from(document.querySelectorAll('.session-tab-button')).find(btn => btn.getAttribute('onclick').includes(tabId));
if (activeButton) activeButton.classList.add('active');
session_currentTabIndex = TABS.indexOf(tabId);
session_updateNavButtons();
}
window.session_navigateTabs = function(direction) {
let newIndex = session_currentTabIndex;
if (direction === 'next') newIndex = Math.min(newIndex + 1, TABS.length - 1);
else if (direction === 'prev') newIndex = Math.max(newIndex - 1, 0);
session_changeTab(TABS[newIndex]);
}
function session_updateNavButtons() {
const prevBtn = document.getElementById('session-prev-btn');
const nextBtn = document.getElementById('session-next-btn');
if(prevBtn) prevBtn.disabled = session_currentTabIndex === 0;
if(nextBtn) nextBtn.disabled = session_currentTabIndex === TABS.length - 1;
}
session_initialize();
});