Public
Edited
Sep 12, 2022
4 forks
7 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const xScale = d3
.scaleLinear()
.domain([0, simulationSteps - 1])
.range([margin, budgetWidth - margin]);

const yScale = d3
.scaleLinear()
.domain([-10000, 10000])
.range([budgetHeight - margin, margin]);

const svg = d3
.create("svg")
.attr("width", budgetWidth)
.attr("height", budgetHeight)
.attr("id", "budgetChart");

const bg = svg
.append("rect")
.attr("width", budgetWidth)
.attr("height", budgetHeight)
.attr("fill", backgroundColor);

let lineGen = d3
.line()
.x((d) => xScale(d.generationNumber))
.y((d) => yScale(d.budgetBalance));

svg
.datum(history.finance)
.append("path")
.attr("d", lineGen)
.attr("id", "budgetBalancePath")
.attr("stroke", "yellow")
.attr("stroke-width", "3")
.attr("fill", "none");

// Draw the axis
let yAxis = svg
.append("g")
.attr("transform", "translate(" + margin + ",0)")
.call(d3.axisLeft(yScale));

yAxis.selectAll("text").style("fill", "white");
yAxis.selectAll("line").style("stroke", "white");
yAxis.selectAll("path").style("stroke", "white");

// Draw the axis
let xAxis = svg
.append("g")
.attr("transform", "translate(0," + budgetHeight / 2 + ")")
.call(d3.axisBottom(xScale));

xAxis.selectAll("text").style("fill", "white");
xAxis.selectAll("line").style("stroke", "white");
xAxis.selectAll("path").style("stroke", "white");

// keys
const keys = [
{ name: "Budget", color: "red" },
{ name: "Variable Cost", color: "blue" },
{ name: "Fixed Cost", color: "green" },
{ name: "Budget Balance", color: "yellow" }
];

svg
.selectAll(".keyName")
.data(keys)
.enter()
.append("text")
.attr("x", (d, i) => ((i + 1) / (keys.length + 1)) * width)
.attr("y", 20)
.attr("font-family", "courier")
.attr("font-size", 12)
.attr("fill", "white")
.text((d) => d.name)
.attr("class", "keyName");

svg
.selectAll(".keyLine")
.data(keys)
.enter()
.append("line")
.attr("x1", (d, i) => ((i + 1) / (keys.length + 1)) * width - 25)
.attr("y1", 15)
.attr("x2", (d, i) => ((i + 1) / (keys.length + 1)) * width - 5)
.attr("y2", 15)
.attr("stroke-width", 3)
.attr("stroke", (d) => d.color);

return svg.node();
}
Insert cell
Insert cell
Insert cell
financeBalance = function (gen) {
if (gen === 0) {
d3.selectAll(".budget").remove();
d3.selectAll(".fixedCost").remove();
d3.selectAll(".variableCost").remove();
}

// fixed cost
let stationCost = addStationCount * 1;
let capacityCost = increaseCapacity * 0.1 * history.stations.length;
let evCost = replaceEv * 0.05;
let fixedCost = stationCost + capacityCost + evCost;

// station upgrade cost
let initialValue = 0;
history.upgradeNumber.forEach(
(d) =>
(d.upgradeTotal = d.upgradeNumber.reduce((totalValue, currentValue) => {
return totalValue + currentValue;
}, initialValue))
);
let upgradeCost = upgradePercentage * 0.1;

// subsidy cost
let initialCost = 0;
history.subsidy.forEach(
(d) =>
(d.sum = d.subsidizedMoney.reduce((totalCost, currentCost) => {
return totalCost + currentCost;
}, initialCost))
);

// total variable cost
let variableCost =
upgradeCost * history.upgradeNumber[gen].upgradeTotal +
history.subsidy[gen].sum;

history.finance[gen].fixedCost = -fixedCost / 1000;
history.finance[gen].totalVariableCost = -variableCost / 1000;

if (gen >= 1) {
history.finance[gen].variableCost =
history.finance[gen].totalVariableCost -
history.finance[gen - 1].totalVariableCost;
} else if (gen == 0) {
history.finance[gen].variableCost = history.finance[gen].totalVariableCost;
}

// calculate budget balance
history.finance[gen].budgetBalance =
cityBudget * 1000 + fixedCost + history.finance[gen].totalVariableCost;

const xScale = d3
.scaleLinear()
.domain([0, simulationSteps - 1])
.range([margin, budgetWidth - margin]);

const yScale = d3
.scaleLinear()
.domain([-10000, 10000])
.range([budgetHeight - margin, margin]);

let lineGen = d3
.line()
.x((d) => xScale(d.generationNumber))
.y((d) => yScale(d.budgetBalance));

d3.select("#budgetChart")
.append("rect")
.attr("x", margin)
.attr("y", yScale(Math.max(0, cityBudget * 1000)))
.attr("width", (budgetWidth - margin) / simulationSteps)
.attr("height", Math.abs(yScale(cityBudget * 1000) - yScale(0)))
.attr("fill", "red")
.attr("class", "budget");

d3.select("#budgetChart")
.append("rect")
.attr("x", margin)
.attr("y", budgetHeight / 2 + history.finance[0].totalVariableCost)
.attr("width", (budgetWidth - margin) / simulationSteps)
.attr("height", -yScale(fixedCost))
.attr("fill", "green")
.attr("class", "fixedCost");

d3.select("#budgetChart")
.selectAll(".variableCost")
.data(history.finance)
.enter()
.append("rect")
.attr(
"x",
(d, i) => margin + (i * (budgetWidth - margin)) / simulationSteps
)
.attr("y", (d) => yScale(0))
.attr("width", (budgetWidth - margin) / simulationSteps)
.attr("height", (d) => Math.abs(yScale(d.variableCost) - yScale(0)))
.attr("fill", "blue")
.attr("stroke", "white")
.attr("stroke-width", 1)
.attr("class", "variableCost");

d3.select("#budgetChart")
.select("#budgetBalancePath")
.datum(history.finance)
.transition()
.attr("d", lineGen);
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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