`
).join('');
container.innerHTML = html;
}
// --- CHARTS ---
function createCharts() {
scoreChart = new Chart('score-chart', {
type: 'doughnut',
data: {
labels: ['Compliant', 'Non-Compliant'],
datasets: [{ data: [0, 100], backgroundColor: ['#0d9488', '#f1f5f9'], borderWidth: 0 }]
},
options: {
responsive: true, maintainAspectRatio: false, cutout: '70%',
plugins: { legend: { display: false }, title: { display: true, text: '0%', position: 'bottom', font: { size: 24, weight: 'bold' } } }
}
});
categoryChart = new Chart('category-chart', {
type: 'bar',
options: {
responsive: true, maintainAspectRatio: false, indexAxis: 'y',
scales: { x: { beginAtZero: true, max: 100, ticks: { callback: v => v + '%' } } },
plugins: { legend: { display: false } }
},
data: { labels: [], datasets: [{ label: 'Compliance %', backgroundColor: '#2dd4bf' }] }
});
}
// --- PDF GENERATION ---
async function generatePdf() {
const { jsPDF } = window.jspdf;
ui.downloadPdfBtn.textContent = 'Generating...';
ui.downloadPdfBtn.disabled = true;
try {
const canvas = await html2canvas(document.getElementById('pdf-content'), { scale: 2 });
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF({ orientation: 'portrait', unit: 'px', format: 'a4' });
const orgName = document.getElementById('org-name').value;
const regName = regulations[currentRegulation].name;
pdf.setFontSize(18);
pdf.text('Compliance Report', 40, 40);
pdf.setFontSize(11);
pdf.text(`Organization: ${orgName}`, 40, 60);
pdf.text(`Regulation: ${regName}`, 40, 75);
pdf.text(`Date: ${new Date().toLocaleDateString()}`, 350, 60);
const imgProps = pdf.getImageProperties(imgData);
const pdfWidth = pdf.internal.pageSize.getWidth();
const imgHeight = (imgProps.height * pdfWidth) / imgProps.width;
pdf.addImage(imgData, 'PNG', 0, 90, pdfWidth, imgHeight);
pdf.addPage();
pdf.setFontSize(16);
pdf.text('Gap Analysis Details', 40, 40);
const gaps = [];
ui.checklistContainer.querySelectorAll('input:not(:checked)').forEach(cb => {
gaps.push([cb.dataset.category, cb.parentElement.textContent.trim()]);
});
if (gaps.length > 0) {
pdf.autoTable({ startY: 60, head: [['Category', 'Non-Compliant Item']], body: gaps, theme: 'striped' });
} else {
pdf.text('No compliance gaps were identified.', 40, 60);
}
pdf.save(`${orgName}_Compliance_Report.pdf`);
} catch (error) {
console.error("PDF generation error:", error);
alert("Failed to generate PDF report.");
} finally {
ui.downloadPdfBtn.textContent = 'Download PDF Report';
ui.downloadPdfBtn.disabled = false;
}
}
// --- RUN ---
init();
});
