Published
Edited
Aug 27, 2020
6 forks
22 stars
Insert cell
Insert cell
Insert cell
chart = {
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);

svg.append("g")
.attr("stroke", "#ccc")
.attr("stroke-width", 2)
.selectAll("line")
.data(data)
.join("line")
.attr("x1", x(0))
.attr("x2", d => x(d.value))
.attr("y1", (d, i) => y(i))
.attr("y2", (d, i) => y(i));

svg.append("g")
.call(xAxis);

svg.append("g")
.call(yAxis);

svg.append("g")
.selectAll("circle")
.data(data)
.join("circle")
.attr("fill", d => d3.schemeSet1[d.value > 0 ? 1 : 0])
.attr("cx", d => x(d.value))
.attr("cy", (d, i) => y(i))
.attr("r", 6);

svg.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.selectAll("text")
.data(data)
.join("text")
.attr("text-anchor", d => d.value < 0 ? "end" : "start")
.attr("x", d => x(d.value) + Math.sign(d.value - 0) * 8)
.attr("y", (d, i) => y(i) + y.bandwidth() / 2)
.attr("dy", "0.35em")
.text(d => format(d.value));

return svg.node();
}
Insert cell
data = d3.tsvParse(await FileAttachment("state-population-2010-2019.tsv").text(), ({State: name, "2010": value0, "2019": value1}) => ({name, value: metric === "absolute" ? value1 - value0 : (value1 - value0) / value0})).sort((a, b) => d3.ascending(a.value, b.value))
Insert cell
x = d3.scaleLinear()
.domain(d3.extent(data, d => d.value))
.rangeRound([margin.left, width - margin.right])
Insert cell
y = d3.scalePoint()
.domain(d3.range(data.length))
.rangeRound([margin.top, height - margin.bottom])
.padding(0.1)
Insert cell
xAxis = g => g
.attr("transform", `translate(0,${margin.top})`)
.call(d3.axisTop(x).ticks(width / 80).tickFormat(tickFormat))
.call(g => g.select(".domain").remove())
Insert cell
yAxis = g => g
.attr("transform", `translate(${x(0)},0)`)
.call(d3.axisLeft(y).tickFormat(i => data[i].name).tickSize(0).tickPadding(6))
.call(g => g.selectAll(".tick text").filter(i => data[i].value < 0)
.attr("text-anchor", "start")
.attr("x", 6))
Insert cell
format = d3.format(metric === "absolute" ? "+,d" : "+,.0%")
Insert cell
tickFormat = metric === "absolute" ? d3.formatPrefix("+.1", 1e6) : format
Insert cell
barHeight = 25
Insert cell
height = Math.ceil((data.length + 0.1) * barHeight) + margin.top + margin.bottom
Insert cell
margin = ({top: 30, right: 60, bottom: 10, left: 60})
Insert cell
d3 = require("d3@6")
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