map = {
let div = d3
.create('div')
.style("width", `${width}px`)
.style("height", `${height}px`)
.style('overflow', 'hidden');
let svg = div
.append('svg')
.style('overflow', 'hidden')
.attr("viewBox", [0, 0, width, height]);
let path = d3.geoPath().projection(proj);
let map = svg
.append('g')
.attr('id', 'the_map')
.attr('transform', 'scale(1)');
map
.selectAll("path")
.data(states.features)
.join("path")
.attr('class', 'state')
.attr('d', path)
.style("fill", function(d) {
return d3.interpolateBlues(
(state_total_map.get(d.properties.fips) / state_total_map.max) ** 0.4
);
})
.attr("stroke-width", '1.5px')
.attr("stroke", "#ddd")
.attr("stroke-linejoin", "round");
let froth = map.append('g').attr('id', 'froth');
let bubbles = froth
.selectAll('circle.bubble')
.data(
city_info.sort((a, b) => d3.descending(a.cnt, b.cnt)).slice(0, 10 ** 2)
)
.join('circle')
.attr('class', 'bubble')
.attr("fill", "brown")
.attr("fill-opacity", 0.5)
.attr("stroke", "#fff")
.attr("stroke-width", 0.4)
.attr('r', d => d3.max([1, Math.sqrt(d.cnt) / 10]))
.attr('cx', d => proj([d.x, d.y])[0])
.attr('cy', d => proj([d.x, d.y])[1])
.attr('title', function(d) {
return `${d.city}, ${d.state}: ${d.cnt} hits`;
});
bubbles.nodes().forEach(d => tippy(d, { followCursor: true }));
let city_markers = map
.selectAll('circle.city')
.data(cities_to_show)
.join('circle')
.attr('class', 'city')
.attr('cx', d => proj([d.x, d.y])[0])
.attr('cy', d => proj([d.x, d.y])[1])
.attr('r', 3);
let city_labels = map
.selectAll('text.city')
.data(cities_to_show)
.join('text')
.attr('class', 'city')
.attr('x', d => proj([d.x, d.y])[0])
.attr('y', d => proj([d.x, d.y])[1])
.text(d => d.city.replace(' City', ''))
.style('font-family', 'sans-serif')
.style('font-size', '14px');
svg.call(
d3
.zoom()
.extent([[0, 0], [width, height]])
.translateExtent([[0, 0], [width, height]])
.scaleExtent([1, 5])
.duration(750)
.on('zoom', function() {
map.attr("transform", d3.event.transform);
map
.selectAll("path")
.attr("stroke-width", `${1.5 / d3.event.transform.k}px`);
map.selectAll("circle.city").attr("r", `${3 / d3.event.transform.k}px`);
map
.selectAll("text.city")
.style("font-size", `${14 / d3.event.transform.k ** 0.5}px`);
})
);
return div.node();
}