Annual Savings Rate Optimizer

Annual Savings Rate Optimizer

Current Monthly Income

No income sources added yet.

Total Monthly Income: $0.00 | Total Annual Income: $0.00

Current Monthly Expenses

No expense categories added yet.

Total Monthly Expenses: $0.00 | Total Annual Expenses: $0.00

Current Savings Status

Monthly Savings: $0.00

Annual Savings: $0.00

Current Savings Rate: 0.00%

Optimize Your Savings Rate

Adjust your monthly income and expense amounts below to see the impact on your savings rate. Original amounts are shown for reference.

Add income and expenses in previous tabs to start optimizing.

Optimized Savings Status

New Total Monthly Income: $0.00

New Total Monthly Expenses: $0.00

New Monthly Savings: $0.00

New Annual Savings: $0.00

Optimized Savings Rate: 0.00%

Change in Monthly Savings: $0.00

Optimization Summary & Export

Your optimization summary will appear here.

Monthly Savings: $${monthlySavings.toFixed(2)}

Annual Savings: $${annualSavings.toFixed(2)}

Current Savings Rate: ${savingsRate.toFixed(2)}%

`; return { monthlySavings, annualSavings, savingsRate, totalMonthlyIncome, totalMonthlyExpenses }; } // --- Optimization (Tab 3) --- function asro_populateOptimizationArea() { const area = document.getElementById('asroOptimizationArea'); area.innerHTML = ''; let contentHTML = ''; if (asro_incomeSources.length > 0) { contentHTML += `

Adjust Income Sources:

`; asro_incomeSources.forEach(src => { contentHTML += ``; }); contentHTML += `
SourceCurrent Monthly ($)Adjusted Monthly ($)
${src.name}${src.amount.toFixed(2)}
`; } if (asro_expenseCategories.length > 0) { contentHTML += `

Adjust Expense Categories:

`; asro_expenseCategories.forEach(cat => { contentHTML += ``; }); contentHTML += `
CategoryCurrent Monthly ($)Adjusted Monthly ($)
${cat.name}${cat.amount.toFixed(2)}
`; } if (!contentHTML) { area.innerHTML = '

Add income and expenses in previous tabs to start optimizing.

'; } else { area.innerHTML = contentHTML; } asro_recalculateOptimizedScenario(); // Initial calculation for this tab } function asro_updateAdjustedValue(type, id, value) { const list = type === 'income' ? asro_incomeSources : asro_expenseCategories; const item = list.find(i => i.id === id); if (item) { item.adjustedAmount = parseFloat(value) >= 0 ? parseFloat(value) : 0; // Ensure original input field reflects this if it was an invalid entry (e.g. negative) event.target.value = item.adjustedAmount.toFixed(2); } asro_recalculateOptimizedScenario(); } function asro_recalculateOptimizedScenario() { const totalAdjustedMonthlyIncome = asro_incomeSources.reduce((sum, src) => sum + src.adjustedAmount, 0); const totalAdjustedMonthlyExpenses = asro_expenseCategories.reduce((sum, cat) => sum + cat.adjustedAmount, 0); const newMonthlySavings = totalAdjustedMonthlyIncome - totalAdjustedMonthlyExpenses; const newAnnualSavings = newMonthlySavings * 12; const newSavingsRate = totalAdjustedMonthlyIncome > 0 ? (newMonthlySavings / totalAdjustedMonthlyIncome * 100) : 0; const currentSavingsData = asro_calculateAndDisplayCurrentSavings(); // to get original monthly savings const changeInMonthlySavings = newMonthlySavings - currentSavingsData.monthlySavings; const displayDiv = document.getElementById('asroOptimizedSavingsDisplay'); if(displayDiv) { displayDiv.innerHTML = `

Optimized Savings Status

New Total Monthly Income: $${totalAdjustedMonthlyIncome.toFixed(2)}

New Total Monthly Expenses: $${totalAdjustedMonthlyExpenses.toFixed(2)}

New Monthly Savings: $${newMonthlySavings.toFixed(2)}

New Annual Savings: $${newAnnualSavings.toFixed(2)}

Optimized Savings Rate: ${newSavingsRate.toFixed(2)}%

Change in Monthly Savings: ${changeInMonthlySavings >=0 ? '+' : ''}$${changeInMonthlySavings.toFixed(2)}

