Public
Edited
Nov 4
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
all_states_time_series = turnout.filter(d =>
d.VEP_TURNOUT_RATE !== null &&
(form.electionType === "Both" || d.election_type === form.electionType)
)
Insert cell
time_series_subset = turnout.filter(d =>
form.selectedStates.includes(d.STATE) &&
d.VEP_TURNOUT_RATE !== null &&
(form.electionType === "Both" || d.election_type === form.electionType)
)
Insert cell
us_timeseries_subset = turnout.filter(
d =>
d.STATE == "United States" &&
d.VEP_TURNOUT_RATE !== null &&
(form.electionType === "Both" || d.election_type === form.electionType))
Insert cell
top10_states = turnout
.filter(d =>
d.YEAR === selectedYear &&
d.VEP_TURNOUT_RATE !== null &&
d.STATE !== "United States"
)
.sort((a, b) => b.VEP_TURNOUT_RATE - a.VEP_TURNOUT_RATE)
.slice(0, 10)
Insert cell
bottom10_states = turnout
.filter(d =>
d.YEAR === selectedYear &&
d.VEP_TURNOUT_RATE !== null &&
d.STATE !== "United States"
)
.sort((a, b) => a.VEP_TURNOUT_RATE - b.VEP_TURNOUT_RATE) // reversed sort order
.slice(0, 10)
Insert cell
voter_turnout = new Map(voter_turnout0.map(d => [
d.id,
d.VEP_TURNOUT_RATE === "" ? null : d.VEP_TURNOUT_RATE
]))
Insert cell
Insert cell
voter_turnout0 = turnout
.filter(d =>
d.YEAR === selectedYear
)
.map(d => ({
...d,
id: getFIPS(d.STATE)
}))
Insert cell
years = [...new Set(turnout.map(d => d.YEAR))].sort()
Insert cell
all_states = [...new Set(turnout
.filter(d => d.STATE !== "United States")
.map(d => d.STATE))]
Insert cell
turnout = FileAttachment("Turnout_1980_2022_v1.2.csv").csv()
.then(data => data.map(d => ({
YEAR: parseInt(d.YEAR),
election_type: parseInt(d.YEAR) % 4 === 0 ? "Presidential" : "Midterm",
STATE: d.STATE.replace('*', ''),
STATE_ABV: d.STATE_ABV,
TOTAL_BALLOTS_COUNTED: d.TOTAL_BALLOTS_COUNTED ?
parseInt(d.TOTAL_BALLOTS_COUNTED.replace(/,/g, '')) : null,
VOTE_FOR_HIGHEST_OFFICE: d.VOTE_FOR_HIGHEST_OFFICE?.startsWith('http') ?
null : // handle URLs by converting them to null
(d.VOTE_FOR_HIGHEST_OFFICE ? parseInt(d.VOTE_FOR_HIGHEST_OFFICE.replace(/,/g, '')) : null),
VAP: d.VAP ?
parseInt(d.VAP.replace(/,/g, '')) : null,
NONCITIZEN_PCT: d.NONCITIZEN_PCT ?
parseFloat(d.NONCITIZEN_PCT.replace('%', '')) : null,
INELIGIBLE_PRISON: d.INELIGIBLE_PRISON ?
parseInt(d.INELIGIBLE_PRISON.replace(/,/g, '')) : null,
INELIGIBLE_PROBATION: d.INELIGIBLE_PROBATION ?
parseInt(d.INELIGIBLE_PROBATION.replace(/,/g, '')) : null,
INELIGIBLE_PAROLE: d.INELIGIBLE_PAROLE ?
parseInt(d.INELIGIBLE_PAROLE.replace(/,/g, '')) : null,
INELIGIBLE_FELONS_TOTAL: d.INELIGIBLE_FELONS_TOTAL ?
parseInt(d.INELIGIBLE_FELONS_TOTAL.replace(/,/g, '')) : null,
ELIGIBLE_OVERSEAS: d.ELIGIBLE_OVERSEAS,
VEP: d.VEP ?
parseInt(d.VEP.replace(/,/g, '')) : null,
VEP_TURNOUT_RATE: d.VEP_TURNOUT_RATE ?
parseFloat(d.VEP_TURNOUT_RATE.replace('%', '')) : null,
VAP_TURNOUT_RATE: d.VAP_TURNOUT_RATE ?
parseFloat(d.VAP_TURNOUT_RATE.replace('%', '')) : null
})))
Insert cell
us = FileAttachment("counties-albers-10m.json").json()
Insert cell
states = topojson.feature(us, us.objects.states)
Insert cell
statemap = new Map(states.features.map(d => [d.id, d]))
Insert cell
getFIPS = (stateName) => {
const states = topojson.feature(us, us.objects.states);
// Find the matching state
const state = states.features.find(d =>
d.properties.name.toUpperCase() === stateName.toUpperCase()
);
return state ? state.id : null;
}
Insert cell
d3 = require("d3@^6.1")
Insert cell
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