function make_map() {
let height = 0.4 * width;
let div = d3
.create("div")
.style("width", `${width}px`)
.style("height", `${height}px`)
.style("overflow", "hidden");
let svg = div
.append("svg")
.style("width", `${width}px`)
.style("height", `${height}px`)
.style("overflow", "hidden")
.style("background", "white");
let proj = d3
.geoIdentity()
.reflectY(true)
.fitSize([width, height], map_data.tracts);
let path = d3.geoPath().projection(proj);
let map = svg.append("g");
let tracts = map
.append("g")
.selectAll("path.tract")
.data(map_data.tracts.features)
.join("path")
.attr("d", path)
.attr("class", "tract")
.attr("id", (d, i) => `tract${i}`)
.attr("data-geoid", (d) => d.properties.GEOID)
.style("fill", function (d) {
return color_map.get(d.properties.GEOID);
})
.style("stroke-width", "0.2px")
.style("stroke-opacity", 0.2)
.style("stroke", "#000")
.style("stroke-linejoin", "round");
tracts
.on("mouseenter", function () {
d3.select(this).style("stroke-width", "1px").style("stroke-opacity", 1);
})
.on("mouseleave", function () {
d3.select(this)
.style("stroke-width", "0.2px")
.style("stroke-opacity", 0.2);
});
tracts.nodes().forEach((c) => {
tippy(c, {
allowHTML: true,
maxWidth: 420,
theme: "light",
content: table_map.get(c.getAttribute("data-geoid"))
});
});
let cities = map.append("g");
let city_names = cities
.selectAll("text.city")
.data(city_data)
.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)
.style("font-family", "sans-serif")
.style("font-size", "14px")
.attr("pointer-events", "none");
let city_markers = cities
.selectAll("circle.city")
.data(city_data)
.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)
.style("fill", "yellow")
.attr("pointer-events", "none");
svg.call(
d3
.zoom()
.extent([
[0, 0],
[width, height]
])
.translateExtent([
[0, 0],
[width, height]
])
.scaleExtent([1, 8])
.duration(750)
.on("zoom", function (evt) {
map.attr("transform", evt.transform);
map.selectAll(".highlight").remove();
map.selectAll("circle.city").attr("r", `${3 / evt.transform.k}`);
map
.selectAll("text.city")
.style("font-size", `${14 / evt.transform.k ** 0.75}px`);
})
);
return div.node();
}