`; } return { totalAdjustedMonthlyIncome, totalAdjustedMonthlyExpenses, newMonthlySavings, newAnnualSavings, newSavingsRate, changeInMonthlySavings }; } // --- Summary & Export (Tab 4) --- function asro_displayOptimizationSummary() { const previewDiv = document.getElementById('asroReportPreview'); const current = asro_calculateAndDisplayCurrentSavings(); // Get current figures const optimized = asro_recalculateOptimizedScenario(); // Get optimized figures let changesMadeHTML = "

Summary of Changes Made:

    "; let hasChanges = false; asro_incomeSources.forEach(src => { if (src.amount !== src.adjustedAmount) { changesMadeHTML += `
  • Income '${src.name}': $${src.amount.toFixed(2)} -> $${src.adjustedAmount.toFixed(2)} (Change: $${(src.adjustedAmount - src.amount).toFixed(2)})
  • `; hasChanges = true; } }); asro_expenseCategories.forEach(cat => { if (cat.amount !== cat.adjustedAmount) { changesMadeHTML += `
  • Expense '${cat.name}': $${cat.amount.toFixed(2)} -> $${cat.adjustedAmount.toFixed(2)} (Change: $${(cat.adjustedAmount - cat.amount).toFixed(2)})
  • `; hasChanges = true; } }); if (!hasChanges) changesMadeHTML += "
  • No changes modeled for optimization.
  • "; changesMadeHTML += "
"; previewDiv.innerHTML = `

Current vs. Optimized Scenario

Current Annual Savings: $${current.annualSavings.toFixed(2)} (Rate: ${current.savingsRate.toFixed(2)}%)

Optimized Annual Savings: $${optimized.newAnnualSavings.toFixed(2)} (Rate: ${optimized.newSavingsRate.toFixed(2)}%)

Total Annual Improvement: $${(optimized.newAnnualSavings - current.annualSavings).toFixed(2)}


