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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more