Published
Edited
Oct 1, 2021
1 fork
Insert cell
Insert cell
CSAs = await d3.json(
"https://api.census.gov/data/2019/acs/acs5?get=NAME,B01001_001E&for=combined%20statistical%20area:*"
)
Insert cell
csaData = {
//.slice(1) cuts off the zeroeth item of the array
return CSAs.slice(1)
.map((csa) => {
return {
name: csa[0],
shortName: csa[0].split("-")[0],
population: parseInt(csa[1]),
csaID: parseInt(csa[2])
};
})
.slice(10, 30);
}
Insert cell
yMargin = 40
Insert cell
height = 400
Insert cell
xMargin = 120
Insert cell
yScale = d3
.scalePoint()
.domain(csaData.map((d) => d.shortName))
.range([yMargin, height - yMargin])
Insert cell
yAxis = d3
.axisLeft(yScale)
.tickPadding(10)
.tickSizeInner(-width + xMargin * 2)
.tickSizeOuter(-width + xMargin * 2)
Insert cell
speedScale = d3
.scaleLinear()
.domain(d3.extent(csaData, (d) => d.population))
.range([fastestTime, slowestTime])
Insert cell
colorScale = d3.scaleLinear().domain(d3.extent(csaData, (d) => d.population))
Insert cell
Insert cell
Insert cell
cityRacers = {
//artboard
const svg = d3.create("svg").attr("width", width).attr("height", height);

//background
svg
.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height)
.attr("fill", "#0ab");

//finish line
svg
.append("rect")
.attr("x", width - xMargin)
.attr("y", yMargin)
.attr("width", 8)
.attr("height", height - yMargin * 2)
.attr("fill", "white");

//Make a group ('g') in the SVG
svg
.append("g")
.attr("transform", "translate(" + xMargin + ",0)")
.call(yAxis);

//after the axis is drawn, we can change other visual styles
svg
.selectAll(".tick text") //find all the tick labels
.attr("font-size", "11px") //change font size
.attr("fill", "white") //change font color
.attr("font-family", "menlo"); //change font

//inner tick marks styles
svg.selectAll("g line").attr("stroke", "white").attr("stroke-width", 2);

//axis line and outer tick styles
svg.select("g path").attr("stroke", "white").attr("stroke-width", 2);

//data binding to create each circle
svg
.selectAll(".csas")
.data(csaData)
.enter()
.append("circle")
.attr("cx", xMargin)
.attr("cy", (d) => yScale(d.shortName))
.attr("r", 5)
.attr("fill", "white")
.attr("class", "csas");

//create svg button and attach event listener
svg
.append("rect")
.attr("fill", "orange")
.attr("width", 50)
.attr("height", 20)
.attr("x", width - 60)
.attr("y", 10)
.on("click", () => {
d3.selectAll(".csas")
.transition()
.duration((d) => speedScale(d.population))
.ease(d3.easeBounce)
.attr("cx", width - xMargin)
.attr("fill", (d) => d3.interpolateMagma(colorScale(d.population)));
});

//label for the button
svg
.append("text")
.attr("fill", "white")
.attr("x", width - 58)
.attr("y", 22)
.text("Go!")
.style("font-family", "courier")
.style("font-size", 14)
//so the text doesn't get in the way of our button seeing the mouse click...
.attr("pointer-events", "none");

//create svg button and attach event listener
svg
.append("rect")
.attr("fill", "orange")
.attr("width", 50)
.attr("height", 20)
.attr("x", width - 60)
.attr("y", 40)
.on("click", () => {
d3.selectAll(".csas")
.transition()
.duration((d) => speedScale(d.population))
.ease(d3.easeBounce)
.attr("cx", xMargin)
.attr("fill", "white");
});

//label for the button
svg
.append("text")
.attr("fill", "white")
.attr("x", width - 58)
.attr("y", 54)
.text("Reset")
.style("font-family", "courier")
.style("font-size", 14)
//so the text doesn't get in the way of our button seeing the mouse click...
.attr("pointer-events", "none");

return svg.node();
}
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