Score Range: ${mlrm_model.scoreMin} - ${mlrm_model.scoreMax}
`;
}
summaryHTML += `
Features & Weights:
`;
mlrm_model.features.forEach(f => {
summaryHTML += `- ${f.name || 'Unnamed Feature'} (Type: ${f.type}, Weight: ${f.weight || 0})
- Impact: ${f.impact ? f.impact.replace(/_/g,' ') : 'N/A'}
`;
if (f.type === 'numerical') {
summaryHTML += `- Expected Range: ${f.numericalMin}-${f.numericalMax}
`;
} else {
summaryHTML += `- Categorical Options:
`;
(f.categoricalValues || []).forEach(opt => summaryHTML += `- '${opt.value}': Score ${opt.score}
`);
summaryHTML += `
`;
}
summaryHTML += `
`;
});
summaryHTML += `
`;
if (mlrm_lastAssessment) {
summaryHTML += `
Last Scenario Assessment:
Calculated Score: ${mlrm_lastAssessment.score.toFixed(2)}
`;
if (mlrm_model.outputType === 'categorical') {
summaryHTML += `
Assigned Category: ${mlrm_lastAssessment.category || 'N/A'}
`;
}
summaryHTML += `
Input Data:
`;
mlrm_model.features.forEach(f => {
summaryHTML += `- ${f.name || 'Unnamed'}: ${mlrm_lastAssessment.scenarioData[f.id] !== undefined ? mlrm_lastAssessment.scenarioData[f.id] : 'N/A'}
`;
});
summaryHTML += `
`;
}
container.innerHTML = summaryHTML;
}
function mlrm_downloadPDF() {
if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined') {
alert('PDF library (jsPDF) is not loaded. Check internet connection.'); return;
}
const { jsPDF: JSPDF } = window.jspdf;
const doc = new JSPDF();
let y = 15;
const lm = 15, rm = 15, cw = doc.internal.pageSize.getWidth() - lm - rm;
function addLine(text, size, bold, indent = 0) {
if (y > 270) { doc.addPage(); y = 15; }
doc.setFontSize(size);
doc.setFont(undefined, bold ? 'bold' : 'normal');
const lines = doc.splitTextToSize(text, cw - indent);
doc.text(lines, lm + indent, y);
y += (lines.length * (size * 0.35)) + 2; // Dynamic line height
}
mlrm_generateFullModelSummary(); // Ensure model data is current for PDF
addLine(`Risk Model: ${mlrm_model.name || 'N/A'}`, 18, true); y += 3;
addLine(`Output Type: ${mlrm_model.outputType}`, 11, false);
if (mlrm_model.outputType === 'categorical') {
addLine(`Risk Categories: ${mlrm_model.riskCategories.map(c => c.name).join(', ') || 'N/A'}`, 11, false);
addLine("Category Thresholds (Max score for category):", 11, true);
mlrm_model.riskCategories.forEach((cat, index) => {
if (index < mlrm_model.riskCategories.length -1) {
addLine(`- ${cat.name || 'Unnamed'}: Up to ${mlrm_model.thresholds[cat.id] !== undefined ? mlrm_model.thresholds[cat.id] : 'N/A'}`, 10, false, 5);
} else {
addLine(`- ${cat.name || 'Unnamed'}: Above previous threshold`, 10, false, 5);
}
});
} else {
addLine(`Score Range: ${mlrm_model.scoreMin} - ${mlrm_model.scoreMax}`, 11, false);
}
y += 5;
addLine("Features & Weights:", 14, true);
mlrm_model.features.forEach(f => {
if (y > 260) { doc.addPage(); y = 15; }
addLine(`${f.name || 'Unnamed Feature'} (Weight: ${f.weight || 0})`, 11, true, 5);
addLine(` Type: ${f.type}, Impact: ${f.impact ? f.impact.replace(/_/g,' ') : 'N/A'}`, 10, false, 10);
if (f.type === 'numerical') {
addLine(` Expected Range: ${f.numericalMin}-${f.numericalMax}`, 10, false, 10);
} else {
addLine(` Categorical Options:`, 10, false, 10);
(f.categoricalValues || []).forEach(opt => addLine(` - '${opt.value}': Score ${opt.score}`, 9, false, 15));
}
y += 2;
});
y += 5;
if (mlrm_lastAssessment) {
if (y > 250) { doc.addPage(); y = 15; }
addLine("Last Scenario Assessment:", 14, true);
addLine(`Calculated Score: ${mlrm_lastAssessment.score.toFixed(2)}`, 11, false);
if (mlrm_model.outputType === 'categorical') {
addLine(`Assigned Category: ${mlrm_lastAssessment.category || 'N/A'}`, 11, false);
}
addLine(`Input Data:`, 11, true, 5);
mlrm_model.features.forEach(f => {
addLine(`- ${f.name || 'Unnamed'}: ${mlrm_lastAssessment.scenarioData[f.id] !== undefined ? mlrm_lastAssessment.scenarioData[f.id] : 'N/A'}`, 10, false, 10);
});
}
doc.save((mlrm_model.name.replace(/[^\w\s]/gi, '').replace(/\s+/g, '_') || 'risk_model_summary') + ".pdf");
}