Reputation: 1317
I'm trying to implement a d3 globe with country hovers (e.g http://bl.ocks.org/KoGor/5994804), that also enables rotation/zooming regardless of where on the globe the mouse is (e.g. http://marcneuwirth.com/blog/2012/06/24/creating-the-earth-with-d3-js)
The problem with every example I've found of country hovers (like the one I mention above), is that dragging the globe is only possible either in the ocean or on land. I wondered why that was the case, but having tried to implement myself I realise now that it's because you can either choose to have your roughly 200 'path class=land' elements on top (meaning hovering works), or you can choose to have your 'path class=foreground/body etc' element on top (meaning hovering won't work because the listeners are applied to land elements behind the foreground).
Does anyone know of a way around this? I tried to apply a new drag listener to each of my land elements but couldn't get it working, and am not sure it's a good idea anyway to have multiple competing drag handlers.
Really appreciate any insight on a good approach to tackle the problem with - perhaps someone even knows of some examples that have successfully combined the 2 behaviours? Thanks!
Upvotes: 0
Views: 1904
Reputation: 108557
In the first example you link to, I just replicated the "land" drag handler on the "ocean" and it works flawlessly:
svg.append("path")
.datum({type: "Sphere"})
.attr("class", "water")
.attr("d", path)
.call(d3.behavior.drag()
.origin(function() { var r = projection.rotate(); return {x: r[0] / sens, y: -r[1] / sens}; })
.on("drag", function() {
var rotate = projection.rotate();
projection.rotate([d3.event.x * sens, -d3.event.y * sens, rotate[2]]);
svg.selectAll("path.land").attr("d", path);
svg.selectAll(".focused").classed("focused", focused = false);
}));
Working example here.
Is that what you are after?
Upvotes: 5