D3 canvas globe mouse events

An example of D3 canvas globe: http://bl.ocks.org/mbostock/4183330

What I'm trying to do is click on a country and have the globe rotate so that country is centered on the globe.

How do I do add an eventlistener (D3's .on or jQuery's .bind or plain addEventListener) to the country shapes so I can figure out which country I've clicked on?

Thoughts?

Answers


The example you've linked to is using the HTML5 canvas renderer. As far as I know, it doesn't support binding click events to specific regions.

This example uses SVG, which is not as performant, but would allow you to bind events to each country.

Something like,

svg.selectAll(".countries path")
.on('click', function(d, i) {
   /* perform whatever logic here related to country associated with d */
});

In this case, to rotate the globe, you'll want to look at setting the projection's rotation.

Hope this helps.

Edit

Regarding using a canvas, it might be possible to use the d3.mouse wrapper along with d3.geo.projection().invert if your projection supports it, to figure out the projection coordinates of the mouse pointer.

At that point, you'll have to figure out if your point is 'inside' any of the countries. That might be more difficult.


Thanks to John Ledbetter's answer I was able to create a working demonstration of a globe rotating to the point a user clicked on.

It doesn't solve the second part of the question, highlighting the country the user clicked on. But the code below does expose the longitude/latitude, so it's possible to build towards that solution from here.

Full Example

Here's a complete example of rotating to a point when a user clicks on a transparent 3d globe on CodePen.

The Important Parts

The important pieces to doing a globe rotation when a user clicks a location on the globe are:

var canvas = d3.select("#map").append("canvas");

canvas.on("mousedown.drag", onMapClick);

function onMapClick() {
  rotateMap(projection.invert(d3.mouse(this)));
}

function rotateMap(p) {
  d3.transition()
    .duration(850)
    .tween("rotate", function() {
        var r = d3.interpolate(projection.rotate(), [-p[0], -p[1]]);

        return function(t) {
          projection.rotate(r(t));
          redrawMap();
        };
      })
    .transition();
}

The user click is converted to latitude/longitude using the projection.invert(d3.mouse(this)).

The rotation calculation function is created in the d3.interpolate(projection.rotate(), [-p[0], -p[1]]) line.

And finally the globe rotation itself occurs in the tween using at the projection.rotate(r(t)) line.

References

On the topic of map navigation, Jason Davie's article Rotate the World does a great job explaining the difficulties of navigating a 3d space with a 2d representation.


Need Your Help

Grow a div to the left

html css html5 css3

Is this even possible? The basic setup is a sidebar on the right with div elements in it.

Multicast to directly connected WIFI device

java camera udp multicast sony

I have a WIFI device, that I am experimenting with. From my macbook I can make a direct connection to the device over wifi. After I have WIFI connection I should be able to communicate with the dev...