Loan Payoff Calculator

Loan Payoff Calculator

$${interestSaved.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2})}

Original Payoff Date

${originalLoan.payoffDate}

Accelerated Payoff Date

${acceleratedLoan.payoffDate}

Time Saved

${yearsSaved} years and ${remainingMonths} months

`; // --- CHART GENERATION --- renderChart(originalLoan, acceleratedLoan); // --- AMORTIZATION TABLE GENERATION --- scheduleDiv.innerHTML = generateScheduleHTML(acceleratedLoan.schedule, 'Accelerated Payoff Schedule'); resultsArea.style.display = 'block'; } function calculateAmortization(withExtraPayment) { const getValue = id => parseFloat(document.getElementById(id)?.value) || 0; const loanBalance = getValue('loanBalance'); const annualRate = getValue('interestRate'); const monthlyPayment = getValue('monthlyPayment'); const extraPayment = withExtraPayment ? getValue('extraPayment') : 0; if (loanBalance <= 0 || annualRate <= 0 || monthlyPayment <= 0) return { schedule: [], totalInterest: 0, totalMonths: 0, payoffDate: 'N/A' }; const monthlyRate = annualRate / 100 / 12; const totalMonthlyPayment = monthlyPayment + extraPayment; // Check if payment covers interest if (totalMonthlyPayment <= loanBalance * monthlyRate) { alert("The monthly payment is not enough to cover the interest. The loan will never be paid off."); return { schedule: [], totalInterest: 0, totalMonths: 0, payoffDate: 'N/A' }; } let balance = loanBalance; let totalInterest = 0; let months = 0; const schedule = []; const yearlyData = {}; while (balance > 0) { months++; const interestPaid = balance * monthlyRate; const principalPaid = totalMonthlyPayment - interestPaid; balance -= principalPaid; totalInterest += interestPaid; const currentYear = Math.ceil(months / 12); if (!yearlyData[currentYear]) { yearlyData[currentYear] = { principal: 0, interest: 0, balance: 0 }; } yearlyData[currentYear].principal += principalPaid; yearlyData[currentYear].interest += interestPaid; yearlyData[currentYear].balance = Math.max(0, balance); } for (const year in yearlyData) { schedule.push({ year: year, principalPaid: yearlyData[year].principal, interestPaid: yearlyData[year].interest, endingBalance: yearlyData[year].balance }); } const payoffDate = new Date(); payoffDate.setMonth(payoffDate.getMonth() + months); const payoffDateString = payoffDate.toLocaleString('en-US', { month: 'long', year: 'numeric' }); return { schedule, totalInterest, totalMonths: months, payoffDate: payoffDateString }; } function generateScheduleHTML(scheduleData, title) { let tableHTML = `

${title}

`; scheduleData.forEach(row => { tableHTML += ` `; }); tableHTML += `
Year Principal Paid Interest Paid Ending Balance
${row.year} $${row.principalPaid.toFixed(2)} $${row.interestPaid.toFixed(2)} $${row.endingBalance.toFixed(2)}
`; return tableHTML; } function renderChart(original, accelerated) { const ctx = document.getElementById('payoffChart'); if (!ctx) return; const originalData = []; const acceleratedData = []; let balance = parseFloat(document.getElementById('loanBalance').value); originalData.push(balance); acceleratedData.push(balance); original.schedule.forEach(row => originalData.push(row.endingBalance)); accelerated.schedule.forEach(row => acceleratedData.push(row.endingBalance)); const labels = Array.from({ length: originalData.length }, (_, i) => `Year ${i}`); if (payoffChartInstance) { payoffChartInstance.destroy(); } payoffChartInstance = new Chart(ctx, { type: 'line', data: { labels: labels, datasets: [ { label: 'Original Payoff', data: originalData, borderColor: 'rgb(239, 68, 68)', backgroundColor: 'rgba(239, 68, 68, 0.5)', tension: 0.1 }, { label: 'Accelerated Payoff', data: acceleratedData, borderColor: 'rgb(59, 130, 246)', backgroundColor: 'rgba(59, 130, 246, 0.5)', tension: 0.1 } ] }, options: { responsive: true, plugins: { title: { display: true, text: 'Loan Balance Over Time' } }, scales: { y: { title: { display: true, text: 'Loan Balance ($)' } } } } }); } function downloadPDF() { const { jsPDF } = window.jspdf; const pdfContent = document.getElementById('pdf-output'); const pdfTitle = document.getElementById('pdf-title'); if (!pdfContent || !pdfTitle) return; pdfTitle.style.display = 'block'; html2canvas(pdfContent, { scale: 2 }).then(canvas => { pdfTitle.style.display = 'none'; const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const imgProps = pdf.getImageProperties(imgData); const imgWidth = pdfWidth - 20; const imgHeight = (imgProps.height * imgWidth) / imgProps.width; pdf.addImage(imgData, 'PNG', 10, 10, imgWidth, imgHeight); pdf.save('Loan-Payoff-Analysis.pdf'); }); } });
Scroll to Top