chart = () => {
const wrapper = d3.create("div")
.style("font-family", franklinLight);
wrapper.append("div")
.text("Cumulative approvals of applications for permits to drill on federal land")
const svg = wrapper.append("svg")
.attr("width", chartwidth + margin.left + margin.right)
.attr("height", chartheight + margin.top + margin.bottom);
const g = svg.append("g")
.attr("transform", `translate(${[margin.left, margin.top]})`);
const xaxis = g.append("g")
.attr("transform", `translate(0, ${chartheight})`)
.call(
d3.axisBottom(x)
.tickFormat(d => d ? d : "Inauguration")
.tickSize(10)
.tickValues([...d3.range(0, 800, 200), lastBiden])
);
xaxis.select(".domain").remove();
const xticks = xaxis.selectAll(".tick");
xticks.select("line")
.attr("stroke", "#808080");
xticks.select("text")
.attr("fill", "#494949")
.attr("font-family", franklinLight)
.attr("font-size", 14)
.attr("text-anchor", (d, i) => i === 0 ? "start" : "middle")
.attr("x", (d, i) => i === 0 ? -4 : 0);
g.append("text")
.attr("font-size", 16)
.attr("x", -4)
.attr("y", chartheight + 44)
.text("Number of days in office →")
const yaxis = g.append("g")
.attr("transform", `translate(${chartwidth})`)
.call(
d3.axisLeft(y)
.tickSize(chartwidth + 10)
);
yaxis.select(".domain").remove();
const yticks = yaxis.selectAll(".tick");
yticks.select("line")
.attr("stroke", "#d5d5d5")
yticks.select("text")
.attr("fill", "#494949")
.attr("font-family", franklinLight)
.attr("font-size", 14)
g.selectAll(".line")
.data(adminsPermits)
.join("path")
.attr("class", "line")
.attr("fill", "none")
.attr("stroke", d => colors[d.admin])
.attr("stroke-width", 2)
.attr("d", d => line(d.data));
const lineLabels = g.selectAll(".line-label")
.data(adminsPermits)
.join("g")
.attr("class", "line-label")
.attr("font-family", franklinBold)
.attr("font-size", 18)
.attr("text-anchor", d => d.admin === "Biden" ? "end" : "start")
.style("text-transform", "uppercase")
.attr("transform", d => {
const mid = d.data[Math.floor(lastBiden / 2)];
const lx = x(mid.admin_days);
const ly = y(mid.cumsum) + (d.admin === "Trump" ? 12 : 0);
const h = 8 * (d.admin === "Biden" ? -1 : 1);
const v = h * (chartheight / chartwidth);
return `translate(${[lx + h, ly + v]})`
});
lineLabels.append("text")
.attr("fill", "white")
.attr("stroke", "white")
.attr("stroke-linecap", "round")
.attr("stroke-linejoin", "round")
.attr("stroke-width", 8)
.text(d => d.admin)
lineLabels.append("text")
.attr("fill", d => colors[d.admin])
.text(d => d.admin);
const endLabels = g.selectAll(".end-label")
.data(adminsPermits)
.join("g")
.attr("class", "end-label")
.attr("transform", d => {
const end = d.data[d.data.length - 1];
return `translate(${[x(end.admin_days), y(end.cumsum)]})`
});
endLabels.append("circle")
.attr("fill", d => colors[d.admin])
.attr("r", 4)
.attr("stroke", "white");
endLabels.append("text")
.attr("dy", d => 7 * (d.admin === "Biden" ? -1 : 1))
.attr("fill", d => colors[d.admin])
.attr("font-family", franklinLight)
.attr("font-size", 16)
.attr("x", 7)
.attr("y", 3)
.text(d => d3.format(",")(d.data[d.data.length - 1].cumsum))
return wrapper.node();
}