353 lines
10 KiB
JavaScript
353 lines
10 KiB
JavaScript
document.addEventListener("DOMContentLoaded", function () {
|
|
console.log("Frontend.js loaded");
|
|
|
|
// Initialize charts on page load
|
|
initializeCharts();
|
|
|
|
// Handle form submissions
|
|
handleFormSubmissions();
|
|
|
|
// Add animations for results
|
|
addResultAnimations();
|
|
});
|
|
|
|
function initializeCharts() {
|
|
console.log("Initializing charts...");
|
|
|
|
// Mortgage Charts
|
|
const mortgageCharts = document.querySelectorAll(".mortgage-chart");
|
|
mortgageCharts.forEach((canvas) => {
|
|
console.log("Rendering mortgage chart for:", canvas);
|
|
const principal = parseFloat(canvas.dataset.principal) || 200000;
|
|
const totalInterest = parseFloat(canvas.dataset.interest) || 123312.18;
|
|
renderMortgageChart(canvas, principal, totalInterest);
|
|
});
|
|
|
|
// Data Center Charts
|
|
const datacenterCharts = document.querySelectorAll(".datacenter-chart");
|
|
datacenterCharts.forEach((canvas) => {
|
|
console.log("Rendering datacenter chart for:", canvas);
|
|
const powerCost = parseFloat(canvas.dataset.power) || 730;
|
|
const coolingCost = parseFloat(canvas.dataset.cooling) || 876;
|
|
const rackCost = parseFloat(canvas.dataset.rack) || 500;
|
|
renderDatacenterChart(canvas, powerCost, coolingCost, rackCost);
|
|
});
|
|
|
|
// ROI Charts
|
|
const roiCharts = document.querySelectorAll(".roi-chart");
|
|
roiCharts.forEach((canvas) => {
|
|
console.log("Rendering ROI chart for:", canvas);
|
|
const initialInvestment = parseFloat(canvas.dataset.investment) || 10000;
|
|
const netProfit = parseFloat(canvas.dataset.profit) || 4025.52;
|
|
renderRoiChart(canvas, initialInvestment, netProfit);
|
|
});
|
|
}
|
|
|
|
function handleFormSubmissions() {
|
|
const calculatorForms = document.querySelectorAll(".maple-calc form");
|
|
|
|
calculatorForms.forEach((form) => {
|
|
form.addEventListener("submit", function (e) {
|
|
e.preventDefault();
|
|
console.log("Form submitted");
|
|
|
|
// Validate form inputs
|
|
const inputs = form.querySelectorAll("input[required]");
|
|
let isValid = true;
|
|
|
|
inputs.forEach((input) => {
|
|
if (!input.value) {
|
|
isValid = false;
|
|
input.style.borderColor = "#ff0000";
|
|
} else {
|
|
input.style.borderColor = "#ccc";
|
|
}
|
|
});
|
|
|
|
if (!isValid) {
|
|
alert("Please fill in all required fields.");
|
|
return;
|
|
}
|
|
|
|
// Process form data
|
|
const formData = new FormData(form);
|
|
const formEntries = Object.fromEntries(formData.entries());
|
|
|
|
// Determine calculator type
|
|
const calculatorType = form
|
|
.closest(".maple-calc")
|
|
.classList.contains("mortgage-calculator")
|
|
? "mortgage"
|
|
: form
|
|
.closest(".maple-calc")
|
|
.classList.contains("datacenter-calculator")
|
|
? "datacenter"
|
|
: "roi";
|
|
|
|
const resultsDiv = form.nextElementSibling;
|
|
|
|
if (calculatorType === "mortgage") {
|
|
const principal = parseFloat(formEntries.principal) || 200000;
|
|
const interestRate = parseFloat(formEntries.interest_rate) || 3.5;
|
|
const termYears = parseInt(formEntries.term_years) || 30;
|
|
|
|
const monthlyPayment = calculateMonthlyPayment(
|
|
principal,
|
|
interestRate,
|
|
termYears,
|
|
);
|
|
const totalPayment = monthlyPayment * termYears * 12;
|
|
const totalInterest = totalPayment - principal;
|
|
|
|
updateMortgageResults(
|
|
resultsDiv,
|
|
monthlyPayment,
|
|
totalPayment,
|
|
totalInterest,
|
|
);
|
|
renderMortgageChart(
|
|
resultsDiv.querySelector(".mortgage-chart"),
|
|
principal,
|
|
totalInterest,
|
|
);
|
|
} else if (calculatorType === "datacenter") {
|
|
const powerKw = parseFloat(formEntries.power_kw) || 10;
|
|
const costPerKwh = parseFloat(formEntries.cost_per_kwh) || 0.1;
|
|
const rackSpace = parseInt(formEntries.rack_space) || 5;
|
|
const coolingFactor = 1.2;
|
|
|
|
const powerCostPerMonth = powerKw * costPerKwh * 24 * 30;
|
|
const coolingCostPerMonth = powerCostPerMonth * coolingFactor;
|
|
const rackCostPerMonth = rackSpace * 100;
|
|
const totalMonthlyCost =
|
|
powerCostPerMonth + coolingCostPerMonth + rackCostPerMonth;
|
|
const totalAnnualCost = totalMonthlyCost * 12;
|
|
|
|
updateDatacenterResults(
|
|
resultsDiv,
|
|
powerCostPerMonth,
|
|
coolingCostPerMonth,
|
|
rackCostPerMonth,
|
|
totalMonthlyCost,
|
|
totalAnnualCost,
|
|
);
|
|
renderDatacenterChart(
|
|
resultsDiv.querySelector(".datacenter-chart"),
|
|
powerCostPerMonth,
|
|
coolingCostPerMonth,
|
|
rackCostPerMonth,
|
|
);
|
|
} else if (calculatorType === "roi") {
|
|
const initialInvestment =
|
|
parseFloat(formEntries.initial_investment) || 10000;
|
|
const annualReturnRate =
|
|
parseFloat(formEntries.annual_return_rate) || 7;
|
|
const timeYears = parseInt(formEntries.time_years) || 5;
|
|
|
|
const finalValue =
|
|
initialInvestment * Math.pow(1 + annualReturnRate / 100, timeYears);
|
|
const netProfit = finalValue - initialInvestment;
|
|
const roiPercentage = (netProfit / initialInvestment) * 100;
|
|
|
|
updateRoiResults(resultsDiv, finalValue, netProfit, roiPercentage);
|
|
renderRoiChart(
|
|
resultsDiv.querySelector(".roi-chart"),
|
|
initialInvestment,
|
|
netProfit,
|
|
);
|
|
}
|
|
|
|
// Show results with animation
|
|
resultsDiv.style.opacity = "0";
|
|
setTimeout(() => {
|
|
resultsDiv.style.opacity = "1";
|
|
}, 100);
|
|
});
|
|
});
|
|
}
|
|
|
|
function calculateMonthlyPayment(principal, interestRate, termYears) {
|
|
const monthlyInterestRate = interestRate / 100 / 12;
|
|
const termMonths = termYears * 12;
|
|
return (
|
|
(principal *
|
|
(monthlyInterestRate * Math.pow(1 + monthlyInterestRate, termMonths))) /
|
|
(Math.pow(1 + monthlyInterestRate, termMonths) - 1)
|
|
);
|
|
}
|
|
|
|
function updateMortgageResults(
|
|
resultsDiv,
|
|
monthlyPayment,
|
|
totalPayment,
|
|
totalInterest,
|
|
) {
|
|
resultsDiv.querySelector("p:nth-child(2)").innerHTML =
|
|
`<strong>Monthly Payment:</strong> $${monthlyPayment.toFixed(2)}`;
|
|
resultsDiv.querySelector("p:nth-child(3)").innerHTML =
|
|
`<strong>Total Payment:</strong> $${totalPayment.toFixed(2)}`;
|
|
resultsDiv.querySelector("p:nth-child(4)").innerHTML =
|
|
`<strong>Total Interest:</strong> $${totalInterest.toFixed(2)}`;
|
|
}
|
|
|
|
function updateDatacenterResults(
|
|
resultsDiv,
|
|
powerCost,
|
|
coolingCost,
|
|
rackCost,
|
|
totalMonthlyCost,
|
|
totalAnnualCost,
|
|
) {
|
|
resultsDiv.querySelector("p:nth-child(2)").innerHTML =
|
|
`<strong>Power Cost (Monthly):</strong> $${powerCost.toFixed(2)}`;
|
|
resultsDiv.querySelector("p:nth-child(3)").innerHTML =
|
|
`<strong>Cooling Cost (Monthly):</strong> $${coolingCost.toFixed(2)}`;
|
|
resultsDiv.querySelector("p:nth-child(4)").innerHTML =
|
|
`<strong>Rack Cost (Monthly):</strong> $${rackCost.toFixed(2)}`;
|
|
resultsDiv.querySelector("p:nth-child(5)").innerHTML =
|
|
`<strong>Total Monthly Cost:</strong> $${totalMonthlyCost.toFixed(2)}`;
|
|
resultsDiv.querySelector("p:nth-child(6)").innerHTML =
|
|
`<strong>Total Annual Cost:</strong> $${totalAnnualCost.toFixed(2)}`;
|
|
}
|
|
|
|
function updateRoiResults(resultsDiv, finalValue, netProfit, roiPercentage) {
|
|
resultsDiv.querySelector("p:nth-child(2)").innerHTML =
|
|
`<strong>Final Value:</strong> $${finalValue.toFixed(2)}`;
|
|
resultsDiv.querySelector("p:nth-child(3)").innerHTML =
|
|
`<strong>Net Profit:</strong> $${netProfit.toFixed(2)}`;
|
|
resultsDiv.querySelector("p:nth-child(4)").innerHTML =
|
|
`<strong>ROI (%):</strong> ${roiPercentage.toFixed(2)}%`;
|
|
}
|
|
|
|
function renderMortgageChart(canvas, principal, totalInterest) {
|
|
if (!canvas) {
|
|
console.error("Mortgage chart canvas not found");
|
|
return;
|
|
}
|
|
const ctx = canvas.getContext("2d");
|
|
new Chart(ctx, {
|
|
type: "pie",
|
|
data: {
|
|
labels: ["Principal", "Total Interest"],
|
|
datasets: [
|
|
{
|
|
data: [principal, totalInterest],
|
|
backgroundColor: ["#02066F", "#ff6384"],
|
|
borderWidth: 1,
|
|
},
|
|
],
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
plugins: {
|
|
legend: {
|
|
position: "bottom",
|
|
labels: {
|
|
font: {
|
|
size: 14,
|
|
family: "Arial, sans-serif",
|
|
},
|
|
color: "#222222",
|
|
boxWidth: 20,
|
|
padding: 20,
|
|
usePointStyle: true,
|
|
},
|
|
},
|
|
title: {
|
|
display: false,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
function renderDatacenterChart(canvas, powerCost, coolingCost, rackCost) {
|
|
if (!canvas) {
|
|
console.error("Datacenter chart canvas not found");
|
|
return;
|
|
}
|
|
const ctx = canvas.getContext("2d");
|
|
new Chart(ctx, {
|
|
type: "pie",
|
|
data: {
|
|
labels: ["Power Cost", "Cooling Cost", "Rack Cost"],
|
|
datasets: [
|
|
{
|
|
data: [powerCost, coolingCost, rackCost],
|
|
backgroundColor: ["#02066F", "#ff6384", "#36a2eb"],
|
|
borderWidth: 1,
|
|
},
|
|
],
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
plugins: {
|
|
legend: {
|
|
position: "bottom",
|
|
labels: {
|
|
font: {
|
|
size: 14,
|
|
family: "Arial, sans-serif",
|
|
},
|
|
color: "#222222",
|
|
boxWidth: 20,
|
|
padding: 20,
|
|
usePointStyle: true,
|
|
},
|
|
},
|
|
title: {
|
|
display: false,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
function renderRoiChart(canvas, initialInvestment, netProfit) {
|
|
if (!canvas) {
|
|
console.error("ROI chart canvas not found");
|
|
return;
|
|
}
|
|
const ctx = canvas.getContext("2d");
|
|
new Chart(ctx, {
|
|
type: "pie",
|
|
data: {
|
|
labels: ["Initial Investment", "Net Profit"],
|
|
datasets: [
|
|
{
|
|
data: [initialInvestment, netProfit],
|
|
backgroundColor: ["#02066F", "#36a2eb"],
|
|
borderWidth: 1,
|
|
},
|
|
],
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
plugins: {
|
|
legend: {
|
|
position: "bottom",
|
|
labels: {
|
|
font: {
|
|
size: 14,
|
|
family: "Arial, sans-serif",
|
|
},
|
|
color: "#222222",
|
|
boxWidth: 20,
|
|
padding: 20,
|
|
usePointStyle: true,
|
|
},
|
|
},
|
|
title: {
|
|
display: false,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
}
|
|
|
|
function addResultAnimations() {
|
|
const resultsDivs = document.querySelectorAll(".results");
|
|
resultsDivs.forEach((div) => {
|
|
div.style.transition = "opacity 0.5s ease-in-out";
|
|
});
|
|
}
|