Public
Edited
Nov 17, 2022
Insert cell
Insert cell
Insert cell
years = d3.range(2015, 2020)
Insert cell
Insert cell
//wait for everything to finish
rawCensusData = Promise.all(
//going each year one-by-one
years.map(
//go through each year in order
async (year) =>
//call census API
await d3.json(
"https://api.census.gov/data/" +
year +
"/acs/acs1?get=NAME,B28002_004E,B28002_001E&for=state:*"
)
)
)
Insert cell
cleanedData = rawCensusData.map((censusYear, i) =>
//remove the header row, and then iterate over all states
censusYear.slice(1).map((state) => ({
name: state[0],
internetHouseholds: parseInt(state[1]),
totalHouseholds: parseInt(state[2]),
internetPercentage: parseInt(state[1]) / parseInt(state[2]),
year: new Date(years[i], 0)
}))
)
Insert cell
Insert cell
states = cleanedData[0].map((state) => state.name)
Insert cell
//work through all the states
transposedData = states.map((state) =>
//work through each year, and find the correct state inside of it
cleanedData.map((year) => year.find((yearState) => yearState.name === state))
)
Insert cell
Insert cell
Insert cell
yearObjects = years.map((year) => new Date(year, 0))
Insert cell
xScale = d3
.scaleTime()
.domain(d3.extent(yearObjects))
.range([margin.left, width - margin.right])
Insert cell
xAxis = (g) =>
g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(xScale))
Insert cell
yScale = d3
.scaleLinear()
.domain(d3.extent(transposedData.flat(Infinity), (d) => d.internetPercentage))
.nice()
.range([height - margin.bottom, margin.top])
Insert cell
yAxis = (g) =>
g.attr("transform", `translate(${margin.left},0)`).call(d3.axisLeft(yScale))
Insert cell
Insert cell
height = 600
Insert cell
Insert cell
margin = ({ top: 20, right: 20, bottom: 30, left: 80 })
Insert cell
Insert cell
lineGen = d3
.line()
.x((d) => xScale(d.year))
.y((d) => yScale(d.internetPercentage))
Insert cell
chart = {
// Create an empty SVG with specified width and height.
const svg = d3.create("svg").attr("width", width).attr("height", height);

// Draw the x and y axes.
svg.append("g").call(xAxis);
svg.append("g").call(yAxis);

// Draw the line.
transposedData.map((state) => {
svg
.append("path")
.datum(state)
.attr("d", lineGen)
.attr("fill", "none")
.attr("stroke", "blue")
.attr("stroke-width", 0.5);
});

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