Risk Assessment Matrix/Report Generator

Risk Assessment Matrix Generator

Project Atlas - Risk Assessment

Risk Heat Map

(Probability on Y-Axis, Impact on X-Axis)

Probability → Impact →
High (3)
Medium (2)
Low (1)
Low (1)
Medium (2)
High (3)

Risk Register

ID Risk Description Prob Impact Score Mitigation Strategy

Project Information

Add New Risk

Current Risks

No risks added yet.

"; } appState.risks.forEach(function(risk) { var item = document.createElement("div"); item.className = "ram-risk-item"; var score = calculateScore(risk.prob, risk.impact); var levelData = getRiskLevel(score); item.innerHTML = ` ${risk.riskId}: ${risk.desc.substring(0, 50)}... (${levelData.level}) `; riskList.appendChild(item); }); }; var renderHeatMap = function() { heatMapContainer.innerHTML = ''; var scoreCounts = {}; // Initialize score counts for 3x3 matrix (1-9) for (var p = 1; p <= 3; p++) { for (var i = 1; i <= 3; i++) { scoreCounts[p + '-' + i] = 0; } } appState.risks.forEach(function(risk) { var key = risk.prob + '-' + risk.impact; scoreCounts[key]++; }); for (var p = 3; p >= 1; p--) { // Probability (rows: High to Low) for (var i = 1; i <= 3; i++) { // Impact (columns: Low to High) var score = p * i; var count = scoreCounts[p + '-' + i]; var levelData = getRiskLevel(score); var cell = document.createElement('div'); cell.className = 'ram-matrix-cell'; cell.setAttribute('data-risk', score); var top = (3 - p) * 33.33; var left = (i - 1) * 33.33; cell.style.top = top + '%'; cell.style.left = left + '%'; // Display the count and the risk score cell.innerHTML = '' + count + '
' + '(Score ' + score + ')'; heatMapContainer.appendChild(cell); } } }; var renderDashboardTab = function() { projectTitleDisplay.textContent = appState.projectName; renderHeatMap(); var levelFilter = filterLevelSelect.value; var sortBy = sortBySelect.value; // 1. Filter var filteredRisks = appState.risks.filter(function(risk) { var score = calculateScore(risk.prob, risk.impact); var levelData = getRiskLevel(score); if (levelFilter === 'all') return true; if (levelFilter === 'Low') return levelData.level === 'Low' || levelData.level === 'Medium'; return levelData.level === levelFilter; }); // 2. Sort filteredRisks.sort(function(a, b) { var scoreA = calculateScore(a.prob, a.impact); var scoreB = calculateScore(b.prob, b.impact); if (sortBy === 'score_desc') { return scoreB - scoreA; } else if (sortBy === 'name_asc') { return a.riskId.localeCompare(b.riskId); } return 0; }); // 3. Render Table tableBody.innerHTML = ""; if (filteredRisks.length === 0) { tableBody.innerHTML = "No risks match the current filter."; return; } filteredRisks.forEach(function(risk) { var score = calculateScore(risk.prob, risk.impact); var levelData = getRiskLevel(score); var tagClass = 'tag-' + levelData.color; var tr = document.createElement("tr"); tr.innerHTML = ` ${risk.riskId} ${risk.desc} ${risk.prob} ${risk.impact} ${levelData.level} (${score}) ${risk.mitigation} `; tableBody.appendChild(tr); }); }; // --- Event Handlers --- // Update Dashboard Button updateBtn.addEventListener("click", function() { appState.projectName = projectNameInput.value || "Untitled Risk Assessment"; saveState(); renderDashboardTab(); showTab(0); }); // Add Risk addRiskBtn.addEventListener("click", function() { var riskId = riskIdInput.value.trim(); var desc = riskDescInput.value.trim(); var prob = parseInt(riskProbSelect.value); var impact = parseInt(riskImpactSelect.value); var mitigation = riskMitigationTextarea.value.trim(); if (!riskId || !desc) { alert("Please enter a Risk ID and Description."); return; } var newRisk = { id: Date.now(), riskId: riskId, desc: desc, prob: prob, impact: impact, mitigation: mitigation }; appState.risks.push(newRisk); saveState(); renderConfigTab(); // Clear form riskIdInput.value = ""; riskDescInput.value = ""; riskMitigationTextarea.value = ""; riskProbSelect.value = "2"; riskImpactSelect.value = "2"; }); // Remove Risk (Event Delegation) riskList.addEventListener("click", function(e) { if (e.target.classList.contains("ram-remove-btn")) { var id = parseInt(e.target.dataset.id); appState.risks = appState.risks.filter(function(risk) { return risk.id !== id; }); saveState(); renderConfigTab(); } }); // Filters Change filterLevelSelect.addEventListener("change", renderDashboardTab); sortBySelect.addEventListener("change", renderDashboardTab); // PDF Download pdfBtn.addEventListener("click", function() { var jsPDF = window.jspdf.jsPDF; var fileName = `${appState.projectName.replace(/ /g, '_')}_Risk_Report.pdf`; // Temporarily adjust minimum table width for PDF quality var table = document.getElementById('ram-register-table'); var originalMinWidth = table.style.minWidth; table.style.minWidth = '1100px'; // Hide filters for PDF var filtersDiv = toolContainer.querySelector('.ram-filters'); var filtersDisplayStyle = filtersDiv.style.display; filtersDiv.style.display = 'none'; html2canvas(exportArea, { scale: 2, useCORS: true, backgroundColor: '#ffffff' }).then(function(canvas) { // Restore styles table.style.minWidth = originalMinWidth; filtersDiv.style.display = filtersDisplayStyle; var imgData = canvas.toDataURL('image/png'); var doc = new jsPDF({ orientation: 'l', // Landscape is better for wide tables unit: 'pt', format: 'a4' }); var pdfWidth = doc.internal.pageSize.getWidth(); var pdfHeight = doc.internal.pageSize.getHeight(); var imgProps = doc.getImageProperties(imgData); var imgWidth = imgProps.width; var imgHeight = imgProps.height; var margin = 30; var usableWidth = pdfWidth - (2 * margin); var ratio = usableWidth / imgWidth; var scaledHeight = imgHeight * ratio; // Handle multi-page if content exceeds page height if (scaledHeight > pdfHeight - (2 * margin)) { var pageHeight = pdfHeight - (2 * margin); var heightLeft = scaledHeight; var position = 0; while (heightLeft > 0) { doc.addImage(imgData, 'PNG', margin, position + margin, usableWidth, scaledHeight); heightLeft -= pageHeight; position -= pageHeight; if (heightLeft > 0) { doc.addPage(); } } } else { // Single page doc.addImage(imgData, 'PNG', margin, margin, usableWidth, scaledHeight); } doc.save(fileName); }).catch(function(err) { // Restore styles even if PDF fails table.style.minWidth = originalMinWidth; filtersDiv.style.display = filtersDisplayStyle; console.error("RAM PDF Error:", err); // alert("An error occurred while generating the PDF."); // Per spec }); }); // --- Local Storage --- var saveState = function() { try { localStorage.setItem("ramAppState", JSON.stringify(appState)); } catch (e) { console.warn("RAM: Could not save state."); } }; var loadState = function() { try { var storedState = localStorage.getItem("ramAppState"); if (storedState) appState = JSON.parse(storedState); } catch (e) { console.warn("RAM: Could not load state."); } }; // --- Initial Load --- loadState(); renderConfigTab(); renderDashboardTab(); showTab(0); });
Scroll to Top