Anomalies Detected
${anomalyCount}
`;
}
function renderAnomaliesTable(anomalies) {
let html = '
| Timestamp | Value | Z-Score |
';
if (anomalies.length === 0) {
html += '| No anomalies detected at this threshold. |
';
} else {
html += anomalies.map(row => `
| ${new Date(row.timestamp).toLocaleString()} |
${row.value.toFixed(2)} |
${row.zScore.toFixed(2)} |
`).join('');
}
elements.anomaliesTable.innerHTML = html + '';
}
function renderAnomalyChart(data) {
const valueCol = elements.colSelect.value;
const timestamps = data.map(row => row.timestamp);
const values = data.map(row => row[valueCol]);
const pointColors = data.map(row => row.isAnomaly ? '#e63946' : 'rgba(0, 119, 182, 0.7)');
const pointRadii = data.map(row => row.isAnomaly ? 6 : 3);
if (chartInstance) chartInstance.destroy();
chartInstance = new Chart(elements.chartCanvas, {
type: 'line',
data: {
labels: timestamps,
datasets: [{
label: valueCol,
data: values,
borderColor: 'rgba(0, 119, 182, 0.5)',
backgroundColor: 'rgba(0, 119, 182, 0.1)',
pointBackgroundColor: pointColors,
pointRadius: pointRadii,
pointHoverRadius: 8,
tension: 0.1,
fill: true
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false },
title: { display: true, text: `Time-Series Analysis for ${valueCol}` }
},
scales: {
x: {
type: 'time',
time: {
tooltipFormat: 'PPpp',
unit: 'day'
},
title: { display: true, text: 'Timestamp' }
},
y: {
title: { display: true, text: 'Value' }
}
}
}
});
}
window.anomalyDownloadPDF = () => {
const dashboard = document.getElementById('anomaly-dashboard-output');
html2canvas(dashboard, { scale: 2 }).then(canvas => {
const pdf = new jspdf.jsPDF({ orientation: 'portrait', unit: 'pt', format: 'a4' });
const pdfWidth = pdf.internal.pageSize.getWidth();
const margin = 40;
const imgWidth = pdfWidth - (margin * 2);
const imgHeight = (canvas.height * imgWidth) / canvas.width;
pdf.addImage(canvas.toDataURL('image/png'), 'PNG', margin, margin, imgWidth, imgHeight);
pdf.save('Anomaly_Detection_Report.pdf');
});
};
});