Unlisted
Edited
Oct 24, 2024
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// From the Census Bureau
counties_geo = ({
type: "FeatureCollection",
features: (await FileAttachment("counties.geojson").json()).features
.filter(f => f.properties.STATEFP === "12")
})
Insert cell
Insert cell
// From the National Hurricane Center
milton_windswath = FileAttachment("milton_windswath.json").json()
Insert cell
milton_windswath_geo = topojson.feature(milton_windswath, milton_windswath.objects.windswath)
Insert cell
milton_64kt = milton_windswath_geo.features.find(f => f.properties.wsp === 64)
Insert cell
Insert cell
counties_intersected = JSON.parse(JSON.stringify(counties_geo.features)).filter((feature) => {
// Uses Milevski and Ovsyannikov's extension of
// Martinez et al's polygon clipping algorithm
// Implementation: https://github.com/w8r/martinez
const intersection = clip.intersection(
feature.geometry.coordinates,
milton_64kt.geometry.coordinates
);
if (!intersection) return false;
if (!intersection.length) return false;
return true;
});
Insert cell
Insert cell
// via Andrew J. Van Leuven (https://andrewvanleuven.com/post/countypopulations/)
historical_county_populations = FileAttachment("historical_county_populations.csv").csv()
Insert cell
historical_county_populations_index = d3.index(historical_county_populations, d => d.cty_fips)
Insert cell
// via https://www.census.gov/data/datasets/time-series/demo/popest/2020s-counties-total.html
census_2023 = (await FileAttachment("census_2023.json").json())
.map(d => (d.county_name = d.name.replace(".", "").replace(" County, Florida", ""), d))
Insert cell
census_2023_index = d3.index(census_2023, d => d.county_name)
Insert cell
// Data from Quarterly Census of Employment and Wages, a product of the Bureau of Labor Statistics
counties_qcew = FileAttachment("QCEW annual 1975 to 2023 by county all idustries total covered.csv").csv()
Insert cell
counties_qcew_groups = d3
.groups(counties_qcew, d => d.area_fips)
.map(([county_fips, entries]) => ({county_fips, entries}))
Insert cell
counties_qcew_index = d3.index(counties_qcew_groups, d => d.county_fips)
Insert cell
// A list of columns we want to keep
keep = ["county_fips", "county_name", "state_postal", ...d3.range(1900, 2020, 10).map(d => `pop_${d}`), ...d3.range(2020, 2024, 1).map(d => `pop_${d}`)]
Insert cell
milton_counties = counties_intersected.map(({properties}) => {
const { GEOID: county_fips, NAME: county_name } = properties;
const o = Object.assign(
{ county_fips, county_name, state_postal: "FL" },
historical_county_populations_index.get(county_fips),
census_2023_index.get(county_name)
);

const d = {};
keep.forEach(c => {
const v = o[c];
d[c] = c.includes("pop") ? +v : v;
});

const qcew = counties_qcew_index.get(county_fips);
d.total_annual_wages_1980 = +qcew.entries.find(d => d.year === "1980").total_annual_wages;
d.total_annual_wages_2020 = +qcew.entries.find(d => d.year === "2020").total_annual_wages;
d.total_annual_wages_2023 = +qcew.entries.find(d => d.year === "2023").total_annual_wages;

return d;
})
Insert cell
Insert cell
// Get the combined 1980 population
milton_counties_pop_1980 = d3.sum(milton_counties, d => d.pop_1980)
Insert cell
// Get the combined 2023 population
milton_counties_pop_2023 = d3.sum(milton_counties, d => d.pop_2023)
Insert cell
// Get the combined 2020 population
milton_counties_pop_2020 = d3.sum(milton_counties, d => d.pop_2020)
Insert cell
// Get the combined 1980 wages
milton_counties_wages_1980 = d3.sum(milton_counties, d => d.total_annual_wages_1980) * adjustment_1980
Insert cell
// Get the combined 2020 wages
milton_counties_wages_2020 = d3.sum(milton_counties, d => d.total_annual_wages_2020) * adjustment_2020
Insert cell
// Get the combined 2023 wages
milton_counties_wages_2023 = d3.sum(milton_counties, d => d.total_annual_wages_2023)
Insert cell
// https://fred.stlouisfed.org/graph/?g=1wkHx
adjustment_1980 = 3.697
Insert cell
// https://fred.stlouisfed.org/graph/?g=1wkSD
adjustment_2020 = 1.177
Insert cell
// 4x increase in inflation-adjusted annual wages
milton_counties_wages_2023 / milton_counties_wages_1980
Insert cell
Insert cell
map = () => {
const width = 640;
const height = width;
const projection = d3.geoMercator().fitSize([width, height], counties_geo);
const path = d3.geoPath(projection);
const svg = d3.create("svg").attr("width", width).attr("height", height);
svg.selectAll(".county")
.data(counties_geo.features)
.join("path")
.attr("class", "county")
.attr("d", path)
.attr("fill", "white")
.attr("stroke", "gray");
svg.selectAll(".intersected")
.data(counties_intersected)
.join("path")
.attr("class", "intersected")
.attr("d", path)
.attr("fill", "red")
.attr("stroke", "gray");
svg.append("path")
.datum(milton_64kt)
.attr("fill", "lightblue")
.attr("fill-opacity", 0.3)
.attr("d", path);
return svg.node();
}
Insert cell
sentence = () => md`The ${counties_intersected.length} counties hit by Hurricane Milton’s most intense winds saw their combined population swell from ${(milton_counties_pop_1980 / 1e6).toFixed(1)} million people in 1980 to ${(milton_counties_pop_2023 / 1e6).toFixed(1)} million in 2023. As the population more than doubled, the area’s economic activity, as captured by inflation-adjusted wages earned by the people who lived there, quadrupled over the same time period.`
Insert cell
Insert cell
import { toc } from "@harrystevens/toc"
Insert cell
clip = require("martinez-polygon-clipping")
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