Published
Edited
Jul 23, 2020
3 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
hexbin = d3
.hexbin()
.extent([[0, 0], [map_width, height]])
.x(x => x.x)
.y(y => y.y)
.radius(map_width / 80)
Insert cell
// Need the max to shade the hexes
hex_max = d3.max(city_info_hex.map(o => d3.sum(o.map(d => d.cnt))))
Insert cell
// Best to do this just once
city_info_hex = hexbin(city_info)
Insert cell
// Tooltip titles for the hexes
function title_table(ci) {
let html = `<table>
<thead>
<tr>
<th>City</th><th>State</th><th style='text-align: right'>Hits</th>
</tr>
</thead>
`;
ci.slice(0, 10).forEach(function(o) {
let this_html = ` <tr>
<td style='text-align: left'>${o.city}</td><td>${o.state}</td><td style='text-align: right'>${o.cnt}</td>
</tr>
`;
html = html + this_html;
});
html = html + '</table>';
return html;
}
Insert cell
Insert cell
// Cities and count data file
city_info = d3
.csvParse(await FileAttachment("city_counts@4.csv").text(), d3.autoType)
.sort((a, b) => d3.descending(a.cnt, b.cnt))
.slice(0, N)
.map(function(o) {
let [x, y] = proj([o.x, o.y]);
o.x = x;
o.y = y;
return o;
})
Insert cell
// Map and city data are pre-projected to Albers USA.
// Just need to scale to fit the extent.
proj = d3
.geoIdentity()
.reflectY(true)
.fitSize([map_width, height], states)
Insert cell
// State totals for shading
state_total_map = {
let state_total_map = new Map();
city_info.forEach(function(c) {
let key = c.state;
if (typeof state_total_map.get(key) == 'undefined') {
state_total_map.set(key, c.cnt);
} else {
state_total_map.set(key, state_total_map.get(key) + c.cnt);
}
});
state_total_map.max = d3.max(Array.from(state_total_map.values()));
return state_total_map;
}
Insert cell
// The states
states = {
let map_file = await FileAttachment("states.json").json();
let states = topojson.feature(map_file, map_file.objects.states);
return states;
}
Insert cell
Insert cell
// Number of cities
// (there's almost 6000 but the map is awfully busy with all of them)
N = 2500
Insert cell
map_width = 0.9 * width
Insert cell
height = 0.625 * map_width
Insert cell
Insert cell
topojson = require("topojson-client@3")
Insert cell
d3 = require("d3@5", "d3-hexbin@0.2")
Insert cell
tippy = require("https://unpkg.com/tippy.js@2.5.4/dist/tippy.all.min.js")
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