Bot Traffic %
${currentData.botTrafficPercent.toFixed(1)}%
Detailed Event Log
| IP Address | User Agent | Status | Reasons |
${eventRows}
`;
const ctx = getElem('trafficChart').getContext('2d');
if (trafficChart) trafficChart.destroy();
trafficChart = new Chart(ctx, {
type: 'pie',
data: {
labels: ['Human', 'Bot'],
datasets: [{
data: [currentData.classificationCounts.Human, currentData.classificationCounts.Bot],
backgroundColor: ['#22C55E', '#EF4444'],
}]
},
options: { responsive: true, maintainAspectRatio: false }
});
downloadSection.classList.remove('hidden');
showTab(1);
};
analyzeBtn.addEventListener('click', analyzeTraffic);
// --- PDF DOWNLOAD ---
const downloadPDF = () => {
if (!currentData) return;
const { jsPDF } = window.jspdf;
const pdf = new jsPDF({ orientation: 'portrait', unit: 'pt', format: 'a4' });
const btnText = getElem('pdf-btn-text');
const btnSpinner = getElem('pdf-btn-spinner');
btnText.classList.add('hidden');
btnSpinner.classList.remove('hidden');
downloadPdfBtn.disabled = true;
try {
const pageWidth = pdf.internal.pageSize.getWidth();
const margin = 40;
let y = margin;
pdf.setFont('helvetica', 'bold');
pdf.setFontSize(22);
pdf.text("Bot Activity Report", pageWidth / 2, y, { align: 'center' });
y += 15;
pdf.setFont('helvetica', 'normal');
pdf.setFontSize(10);
pdf.text(`Report Date: ${today.toLocaleDateString('en-US')}`, pageWidth / 2, y, { align: 'center' });
y += 35;
pdf.autoTable({
startY: y,
theme: 'grid',
head: [['Metric', 'Value']],
body: [
['Total Traffic Events Analyzed', `${currentData.totalEvents}`],
['Total Bots Detected', { content: `${currentData.botsDetected}`, styles: {textColor: '#DC2626', fontStyle: 'bold'} }],
['Bot Traffic Percentage', `${currentData.botTrafficPercent.toFixed(1)}%`],
],
didDrawPage: (data) => { y = data.cursor.y; }
});
y += 20;
pdf.setFont('helvetica', 'bold');
pdf.text("Detailed Event Log", margin, y);
y += 15;
const tableData = currentData.results.map(r => [r.ip, r.ua.substring(0, 40) + '...', r.classification, r.reasons]);
pdf.autoTable({
startY: y,
head: [['IP Address', 'User Agent', 'Classification', 'Risk Factors']],
body: tableData,
theme: 'striped',
headStyles: { fillColor: [29, 78, 216] }, // blue-700
didParseCell: function (data) {
if (data.section === 'body' && data.column.index === 2) {
if (data.cell.raw === 'Bot') data.cell.styles.textColor = '#DC2626';
}
},
});
pdf.save(`Bot-Activity-Report.pdf`);
} catch(e) { console.error("PDF Generation failed:", e); }
finally {
btnText.classList.remove('hidden');
btnSpinner.classList.remove('hidden');
downloadPdfBtn.disabled = false;
}
};
downloadPdfBtn.addEventListener('click', downloadPDF);
initialize();
});