Check out this weirdness that’s part of handling d3 dragging/event handling:
var drag = d3.behavior.drag()
.on("drag", function(d,i) {
d.x += d3.event.dx
d.y += d3.event.dy
d3.select(this).attr("transform", function(d,i){
return "translate(" + [ d.x,d.y ] + ")"
})
});
var face = d3.select("#charts")
.append("svg:g")
.data([ {"x":x, "y":y} ])
.call(drag);
That last line doesn’t seem to make much sense, does it? What exactly are we invoking when we say .call(drag)
? By standard javascript syntax, it seems like .select()
or .append()
is returning a function, which we’re then invoking, with our drag variable as the context. Huh???
As it turns out, d3 overwrites the call function with their own:
d3_selectionPrototype.call = function(callback) {
var args = d3_array(arguments);
callback.apply(args[0] = this, args);
return this;
};
So when we invoke selection.call(drag)
, it’s actually invoking the above function, not the JS default, and passing drag
as a callack function, not as the context. Our custom function (drag
) is then run on the selection, with an event handler for the event drag
. Confusing, but cool.