Published
Edited
Jul 24, 2020
4 forks
Importers
21 stars
Insert cell
Insert cell
Insert cell
simpleSVGMap = {
// we create an SVG with the width and height specified
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)

svg.append("g")
.selectAll("path")
.data(countyShapes.features)
.join("path")
// This line renders our population data
.attr("fill", d => populationColor(populationByCounty.get(d.id)))
.attr("d", path)
.append("title")
.text(d => `${d.properties.name}, ${statesByFips.get(d.id.slice(0, 2)).name}
${populationFormat(populationByCounty.get(d.id))}`);

// this part renders the state borders over top of our counties
svg.append("path")
.datum(statesMesh)
.attr("fill", "none")
.attr("stroke", "white")
.attr("stroke-linejoin", "round")
.attr("d", path);

// we need to return a DOM element.
// the .node() function returns the DOM element corresponding to the d3 selection.
return svg.node();
}
Insert cell
// we use the color-legend from https://observablehq.com/@d3/color-legend to render our scale
legend({color: populationColor, width: width - 20, tickFormat: ",d", ticks: 7})
Insert cell
Insert cell
Insert cell
Insert cell
us = d3.json("https://unpkg.com/us-atlas@3/counties-10m.json")
Insert cell
Insert cell
countyShapes = topojson.feature(us, us.objects.counties)//.features
Insert cell
Insert cell
populationData = d3.json("https://api.census.gov/data/2018/pep/population?get=POP&for=county:*")
Insert cell
populationByCounty = {
// first we get rid of the first row (the header)
let rows = populationData.slice(1)
// each row is currently [Population, State code, County code ]
// we want to transform each row into [ FIPS Code, Population ]
.map(row => [String(row[1]) + String(row[2]), Number(row[0])])
// finally we return a JavaScript Map which allows us to easily lookup the population given a FIPS code
return new Map(rows)
}
Insert cell
// The smallest and biggest populations give us the "domain" for our color scale
populationExtent = d3.extent(populationData.slice(1), d=> +d[0])
Insert cell
// We use a log color scale
populationColor = d3.scaleSequentialLog(populationExtent, d3.interpolateGreens)
Insert cell
// This is how we format the numbers to use commas.
populationFormat = d3.format(",d")
Insert cell
Insert cell
statesByFips = new Map(us.objects.states.geometries.map(d => [d.id, d.properties]))
Insert cell
// The borders of the states are merged so we can render a single line where they would otherwise overlap
statesMesh = topojson.mesh(us, us.objects.states, (a, b) => a !== b)
Insert cell
Insert cell
projection = d3.geoAlbersUsa()
.fitSize([width, height], countyShapes)
// The default projection parameters used by most other county map examples instead of fitSize:
// .scale(1300)
// .translate([975/2, 610/2])
Insert cell
path = d3.geoPath(projection)
Insert cell
// width = ... by default the width is set by Observable, and will update if this is embedded
height = width * 0.6256410256410256 // the aspect ratio used in the projection, same as 610/975
Insert cell
Insert cell
Insert cell
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