Public
Edited
Jul 18, 2024
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
css = `
.chart text {
fill: #2a2a2a;
font-family: ${franklinLight};
font-size: 16px;
}
.chart text.highlight {
font-weight: bold;
}
.chart rect {
fill: #d5d5d5;
}
.chart rect.highlight {
fill: #2a2a2a;
}
`
Insert cell
labelFormat = (d, i) => {
const text = d.replace("Point-Source ", "");
const label = `${text[0].toUpperCase()}${text.slice(1).toLowerCase()}`;
if (i == 3) {
const tspans = ["Carbon transport", "and storage"]

return `<tspan y=${y(d) + 11}>${tspans.join("</tspan><tspan>")}</tspan>`
}
return label
}
Insert cell
valueFormat = d => d >= 1e9 ? `$${(d / 1e9).toFixed(1)}B` : `$${Math.round(d / 1e6)}M`
Insert cell
Insert cell
chart = () => {
const svg = d3.create("svg")
.attr("class", "chart")
.attr("width", chartwidth + margin.left + margin.right)
.attr("height", chartheight + margin.top + margin.bottom);

svg.append("style").html(css);

const g = svg.append("g")
.attr("transform", `translate(${[margin.left, margin.top]})`);

const rect = g.selectAll("rect")
.data(dataFunding)
.enter().append("rect")
.classed("highlight", d => d.technology === "Geothermal")
.attr("width", d => x(d.funding))
.attr("height", barHeight)
.attr("y", d => y(d.technology));

const labelText = g.selectAll(".label")
.data(dataFunding)
.enter().append("text")
.attr("class", "label")
.attr("dy", y.bandwidth() / 2 + 2)
.attr("x", -margin.left)
.attr("y", d => y(d.technology))
.classed("highlight", d => d.technology === "Geothermal")
.html((d, i) => labelFormat(d.technology, i))
.selectAll("tspan")
.attr("x", -margin.left)
.attr("dy", (_, i) => i * 16);

const valueText = g.selectAll(".value")
.data(dataFunding)
.enter().append("text")
.attr("class", "value")
.attr("dx", 5)
.attr("dy", y.bandwidth() / 2 + 2)
.attr("x", d => x(d.funding))
.attr("y", d => y(d.technology))
.text(d => valueFormat(d.funding))
.classed("highlight", d => d.technology === "Geothermal")

return svg.node();
}
Insert cell
Insert cell
// These figures were provided by the Department of Energy
doe = `Geothermal 0.08
Direct Air Capture 3.5
Point-Source Carbon Capture 3.58
Carbon Transport & Storage 4.6
Energy Storage 7.78
Hydrogen 9.5
Nuclear 10.05`
Insert cell
dataFunding = doe
.split("\n")
.map(d => {
const [ technology, value ] = d.split("\t");
return {
technology,
funding: +value * 1e9
}
})
Insert cell
Insert cell
x = d3.scaleLinear()
.domain([0, d3.max(dataFunding, d => d.funding)])
.range([0, chartwidth])
Insert cell
y = d3.scaleBand()
.domain(dataFunding.map(d => d.technology))
.range([0, chartheight])
Insert cell
Insert cell
margin = ({ left: 126, right: 55, top: 0, bottom: 0 })
Insert cell
chartwidth = Math.min(width, 640) - margin.left - margin.right
Insert cell
barHeight = 26
Insert cell
barPadding = 10
Insert cell
chartheight = barHeight * dataFunding.length + barPadding * (dataFunding.length - 2)
Insert cell
Insert cell
import { toc } from "@climatelab/toc@45"
Insert cell
import { franklinLight } from "@climatelab/fonts@46"
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