Enter your total estimated expenses per year (in your local currency).
The percentage of your portfolio you plan to withdraw annually (e.g., 4% is common).
Your estimated average annual return on investments (e.g., 7%).
The estimated average annual increase in the cost of living (e.g., 3%).
How many years you expect to save and invest before reaching FIRE.
Your FIRE Number
—
Formula: FIRE Number = Annual Living Expenses / Safe Withdrawal Rate
Required Portfolio = FIRE Number
Note: This calculator uses a simplified model. Real-world FIRE planning involves many more variables.
Projected Portfolio Growth Towards FIRE
What is the FIRE Number?
The FIRE number, an acronym for Financial Independence, Retire Early, represents the estimated amount of investment assets you need to accumulate to cover your living expenses indefinitely without needing to work. It's the cornerstone of the FIRE movement, a lifestyle focused on aggressive saving and investing to achieve financial freedom and the ability to retire much earlier than traditional retirement age. Your FIRE number is a personalized target, reflecting your unique spending habits, investment strategy, and desired lifestyle in early retirement.
Anyone seeking greater control over their time and financial future can benefit from understanding and calculating their FIRE number. This includes young professionals aiming for early retirement, individuals looking to escape the traditional 9-to-5 grind, entrepreneurs planning for financial freedom, and anyone who wants to build a substantial investment portfolio to generate passive income.
A common misconception is that the FIRE number is a static, one-size-fits-all figure. In reality, it's highly dynamic and depends on your personal spending, lifestyle choices, and investment returns. Another misunderstanding is that achieving FIRE means completely stopping all work; many FIRE adherents engage in passion projects or part-time work that aligns with their interests, generating supplemental income. The core idea is removing the *necessity* of working for survival. Calculating your FIRE number is the crucial first step in making this ambitious goal a tangible reality.
{primary_keyword} Formula and Mathematical Explanation
The foundational formula for calculating your FIRE number is elegantly simple, often referred to as the "4% Rule" in its most basic form. It posits that if you can withdraw 4% of your investment portfolio annually to cover your expenses, your portfolio is likely sustainable for a traditional retirement period. To calculate your specific FIRE number, you invert this rule.
The Core Formula:
FIRE Number = Current Annual Living Expenses / Safe Withdrawal Rate (%)
This formula tells you the total investment portfolio value required to sustain your current lifestyle. For example, if your annual expenses are $50,000 and you plan to use a 4% safe withdrawal rate, your FIRE number would be $50,000 / 0.04 = $1,250,000.
Variables Explained:
Current Annual Living Expenses: This is the total amount of money you spend in a typical year on all necessities and discretionary items. Accurately estimating this figure is critical.
Safe Withdrawal Rate (SWR): This is the percentage of your investment portfolio that you can safely withdraw each year without significantly risking depleting your principal over a long retirement period (typically 30+ years). The 4% rule is a widely cited benchmark, derived from historical market data, but can vary based on market conditions, retirement duration, and asset allocation.
FIRE Number Variables Table
Variable
Meaning
Unit
Typical Range/Example
Current Annual Living Expenses
Total cost of living for one year.
Currency (e.g., USD, EUR)
$30,000 – $100,000+
Safe Withdrawal Rate (SWR)
Percentage of portfolio withdrawn annually.
%
3% – 5% (4% is common)
FIRE Number (Target Portfolio Value)
Total investment assets needed.
Currency (e.g., USD, EUR)
(Expenses / SWR)
Advanced Considerations: Growth, Inflation, and Time
While the basic formula is straightforward, achieving FIRE involves compounding growth and the erosive effect of inflation over time. Our calculator incorporates these factors to provide a more realistic projection.
Expected Annual Investment Growth Rate: The average annual return you anticipate from your investments after fees. This is crucial for portfolio growth.
Expected Annual Inflation Rate: The average annual increase in the cost of goods and services. This means your spending power decreases, so your FIRE number needs to account for future inflation.
Years Until FIRE: The timeframe you have to save and invest. The longer you have, the more powerful compounding becomes.
These elements influence not just the target FIRE number but also the required savings rate and how your portfolio grows over time. The goal is to reach a portfolio value large enough that its growth and returns can cover your expenses, adjusted for inflation, even after withdrawals.
Practical Examples (Real-World Use Cases)
Example 1: The Lean FIRE Enthusiast
Scenario: Sarah is 30 years old and aims for a "Lean FIRE" lifestyle. She lives frugally and estimates her annual living expenses at $35,000. She believes a 4% safe withdrawal rate is appropriate for her long retirement horizon. She plans to reach FIRE in 15 years. She conservatively estimates her investments will grow by 7% annually, with inflation at 3%.
Calculation:
FIRE Number: $35,000 / 0.04 = $875,000
Required Portfolio Value (considering growth & inflation over 15 years): Using a more advanced calculation (often done via simulators), let's say the calculator projects this to be approximately $1,150,000 to account for future inflation adjustments and ensure the 4% withdrawal remains meaningful.
Required Savings Rate: To reach ~$1,150,000 in 15 years with 7% growth, Sarah would need to save roughly 30% of her income.
Interpretation: Sarah needs a portfolio of around $1,150,000 to retire in 15 years, drawing $35,000 (adjusted for inflation) annually. This requires significant discipline in her savings rate. This example highlights how the FIRE number calculation provides a concrete savings target.
Example 2: The Fat FIRE Dreamer
Scenario: Mark, 40, enjoys travel and dining out, estimating his current annual expenses at $90,000. He prefers a more conservative 3.5% withdrawal rate due to market volatility concerns and plans for a shorter accumulation phase of 10 years. He anticipates an 8% average annual investment growth and 2.5% inflation.
Calculation:
FIRE Number (Basic): $90,000 / 0.035 = $2,571,429
Required Portfolio Value (considering growth & inflation over 10 years): A more detailed projection might suggest a target of around $2,800,000 to ensure his $90,000 lifestyle (inflation-adjusted) is covered indefinitely.
Required Savings Rate: Reaching ~$2,800,000 in 10 years with 8% growth would necessitate saving approximately 55% of his income.
Interpretation: Mark's higher spending and more conservative withdrawal rate result in a substantially larger FIRE number. Achieving this requires an extremely high savings rate, demonstrating the trade-offs between lifestyle costs, withdrawal rate safety, and the time horizon for reaching financial independence. This illustrates the impact of lifestyle choices on the {primary_keyword} calculation.
How to Use This FIRE Number Calculator
Our FIRE Number Calculator is designed to be intuitive and provide a quick estimate of your financial independence target. Follow these steps to get your personalized FIRE number.
Enter Current Annual Living Expenses: Be as accurate as possible. Review bank statements, credit card bills, and budgeting apps to capture all your spending categories – housing, food, transportation, healthcare, entertainment, etc.
Set Your Safe Withdrawal Rate (SWR): A 4% SWR is a common starting point, but consider your risk tolerance, planned retirement duration, and market outlook. Lower rates (e.g., 3% or 3.5%) offer greater safety margins but require a larger portfolio. Higher rates (e.g., 5%) reduce the portfolio size needed but increase the risk of running out of money.
Estimate Investment Growth Rate: Input your expected average annual return *after* investment fees. Historically, diversified stock portfolios have averaged around 7-10% annually over long periods, but future returns are not guaranteed.
Input Inflation Rate: Use a conservative estimate for future inflation, typically between 2% and 3%. Inflation erodes purchasing power, so your FIRE number must account for rising costs over time.
Specify Years Until FIRE: Enter the number of years you plan to save and invest before you intend to stop working. This helps the calculator project future portfolio growth and inflation impact.
Click "Calculate FIRE Number": The calculator will display your primary FIRE number (the total investment portfolio required) and key intermediate values like the required portfolio size considering growth and inflation, and the estimated savings rate needed.
Reading Your Results:
Primary FIRE Number: This is your estimated target portfolio value.
Required Portfolio Value: This adjusts the basic FIRE number for projected investment growth and inflation over your accumulation period, giving a more dynamic target.
Required Savings Rate: This is an estimate of the percentage of your income you'll need to save annually to reach your target portfolio value within your specified timeframe, assuming the given growth rate.
Decision-Making Guidance:
Use the calculated FIRE number as a motivational goal. If the number seems daunting, consider:
Can you realistically increase your income?
Can you decrease your annual expenses?
Is a slightly higher withdrawal rate acceptable given your risk tolerance?
Can you extend your timeline to FIRE?
Our calculator provides a starting point for planning your path to financial independence and early retirement. Remember to revisit and adjust your calculations periodically as your circumstances change. For more detailed planning, consider consulting a financial advisor.
Key Factors That Affect FIRE Number Results
Several critical factors significantly influence your calculated FIRE number and the feasibility of achieving it. Understanding these elements is key to realistic planning:
Spending Habits: This is the most direct input. Higher annual spending requires a larger portfolio. Reducing expenses is often the most effective lever for lowering your FIRE number and increasing your savings rate. Think about essential vs. discretionary spending.
Safe Withdrawal Rate (SWR) Choice: A higher SWR (e.g., 5%) means you need a smaller portfolio, but it comes with increased risk of outliving your savings, especially during market downturns. A lower SWR (e.g., 3%) provides a greater safety buffer but demands a significantly larger nest egg. The "correct" SWR depends on your risk tolerance, retirement duration, and market conditions.
Investment Growth Rate: Higher expected returns accelerate portfolio growth, reducing the time and savings required. However, relying on overly optimistic growth projections can be dangerous. Diversification across asset classes (stocks, bonds, real estate) and consistency are key.
Inflation: Inflation constantly erodes the purchasing power of money. Your FIRE number must be large enough to sustain your desired lifestyle *in future dollars*. High inflation necessitates a higher FIRE target or a higher savings rate to compensate.
Time Horizon (Years to FIRE): The longer you have to save and invest, the more powerful the effect of compound growth becomes. Starting early significantly reduces the required annual savings rate compared to starting later with the same goal.
Taxes: Investment gains, dividends, and withdrawals are often subject to taxes. Different account types (taxable, tax-deferred, tax-free) have varying tax implications that can impact your net returns and the actual amount you need to save. Failing to account for taxes can lead to shortfalls.
Unexpected Expenses & Life Events: Healthcare costs, family emergencies, or major life changes (divorce, job loss) can drastically alter your spending needs and timeline. Building a buffer or contingency fund is crucial.
Sequence of Returns Risk: This is the risk that poor investment returns occur early in your retirement, coinciding with your withdrawal period. This can severely deplete your portfolio faster than expected, even if long-term average returns are good. A lower SWR helps mitigate this.
Frequently Asked Questions (FAQ)
Q1: Is the 4% rule still relevant for calculating my FIRE number?
The 4% rule is a widely used guideline, but its effectiveness can vary depending on market conditions, withdrawal periods, and portfolio allocation. Some studies suggest a 3.5% or even 3% SWR might be safer for longer retirements or more conservative investors. Our calculator allows you to adjust this rate.
Q2: Do I need to include taxes in my FIRE number calculation?
Absolutely. While our basic calculator doesn't explicitly model taxes, you must account for them. Consider the tax implications of your investment accounts (e.g., 401k, IRA, Roth IRA, taxable brokerage) and how withdrawals will be taxed. You may need a larger FIRE number to cover tax liabilities.
Q3: How do I calculate my accurate annual living expenses?
Track your spending diligently for at least 6-12 months using budgeting apps (like Mint, YNAB) or spreadsheets. Categorize expenses (housing, food, transport, healthcare, fun, etc.) and sum them up for an annual total. Be realistic and include irregular expenses like annual insurance premiums or occasional travel.
Q4: What if my expenses change significantly in retirement?
Your expenses may decrease (e.g., no work commute, mortgage paid off) or increase (e.g., healthcare costs, travel). It's wise to create a projected retirement budget that accounts for these anticipated changes. Adjust your FIRE number accordingly.
Q5: Should I use gross or net income for the savings rate calculation?
The savings rate is typically calculated as a percentage of your *gross* income (income before taxes). This is because it represents the portion of your earnings you are setting aside. However, you need to ensure you have enough *net* income (after taxes) to cover your essential living expenses while still achieving the required savings rate.
Q6: How does housing affect my FIRE number?
Housing is often the largest expense. Owning a home outright (paid-off mortgage) significantly reduces annual expenses compared to renting or having mortgage payments. Factor in property taxes, insurance, and maintenance costs if you own, or rent costs if you don't.
Q7: What if I want to retire before 30 years old? Is the 4% rule safe?
Retiring very early (e.g., before age 50) often requires a more conservative SWR (potentially 3% or lower) due to the extended withdrawal period and increased exposure to sequence of returns risk. The 4% rule was primarily based on 30-year retirement horizons. You might need a larger FIRE number than a simple 4% calculation suggests.
Q8: Can I adjust my FIRE number later if my circumstances change?
Yes! Your FIRE number is not set in stone. It's a dynamic target. Revisit your calculation annually or whenever significant life events occur (job change, marriage, new financial goals). Adjust your savings, expenses, or timeline as needed. The goal is to adapt your plan to your evolving life.
// Function to validate input and display errors
function validateInput(inputId, errorId, minValue, maxValue) {
var input = document.getElementById(inputId);
var errorDiv = document.getElementById(errorId);
var value = parseFloat(input.value);
errorDiv.textContent = "; // Clear previous error
if (isNaN(value)) {
errorDiv.textContent = 'Please enter a valid number.';
return false;
}
if (value < 0) {
errorDiv.textContent = 'Value cannot be negative.';
return false;
}
if (minValue !== undefined && value maxValue) {
errorDiv.textContent = 'Value cannot exceed ' + maxValue + '.';
return false;
}
return true;
}
// Function to validate all inputs
function validateAllInputs() {
var isValid = true;
isValid &= validateInput('annualExpenses', 'annualExpensesError', 0);
isValid &= validateInput('withdrawalRate', 'withdrawalRateError', 0.1, 10); // SWR realistically 0.1% to 10%
isValid &= validateInput('investmentGrowthRate', 'investmentGrowthRateError', 0, 15); // Realistic growth 0% to 15%
isValid &= validateInput('inflationRate', 'inflationRateError', 0, 10); // Realistic inflation 0% to 10%
isValid &= validateInput('yearsToFI', 'yearsToFIError', 1); // Must have at least 1 year
return isValid;
}
// Function to calculate compound growth
function calculateFutureValue(principal, rate, periods) {
var r = rate / 100;
return principal * Math.pow(1 + r, periods);
}
// Function to calculate present value needed for future expenses
function calculatePresentValueForFutureExpenses(futureExpenses, rate, periods) {
var r = rate / 100;
return futureExpenses / Math.pow(1 + r, periods);
}
// Main calculation function
function calculateFIRENumber() {
if (!validateAllInputs()) {
return;
}
var annualExpenses = parseFloat(document.getElementById('annualExpenses').value);
var withdrawalRatePercent = parseFloat(document.getElementById('withdrawalRate').value);
var investmentGrowthRatePercent = parseFloat(document.getElementById('investmentGrowthRate').value);
var inflationRatePercent = parseFloat(document.getElementById('inflationRate').value);
var yearsToFI = parseInt(document.getElementById('yearsToFI').value);
var withdrawalRate = withdrawalRatePercent / 100;
var investmentGrowthRate = investmentGrowthRatePercent / 100;
var inflationRate = inflationRatePercent / 100;
// Basic FIRE Number
var fireNumber = annualExpenses / withdrawalRate;
// Calculate future annual expenses considering inflation
var annualExpensesAtFI = annualExpenses * Math.pow(1 + inflationRate, yearsToFI);
// Calculate the portfolio needed to support inflated future expenses
var requiredPortfolioForInflatedExpenses = annualExpensesAtFI / withdrawalRate;
// Calculate current savings needed to reach requiredPortfolioForInflatedExpenses
// This requires solving for P in FV = P * (1+r)^n + PMT * [((1+r)^n – 1) / r]
// For simplicity, let's calculate the target portfolio value adjusted for inflation
// and then use a savings rate approximation. A full FV of annuity calculation is complex.
// We'll use a simplified approach by calculating the future value needed and deriving a savings rate.
// Simplified: Calculate required future value and then estimate savings rate needed.
// This is an approximation as it doesn't perfectly model contributions compounding.
// A more accurate calculation would involve solving for the periodic payment (savings)
// in a future value of an annuity formula.
var requiredSavingsRate = 0;
if (investmentGrowthRate > 0) {
// FV = P * [((1 + r)^n – 1) / r]
// P = FV * r / ((1 + r)^n – 1)
// Here, FV is the target portfolio value minus initial savings (if any)
// For simplicity, let's assume initial savings = 0 for savings rate calculation.
var numerator = requiredPortfolioForInflatedExpenses * investmentGrowthRate;
var denominator = Math.pow(1 + investmentGrowthRate, yearsToFI) – 1;
if (denominator > 0) {
var annualSavingsNeeded = numerator / denominator;
// Assuming annualSavingsNeeded is a percentage of annualExpenses, then we derive savings rate from income.
// This is tricky without knowing income. Let's express it as a ratio to expenses.
// A common approach is to state the required portfolio and imply the savings rate.
// For this example, let's calculate the required savings as a % of expenses, which isn't directly savings rate but an indicator.
// Let's redefine this: Calculate the effective savings needed relative to target portfolio.
// A common interpretation is "how much of your income must be saved". We don't have income, so we'll show required portfolio.
// Let's focus on required portfolio and maybe a conceptual savings rate.
// To simplify, we'll use a common rule of thumb or link to another calculator for detailed savings rate.
// For this calculator, we will state the target portfolio and derived annual spending.
// We'll leave "Required Savings Rate" as conceptual or link to another tool.
// For now, let's calculate a conceptual savings rate IF we assume income = 1.5 * annual expenses (a common FI ratio).
var estimatedIncome = annualExpenses * 1.5; // Example assumption
if (estimatedIncome > 0) {
requiredSavingsRate = (annualSavingsNeeded / estimatedIncome) * 100;
if (requiredSavingsRate > 100) requiredSavingsRate = 100; // Cap at 100%
} else {
requiredSavingsRate = 0; // Cannot calculate if income is zero
}
} else {
requiredSavingsRate = Infinity; // Growth rate is 0, impossible to reach target unless target is 0
}
} else {
requiredSavingsRate = (requiredPortfolioForInflatedExpenses === 0) ? 0 : Infinity;
}
// Display Results
document.getElementById('fireNumberResult').textContent = formatCurrency(fireNumber);
document.getElementById('requiredPortfolioValue').textContent = 'Target Portfolio (Adjusted for Inflation): ' + formatCurrency(requiredPortfolioForInflatedExpenses);
document.getElementById('annualSpendingAtFI').textContent = 'Estimated Annual Spending at FIRE (Inflation Adjusted): ' + formatCurrency(annualExpensesAtFI);
// Displaying conceptual savings rate – needs careful wording
if (requiredSavingsRate === Infinity) {
document.getElementById('requiredSavingsRate').textContent = 'Required Savings Rate: Requires significant contributions or higher growth.';
} else if (requiredSavingsRate > 0) {
document.getElementById('requiredSavingsRate').textContent = 'Estimated Savings Rate Needed: ~' + requiredSavingsRate.toFixed(1) + '% (based on assumed income)';
} else {
document.getElementById('requiredSavingsRate').textContent = 'Required Savings Rate: N/A (or very low)';
}
// Update Chart
updateFIREProjectionChart(annualExpenses, withdrawalRatePercent, investmentGrowthRatePercent, inflationRatePercent, yearsToFI, requiredPortfolioForInflatedExpenses);
}
// Helper function to format currency
function formatCurrency(amount) {
// Basic formatting, assumes USD for display example, but works for any currency symbol.
// Adapt locale and currency as needed.
return amount.toLocaleString('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0 });
}
// Function to reset calculator
function resetCalculator() {
document.getElementById('annualExpenses').value = ";
document.getElementById('withdrawalRate').value = '4';
document.getElementById('investmentGrowthRate').value = '7';
document.getElementById('inflationRate').value = '3';
document.getElementById('yearsToFI').value = ";
document.getElementById('annualExpensesError').textContent = ";
document.getElementById('withdrawalRateError').textContent = ";
document.getElementById('investmentGrowthRateError').textContent = ";
document.getElementById('inflationRateError').textContent = ";
document.getElementById('yearsToFIError').textContent = ";
document.getElementById('fireNumberResult').textContent = '–';
document.getElementById('requiredPortfolioValue').textContent = ";
document.getElementById('annualSpendingAtFI').textContent = ";
document.getElementById('requiredSavingsRate').textContent = ";
// Clear chart
var canvas = document.getElementById('fireProjectionChart');
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = 0; // Clear canvas content and reset size
canvas.height = 0;
}
// Function to copy results
function copyResults() {
var fireNumber = document.getElementById('fireNumberResult').textContent;
var requiredPortfolio = document.getElementById('requiredPortfolioValue').textContent;
var annualSpending = document.getElementById('annualSpendingAtFI').textContent;
var savingsRate = document.getElementById('requiredSavingsRate').textContent;
var assumptions = [];
var inputs = document.querySelectorAll('.loan-calc-container .input-group');
inputs.forEach(function(group) {
var label = group.querySelector('label').textContent;
var valueInput = group.querySelector('input');
var value = valueInput ? valueInput.value : 'N/A';
if (value && value !== " && value !== 'undefined') {
assumptions.push(label + ": " + value + (valueInput.type === 'number' && label.includes('%') ? '%' : "));
}
});
var textToCopy = "— FIRE Number Calculation Results —\n\n";
textToCopy += "Primary FIRE Number: " + fireNumber + "\n";
textToCopy += requiredPortfolio + "\n";
textToCopy += annualSpending + "\n";
textToCopy += savingsRate + "\n\n";
textToCopy += "Key Assumptions:\n";
textToCopy += assumptions.join('\n');
// Use a temporary textarea for copying
var textArea = document.createElement("textarea");
textArea.value = textToCopy;
textArea.style.position = "fixed";
textArea.style.left = "-9999px";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
var successful = document.execCommand('copy');
var msg = successful ? 'Results copied to clipboard!' : 'Failed to copy results.';
console.log(msg);
// Optionally show a temporary message to the user
alert(msg);
} catch (err) {
console.error('Unable to copy results.', err);
alert('Failed to copy results.');
}
document.body.removeChild(textArea);
}
// Charting Functionality
function updateFIREProjectionChart(initialExpenses, withdrawalRatePercent, investmentGrowthRatePercent, inflationRatePercent, yearsToFI, targetPortfolioValue) {
var canvas = document.getElementById('fireProjectionChart');
var ctx = canvas.getContext('2d');
// Clear previous chart
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Responsive resizing: Set canvas dimensions based on container width
var chartContainer = canvas.parentElement;
canvas.width = chartContainer.clientWidth; // Use clientWidth for responsive width
canvas.height = Math.min(chartContainer.clientWidth * 0.5, 400); // Maintain aspect ratio, cap height
var withdrawalRate = withdrawalRatePercent / 100;
var investmentGrowthRate = investmentGrowthRatePercent / 100;
var inflationRate = inflationRatePercent / 100;
var years = Array.from({ length: yearsToFI + 1 }, (_, i) => i);
var portfolioValues = [];
var expensesOverTime = [];
var currentPortfolio = 0; // Start from 0 savings for projection baseline
var currentExpenses = initialExpenses;
// Calculate initial savings needed based on target portfolio and growth rate
// This is a rough estimation: Future Value = P * (1+r)^n => P = FV / (1+r)^n
var initialSavingsNeeded = targetPortfolioValue / Math.pow(1 + investmentGrowthRate, yearsToFI);
for (var i = 0; i 0 && expensesOverTime[expensesOverTime.length – 1] !== currentExpenses) {
expensesOverTime[yearsToFI] = currentExpenses;
}
// Draw Chart
var chartHeight = canvas.height;
var chartWidth = canvas.width;
var margin = { top: 20, right: 30, bottom: 40, left: 60 }; // Increased left margin for Y-axis labels
var plotAreaWidth = chartWidth – margin.left – margin.right;
var plotAreaHeight = chartHeight – margin.top – margin.bottom;
if (plotAreaWidth <= 0 || plotAreaHeight <= 0) return; // Prevent drawing if dimensions are invalid
ctx.save();
ctx.translate(margin.left, margin.top);
// Y-axis for Portfolio Value
var portfolioMax = Math.max(…portfolioValues) || 1;
var expensesMax = Math.max(…expensesOverTime) || 1;
var yAxisMax = Math.max(portfolioMax, expensesMax) * 1.1; // Add 10% buffer
ctx.font = '12px Arial';
ctx.fillStyle = '#333';
// Draw Portfolio Y-axis labels and line
var portfolioYScale = plotAreaHeight / yAxisMax;
var numYTicks = 5;
for (var i = 0; i <= numYTicks; i++) {
var value = (yAxisMax / numTicks) * i;
var yPos = plotAreaHeight – (value * portfolioYScale);
ctx.fillText(formatCurrency(value).replace(/[$,]/g, ''), -5, yPos); // Format and remove symbols for axis
ctx.beginPath();
ctx.moveTo(-5, yPos);
ctx.lineTo(0, yPos);
ctx.strokeStyle = '#ccc';
ctx.stroke();
}
ctx.fillText('Portfolio Value', -margin.left + 10, -10); // Y-axis label
// Draw Expenses Y-axis labels (optional, could share axis if scaling is similar)
// For clarity, let's just use one Y-axis and plot both series against it.
// X-axis labels (Years)
ctx.textAlign = 'center';
var xAxisXScale = plotAreaWidth / yearsToFI;
for (var i = 0; i < years.length; i++) {
var xPos = i * xAxisXScale;
ctx.fillText(years[i], xPos, plotAreaHeight + 20);
}
ctx.textAlign = 'center';
ctx.fillText('Years to FIRE', plotAreaWidth / 2, plotAreaHeight + 40);
// Draw Portfolio Growth Line
ctx.beginPath();
ctx.strokeStyle = 'var(–primary-color)';
ctx.lineWidth = 2;
for (var i = 0; i < portfolioValues.length; i++) {
var xPos = i * xAxisXScale;
var yPos = plotAreaHeight – (portfolioValues[i] * portfolioYScale);
if (i === 0) {
ctx.moveTo(xPos, yPos);
} else {
ctx.lineTo(xPos, yPos);
}
}
ctx.stroke();
// Draw Expenses Growth Line
ctx.beginPath();
ctx.strokeStyle = 'var(–success-color)';
ctx.lineWidth = 2;
for (var i = 0; i < expensesOverTime.length; i++) {
var xPos = i * xAxisXScale;
var yPos = plotAreaHeight – (expensesOverTime[i] * portfolioYScale); // Use the same scale
if (i === 0) {
ctx.moveTo(xPos, yPos);
} else {
ctx.lineTo(xPos, yPos);
}
}
ctx.stroke();
// Add Legend
ctx.textAlign = 'left';
ctx.font = '14px Arial';
var legendY = -margin.top + 5; // Position legend near top
var legendSpacing = 120;
// Portfolio Legend Item
ctx.fillStyle = 'var(–primary-color)';
ctx.fillRect(margin.left, legendY, 15, 15);
ctx.fillStyle = '#333';
ctx.fillText('Projected Portfolio', margin.left + 20, legendY + 12);
// Expenses Legend Item
ctx.fillStyle = 'var(–success-color)';
ctx.fillRect(margin.left + legendSpacing, legendY, 15, 15);
ctx.fillStyle = '#333';
ctx.fillText('Inflation-Adjusted Expenses', margin.left + legendSpacing + 20, legendY + 12);
ctx.restore(); // Restore original canvas state
}
// Initial calculation on load if inputs have default values
document.addEventListener('DOMContentLoaded', function() {
// Set default values if they are not already set by the HTML
if (document.getElementById('withdrawalRate').value === '') document.getElementById('withdrawalRate').value = '4';
if (document.getElementById('investmentGrowthRate').value === '') document.getElementById('investmentGrowthRate').value = '7';
if (document.getElementById('inflationRate').value === '') document.getElementById('inflationRate').value = '3';
// Trigger calculation if defaults are set and valid inputs exist
if (document.getElementById('annualExpenses').value && document.getElementById('yearsToFI').value) {
calculateFIRENumber();
}
// Add event listeners for real-time updates (optional, can be performance intensive)
var inputs = document.querySelectorAll('.loan-calc-container input');
inputs.forEach(function(input) {
input.addEventListener('input', function() {
// Re-validate on input
var id = this.id;
var errorId = id + 'Error';
var minValue, maxValue;
if (id === 'annualExpenses') { minValue = 0; }
else if (id === 'withdrawalRate') { minValue = 0.1; maxValue = 10; }
else if (id === 'investmentGrowthRate') { minValue = 0; maxValue = 15; }
else if (id === 'inflationRate') { minValue = 0; maxValue = 10; }
else if (id === 'yearsToFI') { minValue = 1; }
validateInput(id, errorId, minValue, maxValue);
// Recalculate if all fields are filled and valid
if (validateAllInputs()) {
calculateFIRENumber();
} else {
// Clear results if inputs become invalid
document.getElementById('fireNumberResult').textContent = '–';
document.getElementById('requiredPortfolioValue').textContent = '';
document.getElementById('annualSpendingAtFI').textContent = '';
document.getElementById('requiredSavingsRate').textContent = '';
// Optionally clear chart too
var canvas = document.getElementById('fireProjectionChart');
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = 0; canvas.height = 0;
}
});
});
});