`;
const ctx = resultsChartCanvas.getContext('2d');
if(resultsChart) resultsChart.destroy();
if (results.problem_type === 'classification') {
const data = {
datasets: [
{ label: 'Correct Predictions', data: [], backgroundColor: 'rgba(59, 130, 246, 0.7)' },
{ label: 'Incorrect Predictions', data: [], backgroundColor: 'rgba(239, 68, 68, 0.7)' }
]
};
for (let i = 0; i < results.chart_data.y_test.length; i++) {
const point = { x: results.chart_data.X_test_0[i], y: results.chart_data.X_test_1[i] };
if (results.chart_data.y_test[i] === results.chart_data.y_pred[i]) {
data.datasets[0].data.push(point);
} else {
data.datasets[1].data.push(point);
}
}
resultsChart = new Chart(ctx, { type: 'scatter', data: data, options: { scales: { x: { title: { display: true, text: 'Feature 1' } }, y: { title: { display: true, text: 'Feature 2' } } } } });
} else { // Regression
const data = {
labels: results.chart_data.y_test.map((_, i) => `Sample ${i+1}`),
datasets: [
{ label: 'Actual Values', data: results.chart_data.y_test, backgroundColor: 'rgba(59, 130, 246, 0.7)' },
{ label: 'Predicted Values', data: results.chart_data.y_pred, backgroundColor: 'rgba(22, 163, 74, 0.7)' }
]
};
resultsChart = new Chart(ctx, { type: 'bar', data: data, options: { scales: { y: { beginAtZero: true } } } });
}
document.getElementById('results-placeholder').classList.add('hidden');
document.getElementById('results-content').classList.remove('hidden');
document.getElementById('export-section').classList.remove('hidden');
}
async function downloadPDF() {
pdfLoader.classList.remove('hidden');
pdfDownloadBtn.disabled = true;
try {
const { jsPDF } = window.jspdf;
const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' });
pdf.setFontSize(18);
pdf.setFont('helvetica', 'bold');
pdf.text('Machine Learning Model Training Report', 105, 15, { align: 'center' });
// Add Config
pdf.setFontSize(14);
pdf.text('1. Configuration', 15, 30);
pdf.setFontSize(11);
pdf.text(`- Dataset: ${datasets[datasetSelect.value].name}`, 20, 38);
pdf.text(`- Model: ${models[datasets[datasetSelect.value].type][modelSelect.value].name}`, 20, 44);
// Add Metrics
const metricsCanvas = await html2canvas(metricsOutput);
pdf.text('2. Performance Metrics', 15, 54);
pdf.addImage(metricsCanvas.toDataURL('image/png'), 'PNG', 20, 60, 80, 0);
// Add Chart
const chartCanvas = await html2canvas(resultsChartCanvas);
pdf.text('3. Result Visualization', 15, 100);
pdf.addImage(chartCanvas.toDataURL('image/png'), 'PNG', 15, 106, 180, 0);
pdf.save('ml-training-report.pdf');
} catch (error) {
console.error(error);
alert("Failed to generate PDF.");
} finally {
pdfLoader.classList.add('hidden');
pdfDownloadBtn.disabled = false;
}
}
// --- EVENT LISTENERS ---
datasetSelect.addEventListener('change', updateDatasetInfo);
modelSelect.addEventListener('change', updateHyperparameters);
trainBtn.addEventListener('click', handleTrain);
pdfDownloadBtn.addEventListener('click', downloadPDF);
document.getElementById('next-btn-1').addEventListener('click', () => switchTab(2));
document.getElementById('prev-btn-2').addEventListener('click', () => switchTab(1));
document.getElementById('next-btn-2').addEventListener('click', () => switchTab(3));
document.getElementById('prev-btn-3').addEventListener('click', () => switchTab(2));
// --- INITIALIZATION ---
updateDatasetInfo();
});
