Published
Edited
May 23, 2021
Insert cell
Insert cell
unemployment
Insert cell
stateToAbbr
Insert cell
Insert cell
stateGrid = [[0,0,"AK"],[10,0,"ME"],[5,1,"WI"],[9,1,"VT"],[10,1,"NH"],[0,2,"WA"],[1,2,"ID"],[2,2,"MT"],[3,2,"ND"],[4,2,"MN"],[5,2,"IL"],[6,2,"MI"],[7,2,"NY"],[9,2,"MA"],[0,3,"OR"],[1,3,"NV"],[2,3,"WY"],[3,3,"SD"],[4,3,"IA"],[5,3,"IN"],[6,3,"OH"],[7,3,"PA"],[8,3,"NJ"],[9,3,"CT"],[10,3,"RI"],[0,4,"CA"],[1,4,"UT"],[2,4,"CO"],[3,4,"NE"],[4,4,"MO"],[5,4,"KY"],[6,4,"WV"],[7,4,"VA"],[8,4,"MD"],[9,4,"DE"],[1,5,"AZ"],[2,5,"NM"],[3,5,"KS"],[4,5,"AR"],[5,5,"TN"],[6,5,"NC"],[7,5,"SC"],[8,5,"DC"],[3,6,"OK"],[4,6,"LA"],[5,6,"MS"],[6,6,"AL"],[7,6,"GA"],[0,7,"HI"],[3,7,"TX"],[8,7,"FL"]]
Insert cell
Insert cell
stateToPosition = Object.fromEntries(stateGrid.map(([col, row, state]) => [state, {row, col}]))
Insert cell
Insert cell
unemploymentWithPosition = unemployment.map(d => {
const abbr = stateToAbbr[d.state];
const {row, col} = stateToPosition[abbr];
return {
state: abbr,
rate: d.rate,
row: row,
col: col,
}
})
Insert cell
Insert cell
numberOfRows = d3.max(unemploymentWithPosition, d => d.row) + 1
Insert cell
numberOfCols = d3.max(unemploymentWithPosition, d => d.col) + 1
Insert cell
Insert cell
cellSize = 50
Insert cell
mapWidth = numberOfCols * cellSize
Insert cell
mapHeight = numberOfRows * cellSize
Insert cell
Insert cell
row = d3.scaleBand()
.domain(d3.range(numberOfRows))
.range([0, mapHeight])
.padding(0.05)
Insert cell
col = d3.scaleBand()
.domain(d3.range(numberOfCols))
.range([0, mapWidth])
.padding(0.05)
Insert cell
Insert cell
color = d3.scaleSequential()
.domain(d3.extent(unemployment, d => d.rate))
.interpolator(d3.interpolateBlues)
Insert cell
Insert cell
gridCartogram = {
// set up
const svg = d3.create('svg')
.attr('width', mapWidth)
.attr('height', mapHeight);
// add a group for each cell and position it according to its row and column
const cells = svg.selectAll('g')
.data(unemploymentWithPosition)
.join('g')
.attr('transform', d => `translate(${col(d.col)}, ${row(d.row)})`);
// add a rectangle to each group and make it take up the entire cell
cells.append('rect')
.attr('width', col.bandwidth())
.attr('height', row.bandwidth())
.attr('fill', d => color(d.rate));
// add state label to each group
cells.append('text')
.attr('font-size', 12)
.attr('font-family', 'sans-serif')
.attr('dominant-baseline', 'middle')
.attr('text-anchor', 'middle')
.attr('x', col.bandwidth() / 2)
.attr('y', row.bandwidth() / 2)
.text(d => d.state);
return svg.node();
}
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