Reputation: 1753
I am having some issues applying D3's behavior.drag() on a map. In this example, dragging the map results in a very fast pan, and the point clicked does not stay with the mouse - http://bl.ocks.org/jczaplew/6453048
My drag behavior code looks like this -
var drag = d3.behavior.drag()
.origin(function() { return {x: rotate[0], y: -rotate[1]}; })
.on("drag", function() {
rotate[0] = d3.event.x;
rotate[1] = -d3.event.y;
// Refresh the map
projection.rotate(rotate);
path = d3.geo.path().projection(projection);
d3.selectAll("path").attr("d", path);
});
What I need:
I suspect this issue has something to do with drag.origin(), but perhaps I shouldn't be using d3.behavior.drag() at all? Any and all assistance is greatly appreciated!
Upvotes: 3
Views: 3171
Reputation: 1753
I think I found a potential (albeit slightly unsatisfactory) answer. Using the logic from this example (http://mbostock.github.io/d3/talk/20111018/azimuthal.html) I created this - http://bl.ocks.org/jczaplew/6457917
The key bit is to keep track of the position of the start of the drag (i.e. when the user clicks). The logic for the lat and long of the desired rotation is
start projection rotation + (start screen position - destination screen position) / 4
and the drag behavior now looks like this
var drag = d3.behavior.drag()
.on("dragstart", function() {
var proj = projection.rotate();
m0 = [d3.event.sourceEvent.pageX, d3.event.sourceEvent.pageY];
o0 = [-proj[0],-proj[1]];
})
.on("drag", function() {
if (m0) {
var m1 = [d3.event.sourceEvent.pageX, d3.event.sourceEvent.pageY],
o1 = [o0[0] + (m0[0] - m1[0]) / 4, o0[1] + (m1[1] - m0[1]) / 4];
projection.rotate([-o1[0], -o1[1]]);
}
// Update the map
path = d3.geo.path().projection(projection);
d3.selectAll("path").attr("d", path);
});
This still feels quite hacky, and it doesn't seem to scale very well. For example, changing the projection and the projection scale seems to require tweaking the normalization of the desired rotation coordinates from 4 to something else to achieve the same smoothness and behavior.
Anyone have alternative ideas? I'd love to see other, more elegant ways to accomplish this functionality.
Upvotes: 4