${changesMadeHTML} `; asro_renderSavingsRateChart(current.savingsRate, optimized.newSavingsRate); } function asro_renderSavingsRateChart(currentRate, optimizedRate) { const chartContainer = document.getElementById('asroSavingsRateChartContainer'); const canvas = document.getElementById('asroSavingsRateChart'); if (!currentRate && !optimizedRate && currentRate !==0 && optimizedRate !==0) { // if both are undefined or null (but not zero) chartContainer.style.display = 'none'; return; } chartContainer.style.display = 'block'; if (asro_savingsRateChartInstance) { asro_savingsRateChartInstance.destroy(); } asro_savingsRateChartInstance = new Chart(canvas, { type: 'bar', data: { labels: ['Current Savings Rate', 'Optimized Savings Rate'], datasets: [{ label: 'Savings Rate (%)', data: [currentRate > 0 ? currentRate : 0, optimizedRate > 0 ? optimizedRate : 0], // Ensure non-negative for chart backgroundColor: [ 'rgba(255, 193, 7, 0.6)', // warning-color somewhat 'rgba(76, 175, 80, 0.6)' // accent-color ], borderColor: [ 'rgba(255, 193, 7, 1)', 'rgba(76, 175, 80, 1)' ], borderWidth: 1 }] }, options: { responsive: true, maintainAspectRatio: true, scales: { y: { beginAtZero: true, ticks: { callback: function(value) { return value + "%" } } } }, plugins: { legend: { display: false }, title: { display: true, text: 'Savings Rate Comparison' } } } }); } function asro_generatePdf() { const current = asro_calculateAndDisplayCurrentSavings(); const optimized = asro_recalculateOptimizedScenario(); if (!current || !optimized) { alert("Please ensure data is entered and calculations are complete."); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF(); let yPos = 20; const primaryColor = getComputedStyle(document.documentElement).getPropertyValue('--primary-color').trim(); const accentColor = getComputedStyle(document.documentElement).getPropertyValue('--accent-color').trim(); const textColor = getComputedStyle(document.documentElement).getPropertyValue('--text-color').trim(); const toCurrency = (num) => `$${num.toFixed(2)}`; doc.setFontSize(20); doc.setTextColor(primaryColor); doc.text("Annual Savings Rate Optimization Plan", doc.internal.pageSize.getWidth() / 2, yPos, { align: 'center' }); yPos += 15; function addSectionTitle(title) { if (yPos > 260) { doc.addPage(); yPos = 20; } doc.setFontSize(14); doc.setTextColor(primaryColor); doc.text(title, 14, yPos); yPos += 8; doc.setFontSize(10); doc.setTextColor(textColor); } function addDataRow(label, valueStr) { if (yPos > 275) { doc.addPage(); yPos = 20; } doc.text(`${label}:`, 14, yPos); doc.text(valueStr, 80, yPos); yPos += 6; } // Current Financials addSectionTitle("Current Financial Summary (Monthly)"); addDataRow("Total Income", toCurrency(current.totalMonthlyIncome)); addDataRow("Total Expenses", toCurrency(current.totalMonthlyExpenses)); addDataRow("Monthly Savings", toCurrency(current.monthlySavings)); addDataRow("Annual Savings", toCurrency(current.annualSavings)); addDataRow("Savings Rate", `${current.savingsRate.toFixed(2)}%`); yPos += 4; // Optimized Financials addSectionTitle("Optimized Financial Summary (Monthly)"); addDataRow("New Total Income", toCurrency(optimized.totalAdjustedMonthlyIncome)); addDataRow("New Total Expenses", toCurrency(optimized.totalAdjustedMonthlyExpenses)); addDataRow("New Monthly Savings", toCurrency(optimized.newMonthlySavings)); doc.setTextColor(accentColor); addDataRow("New Annual Savings", toCurrency(optimized.newAnnualSavings)); addDataRow("New Savings Rate", `${optimized.newSavingsRate.toFixed(2)}%`); doc.setTextColor(textColor); addDataRow("Improvement in Annual Savings", toCurrency(optimized.newAnnualSavings - current.annualSavings)); yPos += 4; // Table of Changes let changes = []; asro_incomeSources.forEach(src => { if (src.amount !== src.adjustedAmount) changes.push([src.name (Income), toCurrency(src.amount), toCurrency(src.adjustedAmount), toCurrency(src.adjustedAmount - src.amount)]) }); asro_expenseCategories.forEach(cat => { if (cat.amount !== cat.adjustedAmount) changes.push([cat.name (Expense), toCurrency(cat.amount), toCurrency(cat.adjustedAmount), toCurrency(cat.adjustedAmount - cat.amount)]) }); if (changes.length > 0) { if (yPos > 240) { doc.addPage(); yPos = 20; } addSectionTitle("Summary of Changes Made (Monthly)"); doc.autoTable({ startY: yPos, head: [['Item (Type)', 'Original Amt ($)', 'Adjusted Amt ($)', 'Change ($)']], body: changes, theme: 'grid', headStyles: { fillColor: primaryColor, textColor: '#ffffff' }, styles: { fontSize: 9, cellPadding: 1.5 }, didDrawPage: (d) => { yPos = d.cursor.y; } }); } else { doc.text("No specific changes were modeled in the optimization step.", 14, yPos); } doc.save('savings_rate_optimization_plan.pdf'); } // Initialize document.addEventListener('DOMContentLoaded', () => { asro_showTab(0); asro_renderIncomeSources(); asro_updateTotalIncomeDisplay(); asro_renderExpenseCategories(); asro_updateTotalExpensesDisplay(); asro_calculateAndDisplayCurrentSavings(); // Initial call // Demo Data asro_incomeSources.push({id:'inc_001', name:'Salary', amount: 4000, adjustedAmount: 4000}); asro_incomeSources.push({id:'inc_002', name:'Freelance Work', amount: 500, adjustedAmount: 600}); asro_expenseCategories.push({id:'exp_001', name:'Rent/Mortgage', amount:1500, adjustedAmount:1500}); asro_expenseCategories.push({id:'exp_002', name:'Groceries', amount:400, adjustedAmount:350}); asro_expenseCategories.push({id:'exp_003', name:'Dining Out', amount:200, adjustedAmount:100}); asro_renderIncomeSources(); asro_updateTotalIncomeDisplay(); asro_renderExpenseCategories(); asro_updateTotalExpensesDisplay(); asro_calculateAndDisplayCurrentSavings(); });
Scroll to Top