Public
Edited
Apr 11, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
variables = (
await (
await fetch("https://api.census.gov/data/2021/acs/acs5/variables.json")
).json()
).variables
Insert cell
Insert cell
concepts = d3
.sort(
d3.filter(_.uniq(Object.values(variables).map((o) => o.concept)), (s) => s),
(s) => s.length
)
.slice(0, -1)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
var_info = {
if (concept_table.length == 1) {
return Object.entries(variables)
.filter((a) => a[1].concept == concept_table[0].concept)
.map(([v, o]) => Object.assign(o, { var: v }));
}
}
Insert cell
Insert cell
selected_vars = var_info ? var_info.map((o) => o.var).join(",") : ""
Insert cell
Insert cell
Insert cell
Insert cell
results = selected_vars
? await (
await fetch(
`https://api.census.gov/data/2021/acs/acs5?get=NAME,${selected_vars}&for=county:*&in=state:37`
)
).json()
: md``
Insert cell
Insert cell
query_data = {
let columns = results[0];
return results.slice(1).map(function (a) {
return Object.fromEntries(d3.zip(columns, a));
});
}
Insert cell
Insert cell
Insert cell
state_populations = {
// The API call itself as discussed above.
let results = await (
await fetch(
"https://api.census.gov/data/2021/acs/acs5?get=NAME,B01003_001E&for=state"
)
).json();

// Manipulate the results into proper JSON
let columns = results[0];
results = results.slice(1).map(function (a) {
return Object.fromEntries(d3.zip(columns, a));
});

// Return the result as a Javascript Map object to easily access the
// popoulation count from the state FIPS code.
return d3.rollup(
results,
(a) => parseInt(a[0].B01003_001E),
(o) => o.state
);
}
Insert cell
Insert cell
Insert cell
map = {
let w = d3.min([width, 1100]);
let h = 0.6 * w;
let pad = 10;
let svg = d3
.create("svg")
.attr("viewBox", [0, 0, w, h])
.style("max-width", `${w}px`);

let projection = d3.geoAlbersUsa();
projection.fitExtent(
[
[pad, pad],
[w - pad, h - pad]
],
states
);
let path = d3.geoPath().projection(projection);

let color_scale = d3
.scaleQuantile()
.domain(Array.from(state_populations.values()))
.range(d3.schemeBlues[8]);

svg
.append("g")
.selectAll("path")
.data(states.features)
.join("path")
.attr("d", path)
.attr("fill", (d) =>
color_scale(state_populations.get(d.properties.STATEFP))
)
.attr("stroke", "black")
.attr("stroke-width", 1);

svg.node().scale = color_scale;

return svg.node();
}
Insert cell
Insert cell
// The geographic data file for the map
states = {
let states = await FileAttachment("states.json").json();
states = topojson.feature(states, states.objects.states);
return states;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
sex_by_age_info = {
let sex_by_age_info = await FileAttachment("sex_by_age.csv").csv();

// Supplement the data with an age_base
sex_by_age_info.forEach(function (o) {
let label_components = o.label.split("!!");
let sex = label_components[2];
if (sex) {
o.sex = sex.slice(0, -1);
}
let age_base = label_components[3];
if (age_base) {
age_base = age_base.slice(0, -6);
if (age_base == "Under 5") {
age_base = 0;
} else if (age_base) {
age_base = 5 * Math.floor(parseInt(age_base.split(" ")[0]) / 5);
}
o.age_base = age_base;
}
});

return sex_by_age_info;
}
Insert cell
Insert cell
sex_by_age_results = fetch(
`https://api.census.gov/data/2021/acs/acs5?for=us&get=NAME,${sex_by_age_info
.map((o) => o.var)
.join()}`
).then((r) => r.json())
Insert cell
Insert cell
values = new Map(d3.zip(...sex_by_age_results).slice(1, -1))
Insert cell
Insert cell
pop_by_age_sex = {
let data = d3.rollup(
sex_by_age_info,
(a) => ({
sex: a[0].sex,
age_range: `${a[0].age_base}-${
a[0].age_base == 85 ? "" : a[0].age_base + 4
}`,
value: d3.sum(a.map((o) => parseInt(values.get(o.var))))
}),
(o) => o.sex,
(o) => o.age_base
);

return Array.from(data.values())
.map((d) => Array.from(d.values()))
.flat()
.filter((o) => !o.age_range.match("undefined"));
}
Insert cell
Insert cell
Insert cell
tippy_style
Insert cell
import { make_map, tippy_style } from "2cd910776a0daf15"
Insert cell
import { Swatches, Legend } from "@d3/color-legend"
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