function solve(p) {
if (p.mode === "Closed city") {
const xbar = Math.sqrt(p.N * 1000 / (Math.PI * p.D));
const c = p.y - p.t * xbar - p.rA;
return {xbar, c, N: p.N, viable: c > 0};
}
const xbar = Math.max((p.y - p.cbar - p.rA) / p.t, 0);
const Nk = Math.PI * p.D * xbar * xbar / 1000;
return {xbar, c: p.cbar, N: Nk, viable: xbar > 0};
}
base = solve({mode, y: 60000, t: 1500, rA: 3000, N: 150, D: 4000, cbar: 51800})
city = solve({mode, y, t, rA, N, D, cbar})
xmax = Math.max(base.xbar, city.xbar, 1) * 1.15
curve = (s, tt, ra) => d3.range(0, xmax, xmax / 200).map(x => ({x, r: x <= s.xbar ? ra + tt * (s.xbar - x) : ra}))
Plot.plot({
height: 340, marginLeft: 70,
x: {label: "Distance from the CBD (miles) →", domain: [0, xmax]},
y: {label: "↑ Rent ($ per lot per year)", grid: true, zero: true},
marks: [
Plot.line(curve(base, 1500, 3000), {x: "x", y: "r", stroke: "#999", strokeDasharray: "5,4"}),
Plot.line(curve(city, t, rA), {x: "x", y: "r", stroke: "#881124", strokeWidth: 3}),
Plot.ruleX([city.xbar], {stroke: "#881124", strokeOpacity: 0.4}),
Plot.text([{x: city.xbar, r: rA}], {x: "x", y: "r", text: d => " edge", dy: -10, textAnchor: "start", fill: "#881124"})
]
})