Published
Edited
Nov 12, 2020
Importers
Also listed in…
U.S. Census
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
selectedFips = statePicker
? statesToFips.get(statePicker)
: statesToFips.get(defaultState)
Insert cell
defaultState = "New York"
Insert cell
Insert cell
Insert cell
formatPct = d3.format(".2%")
Insert cell
Insert cell
Insert cell
dataRace = {
const res = await fetch(
`${dataApiUrl}?get=${variables},NAME&for=state:*&key=${apiKey}`
);
const data = await res.json();
return data.slice(1).map(row =>
row.reduce((acc, d, i) => {
acc[variablesNice[i]] = d;
return acc;
}, {})
);
return data;
}
Insert cell
variablesNice = variables
.map(niceLabel)
.map(key =>
key
.replace(/ /gi, "_")
.replace(/:/gi, "")
.replace(/,/gi, "")
)
.concat(["name", "fips"])
Insert cell
variables = [
"B01001_001E", // total estimated population, (all sexes), sex by age,

// total pop by race only
"B02001_002E", // White (includes Hispanic or Latino?)
"B02001_003E", // Black or African American
"B02001_004E", // American Indian or Alaskan Native
"B02001_005E", // Asian
"B02001_006E", // Native Hawaiian or Pacific Islander
"B02001_007E", // Some other race,

// hispanic or latino origin by specific origin
"B03003_003E" // Hispanic or Latino
]
Insert cell
Insert cell
Insert cell
dataRaceByState = {
const data = new Map();

if (!selectedFips) return data;

for (let [race, variables] of ageVariablesByRace) {
const cur = await getData(variables, selectedFips);
const sums = Array.from(getAgeVariablesByRace(curRace).values(), V =>
d3.sum(V, v => cur[1][ageVariablesIndex.get(v)])
);
const sex = Array.from(getSexVariablesByRace(curRace).values(), V =>
d3.sum(V, v => cur[1][ageVariablesIndex.get(v)])
);
const total = d3.sum(cur[1].slice(0, -2));
data.set(race, { sums, sex, total });
yield data;
}
}
Insert cell
stateTotalPop = selectedFips
? d3.sum(dataRaceByState.values(), d => d.total)
: null
Insert cell
Insert cell
Insert cell
curRace = "Black (Alone)"
Insert cell
ageVariableTotals = dataTest.slice(1).map(d => d3.sum(d.slice(0, -1)))
Insert cell
ageVariablesSums = dataTest
.slice(1)
.map(d =>
Array.from(getAgeVariablesByRace(curRace).values(), V =>
d3.sum(V, v => d[ageVariablesIndex.get(v)])
)
)
Insert cell
// sum age buckets for a single state & race
// this transforms the 28 age related variables into 10 age buckets
Array.from(getAgeVariablesByRace(curRace).values(), V =>
d3.sum(V, v => dataTest[1][ageVariablesIndex.get(v)])
)
Insert cell
ageVariablesIndex = {
const index = new Map(dataTest[0].map((d, i) => [d, i]));
if (index.get("state") !== dataTest[0].length - 1)
throw "state should be last column name";
if (index.get("NAME") !== dataTest[0].length - 2)
throw "state should be second to last column name";
return index;
}
Insert cell
dataTest = getData(ageVariablesByRace.get(curRace))
Insert cell
Insert cell
Insert cell
sexBuckets = ["male", "female"]
Insert cell
// these buckets should be consistent for any race / ethnicity
ageBuckets = Array.from(getAgeVariablesByRace("White (Alone)").keys())
Insert cell
ageVariablesByRace = new Map(
[...raceGroupCodes].map(([race, key]) => [
race,
Array.from(getAgeVariablesByRace(race).values())
])
)
Insert cell
// these correspond to table B01001 age buckets by gender by race
// e.g. B01001D would be for all age buckets that are also "Asian"
// see: https://api.census.gov/data/2018/acs/acs5/variables.html
raceGroupCodes = new Map([
// ["White (Alone)", "A"],
["Black (Alone)", "B"],
["American Indian / Alaskan Native", "C"],
["Asian", "D"],
["Native Hawaiian / Pacific Islander", "E"],
["White/Non-Hispanic (Alone)", "H"],
["Hispanic/Latino", "I"],
["Other", "F"]
])
Insert cell
getAgeVariablesByRace = race =>
new Map(
[
["<10", ["003", "004", "018", "019"]],
["10-19", ["005", "006", "007", "020", "021", "022"]],
["20-29", ["008", "009", "023", "024"]],
["30-34", ["010", "025"]],
["35-44", ["011", "026"]],
["45-54", ["012", "027"]],
["55-64", ["013", "028"]],
["65-74", ["014", "029"]],
["75-84", ["015", "030"]],
["≥85", ["016", "031"]]
].map(([key, V]) => [
key,
V.map(v => `B01001${raceGroupCodes.get(race)}_${v}E`)
])
)
Insert cell
getSexVariablesByRace = race =>
new Map(
[
[
"male",
[
"003",
"004",
"005",
"006",
"007",
"008",
"009",
"010",
"011",
"012",
"013",
"014",
"015",
"016"
]
],
[
"female",
[
"018",
"019",
"020",
"021",
"022",
"023",
"024",
"025",
"026",
"027",
"028",
"029",
"030",
"031"
]
]
].map(([key, V]) => [
key,
V.map(v => `B01001${raceGroupCodes.get(race)}_${v}E`)
])
)
Insert cell
// this is just for having a fips <-> state lookup
allStatesFips = {
const res = await fetch(`${dataApiUrl}?get=NAME&for=state:*&key=${apiKey}`);
const data = await res.json();
const vars = ["name", "fips"];
return data.slice(1).map(row =>
row.reduce((acc, d, i) => {
acc[vars[i]] = d;
return acc;
}, {})
);
return data;
}
Insert cell
getData = async (variables, state = "*") => {
const res = await fetch(
`${dataApiUrl}?get=${variables},NAME&for=state:${state}&key=${apiKey}`
);
return await res.json();
}
Insert cell
dataApiUrl = "https://api.census.gov/data/2018/acs/acs5"
Insert cell
apiKey = "bd155aaa303834a623fa83babc2d2644ac60fbf3"
Insert cell
Insert cell
import { Tooltip } from "@clhenrick/tooltip-component"
Insert cell
import { legend } from "@d3/color-legend"
Insert cell
import { select, autoSelect, checkbox } from "@jashkenas/inputs"
Insert cell
import { niceLabel } from "@enjalot/us-county-datasets"
Insert cell
import { select } from "@jashkenas/inputs"
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