Public
Edited
Apr 18, 2024
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
waPopulation = waPopulationRaw.map(d => {
return {
County: d.County,
Census2020: parseInt(d.Census2020),
Estimate2021: parseInt(d.Estimate2021),
Estimate2022: parseInt(d.Estimate2022),
GEOID_AFF: d.GEOID_AFF,
GEOID_TIGER: parseInt(d.GEOID_TIGER)
};
})
Insert cell
waPopulation
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
Insert cell
Insert cell
Insert cell
usData = await d3.json('https://cdn.jsdelivr.net/npm/vega-datasets@2.8.0/data/us-10m.json')
Insert cell
Insert cell
waData = topojson
.feature(usData, usData.objects.states) // parse TopoJSON to GeoJSON features for all states
.features // the features array has one entry per state
.filter((d) => d.id === 53); // filter to WA state (id 53)
Insert cell
Insert cell
waCountyIDs = waPopulation.map(c => c.GEOID_TIGER)
Insert cell
Insert cell
countiesData = topojson
.feature(usData, usData.objects.counties) // parse TopoJSON to GeoJSON for all counties
.features // the features array has one entry per county
.filter(d => waCountyIDs.indexOf(d.id) >= 0) // filter to only counties in WA state
Insert cell
Insert cell
width = 500
Insert cell
height = 500
Insert cell
Insert cell
Insert cell
Insert cell
vl.markGeoshape()
.data(waData)
.project(vl.projection('identity'))
.width(width) // width and height are defined above...
.height(height)
.render()
Insert cell
Insert cell
vl.spec({
mark: { type: 'geoshape' },
data: { values: waData },
projection: { type: 'identity' },
width: width,
height: height
})
.render()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
vl.spec({
mark: { type: 'geoshape' },
data: { values: countiesData },
projection: { type: 'mercator' },
width: width,
height: height,
encoding: {
stroke: {
value: "white"
}
}
})
.render()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
projection = d3.geoIdentity().fitSize([width, height], waData[0]);
Insert cell
Insert cell
path = d3.geoPath(projection);
Insert cell
Insert cell
{
// create the SVG container
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height]);

// NOTE: we need to use the path variable to generate SVG objects from GeoJSON!

// draw WA state using waData
svg
.selectAll(".state") // create an initial selection, empty at first
.data(waData) // populate selection with state data
.join("path") // create SVG path elements for each state
.attr("class", "state") // set the CSS class of each path element
.style("stroke", "none") // stroke (boundary) color of the SVG path
.style("fill", "steelblue") // fill (interior) color of the SVG path
.attr("d", path); // use the geo path helper to generate SVG path coordinates
return svg.node();
};
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
// create the SVG container
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height]);

// NOTE: you will need to use the path variable to generate SVG objects from GeoJSON!
// draw the counties using countiesData
// svg
// .selectAll(".county")
// .data(...)
// .join(...)
// .attr(...)
// .style(...) // set fill, stroke properties
// ...
//[FILL THIS IN WITH YOUR OWN CODE]
return svg.node();
};
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
vl.spec({
mark: { type: 'geoshape' },
data: { values: countiesData },
projection: { type: 'mercator' },
width: width,
height: height,
transform: [{
lookup: 'id',
from: {
data: {values: waPopulation},
key: 'GEOID_TIGER',
fields: ['Census2020'],
}
}],
encoding: {
color: {
field: "Census2020", type: 'quantitative',
},
stroke: {
value: "white"
}
}
})
.render()
Insert cell
vl.spec({
data: { values: countiesData },
width: width,
height: height,
transform: [{
lookup: 'id',
from: {
data: {values: waPopulation},
key: 'GEOID_TIGER',
fields: ['Census2020'],
}
}, {
calculate: "geoCentroid(null, datum)",
as: "centroid"
}, {
calculate: "datum.centroid[0]",
as: "lon"
}, {
calculate: "datum.centroid[1]",
as: "lat"
}],
layer: [{
mark: { type: 'geoshape' },
encoding: {
// color: {
// field: "Census2020", type: 'quantitative',
// },
color: {
value: "transparent"
},
stroke: {
value: "black"
}
},
projection: { type: 'mercator' },
}, {
"mark": "circle",
"encoding": {
"longitude": {
"field": "lon",
"type": "quantitative"
},
"latitude": {
"field": "lat",
"type": "quantitative"
},
"size": {
"field": "Census2020",
"type": "quantitative"
}
}
}],
})
.render()
Insert cell
Insert cell
Insert cell
// paste a copy of the chart code here
// and modify the code to also visualize population data

// You will want to write your own "lookup" data structure or "lookup" function
// where for a given county, we can use "lookup" to retrieve the population count from waPopulation.
// Using your lookup function/data structure may look something like this in the final code:
// .selectAll(".county")
// .data(...)
// .join(...)
// .attr(...)
// .style("fill", f => color(lookup[f.id].Estimate2022))
// ...
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
topojson = require("topojson-client@3")
Insert cell
import {Legend} from "@d3/color-legend"
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