function hover(canvas, svg) {
const path = d3.geoPath(projection);
const highlight = svg
.append("path")
.attr("stroke", "white")
.attr("stroke-width", 2)
.attr("fill", "none");
const tooltip = new Tooltip();
svg.append(() => tooltip.node);
canvas
.on("mousemove", event => {
let [cx, cy] = d3.pointer(event);
const [x, y] = projection.invert([cx, cy]);
const candidates = index.search(x, y, x, y).map(i => features[i]);
const f = candidates.find(f => turf.booleanPointInPolygon([x, y], f));
if (f && data.has(f.id)) {
(cx += 10), (cy += 10);
if (cx + tooltip.width > width) cx -= tooltip.width + 20;
if (cy + tooltip.height > height) cy -= tooltip.height;
tooltip.show(f.properties.name, tooltipKeyValue(tooltipKey, format(data.get(f.id)), f));
tooltip.position(cx, cy);
highlight.attr("d", path(f));
} else {
highlight.attr("d", null);
tooltip.hide();
}
})
.on("mouseout", () => {
highlight.attr("d", null);
tooltip.hide();
});
}