Analytical Thinking Calculator

Analytical Thinking Calculator: Weighted Decision Matrix

The dashboard provides the final ranking based on your weighted criteria and scores. The highest Total Weighted Score is the recommended option.

Final Decision Ranking

Input options and criteria in the last tab, then proceed to the Scoring Matrix tab to begin the analysis.

Detailed Decision Matrix (Score = Weight x Criterion Score)

The complete matrix will appear here after calculation.

Rate each Option against each Criterion on a scale of 1 (Low) to 10 (High). Enter 'N/A' to exclude an option from a criterion.

Please configure Options and Criteria in the 'Options & Criteria Input' tab first.

1. Define Options (e.g., Software A, Project B, House C)

2. Define Criteria and Weight (e.g., Cost, Risk, ROI)

The sum of all weights should ideally equal 100.

Total Weight: 0

Please define at least one Option and one Criterion in the input tab.

'; return; } // 2. Build Table Header let tableHtml = ''; tableHtml += ''; criteria.forEach(crit => { tableHtml += ``; }); tableHtml += ''; // 3. Build Table Body with Input Fields options.forEach(opt => { tableHtml += ``; criteria.forEach(crit => { // Use unique IDs for each cell input: optId_critId const inputId = `${opt.id}_${crit.id}`; tableHtml += ``; }); tableHtml += ''; }); tableHtml += '
Option / Criterion (Weight)${crit.name}
(${crit.weight})
${opt.name}
'; matrixContainer.innerHTML = tableHtml; // 4. Navigate (if requested) if (shouldNavigate) { const scoringButton = document.querySelector('.tab-button[onclick*="scoring-tab"]'); if (scoringButton) { showTab('scoring-tab', scoringButton); } } } /** * Performs the core analytical calculation: Weighted Score = (Criterion Score / 10) * Weight * Note: Lower scores are better for 'cost' type criteria, which requires score inversion. */ function calculateMatrix() { // 1. Validate Scoring Matrix existence const matrixEl = document.getElementById('input-matrix'); if (!matrixEl) { alert("Please generate the scoring matrix first by configuring options and criteria."); return; } let results = []; let totalMaxScore = 0; // Maximum possible weighted score (for normalization if needed) // Calculate total max score for context (10 points * weight) criteria.forEach(crit => { totalMaxScore += crit.weight * 10; }); // 2. Iterate through Options (Rows) options.forEach(opt => { let totalWeightedScore = 0; let detailedScores = {}; let missingScores = false; // 3. Iterate through Criteria (Columns) criteria.forEach(crit => { const inputId = `${opt.id}_${crit.id}`; const inputEl = document.getElementById(inputId); if (!inputEl) { console.warn(`Input element missing for ${inputId}`); missingScores = true; return; } const rawValue = inputEl.value.trim().toUpperCase(); let score; let weightedScore = 0; if (rawValue === '' || rawValue === 'N/A') { score = 'N/A'; } else { score = parseFloat(rawValue); if (isNaN(score) || score < 1 || score > 10) { alert(`Invalid score for ${opt.name} / ${crit.name}. Must be 1-10 or N/A.`); missingScores = true; return; } // Analytical Inversion for 'Cost' Type Criteria (Lower score is better) let normalizedScore; if (crit.type === 'cost') { // Invert score: 10 is best, 1 is worst. New Score = 11 - Old Score. normalizedScore = 11 - score; } else { // Benefit: Higher score is better normalizedScore = score; } // Weighted Score Calculation weightedScore = normalizedScore * crit.weight; totalWeightedScore += weightedScore; } detailedScores[crit.id] = { rawScore: rawValue, weightedScore: weightedScore }; }); if (!missingScores) { results.push({ optionId: opt.id, optionName: opt.name, totalWeightedScore: totalWeightedScore, detailedScores: detailedScores }); } }); if (results.length === options.length) { // 4. Sort and Rank (Highest score is Rank 1) results.sort((a, b) => b.totalWeightedScore - a.totalWeightedScore); // 5. Render Dashboard renderRanking(results); renderDetailedMatrix(results, totalMaxScore); // 6. Navigate to Dashboard Tab calculateMatrixAndNavigate(); } } /** * Renders the final ranking list on the dashboard. */ function renderRanking(results) { const container = document.getElementById('ranking-container'); if (!container) return; let html = ''; results.forEach((res, index) => { const rankClass = index === 0 ? 'rank-1' : ''; html += `
#${index + 1} ${res.optionName} ${res.totalWeightedScore.toFixed(0)} Points
`; }); container.innerHTML = html; } /** * Renders the detailed weighted matrix table. */ function renderDetailedMatrix(results, totalMaxScore) { const container = document.getElementById('detailed-matrix-container'); if (!container) return; let tableHtml = ''; tableHtml += ''; criteria.forEach(crit => { const typeLabel = crit.type === 'cost' ? ' (Cost/Inv)' : ' (Benefit)'; tableHtml += ``; }); tableHtml += ''; // Data Rows results.forEach((res) => { tableHtml += ``; let totalScoreDisplay = 0; criteria.forEach(crit => { const scoreData = res.detailedScores[crit.id]; let displayValue = 'N/A'; if (scoreData.rawScore !== 'N/A') { displayValue = `${scoreData.rawScore} * ${crit.weight} = ${scoreData.weightedScore.toFixed(0)}`; totalScoreDisplay += scoreData.weightedScore; } tableHtml += ``; }); // Total Weighted Score column tableHtml += ``; tableHtml += ''; }); // Total Weight Row (Footer) const totalWeight = criteria.reduce((sum, crit) => sum + crit.weight, 0); tableHtml += ``; tableHtml += '
Option / Criterion${crit.name}
Weight: ${crit.weight}${typeLabel}
Total Weighted Score
${res.optionName}${displayValue}${totalScoreDisplay.toFixed(0)}
Total Weights Sum:${totalWeight}
'; container.innerHTML = tableHtml; } /** * Generates and downloads the PDF report of the Decision Matrix. (II.C) */ function downloadMatrixPdf() { // 1. Ensure Dashboard is active for print formatting const dashboardButton = document.querySelector('.tab-button[onclick*="dashboard-tab"]'); if (dashboardButton) { showTab('dashboard-tab', dashboardButton); } // 2. Set temporary title for PDF file name/header const originalTitle = document.title; document.title = `Analytical Decision Matrix Report - ${new Date().toLocaleDateString('en-US')}`; // 3. Trigger the browser's print/PDF dialog window.print(); // 4. Restore the original title after printing setTimeout(() => { document.title = originalTitle; }, 10); }
Scroll to Top