Public
Edited
Jun 29, 2023
5 forks
Importers
13 stars
Insert cell
Insert cell
Insert cell
viewof duration = Inputs.range([1, 30], {label: "# of Years", step: 1, value: 30})
Insert cell
viewof purchasePrice = Inputs.range([100000, 1000000], {label: "Purchase Price", step: 50000, value: 650000})
Insert cell
viewof downPayment = Inputs.range([0, 500000], {label: "Down Payment", step: 10000})
Insert cell
viewof interestRate = Inputs.range([2, 8], {label: "Interest Rate", step: .1, value: 5.5, title: "testing"})
Insert cell
Insert cell
Plot.plot({
marks: [
Plot.areaY(tidyData.filter(d => d.metric != 'Total Amount Paid'),
Plot.stackY({order: ["Total Principal Paid", "Total Interest Paid"],
x: "key", y: "value", fill: "metric"})),
Plot.ruleY([0])
],
color: {
domain: ["Total Principal Paid", "Total Interest Paid"],
range: ["steelblue", "darkorange"],
legend: true
},
y: {
tickFormat: "s",
}
})
Insert cell
Insert cell
Inputs.table(mortgageData, {
format: {
'Monthly Payment': d => formatMoney(d),
'Interest Payment': d => formatMoney(d),
'Percent Interest': d => formatPercent(d),
'Principal Payment': d => formatMoney(d),
'Percent Principal': d => formatPercent(d),
'Total Interest Paid': d => formatMoney(d),
'Total Principal Paid': d => formatMoney(d),
'Total Amount Paid': d => formatMoney(d),
'Total Mortgage Remaining': d => formatMoney(d),
}
})
Insert cell
Insert cell
function calculateMortgageData(interest, payments, amount) {
// We use "let" here since the value will change, i.e. we make mortgage payments each month, so our total
let mortgageRemaining = amount;
let totalInterestPaid = 0;
let totalPrincipalPaid = 0;
// Calculate the monthly mortage payment. To get a monthly payment, we divide the interest rate by 12
const monthlyMortgagePayment = financial.pmt(interest, payments, amount) * -1;
// Multiply by -1, since it default to a negative value

// This is the array we will show in our table cell. Here we loop through each payment
// and figure out what values will be.
const mortgageArray = d3.range(payments).map((d,i) => {

// The interest payment portion of that month
const monthlyInterestPayment = financial.ipmt(interest, i + 1, payments, amount) * -1;
const monthlyPrincipalPayment = monthlyMortgagePayment - monthlyInterestPayment;
// Calculate the remaining mortgage amount, which you do by subtracting the principal payment
mortgageRemaining = mortgageRemaining - monthlyPrincipalPayment;

// Add to the total interest and principal amounts paid
totalInterestPaid += monthlyInterestPayment;
totalPrincipalPaid += monthlyPrincipalPayment;

// Return object, which contains all the key-value pairs
return { 'Payment #': (i + 1), // We add 1 since indexes start at 0
'Year': Math.floor((i + 1) / 12) + 1, // This calculates the year by dividing the index by 12
'Monthly Payment': monthlyMortgagePayment,
'Interest Payment': monthlyInterestPayment,
'Percent Interest': monthlyInterestPayment / monthlyMortgagePayment,
'Principal Payment': monthlyPrincipalPayment,
'Percent Principal': monthlyPrincipalPayment / monthlyMortgagePayment,
'Total Interest Paid': totalInterestPaid,
'Total Principal Paid': totalPrincipalPaid,
'Total Amount Paid': totalPrincipalPaid + totalInterestPaid,
'Total Mortgage Remaining': mortgageRemaining
}
});
return mortgageArray
}
Insert cell
mortgageData = calculateMortgageData(monthlyInterestRate, numberPayments, mortgage)
Insert cell
Insert cell
Plot.plot({
marks: [
Plot.lineY(mortgageData, {x: "Payment #", y: "Percent Interest"}),
Plot.ruleY([0])
]
})
Insert cell
Insert cell
Insert cell
Inputs.table(tidyData)
Insert cell
function tidy(data) {
const key = 'Payment #'; // Choose a key, which we'll make the payment #, aka - Month
const returnArray = []; // This is the array we'll return
data.forEach(row => { // For each row in the mortgage data...
selectMetrics.forEach(metric => { // For each of the metrics we selected...
returnArray.push({ // Push to our return array the key, metric name, and metric value
key: row[key],
value: row[metric],
metric: metric
})
})
})

return returnArray // return the return array
}
Insert cell
tidyData = tidy(mortgageData)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more