score:41

Accepted answer

You are calling drag on the rect element, but you're transforming its parent: the g element.

The problem is that the drag component uses the mouse location relative to the parent to determine the new d3.event.x and d3.event.y. So, if you move (i.e. transform) the parent while the user drags, things get messed up.

The solution is to call drag on the same element that you are moving around; in this case the g element:

function draw() {
  g = svg.selectAll("g")
    .data(blocks);

  gEnter = g.enter().append("g")
    .call(drag);

  g.attr("transform", function(d) { return "translate("+d.x+","+d.y+")"; });

  gEnter.append("rect")
    .attr("height", 100)
    .attr("width", 100);
}

See corrected Fiddle: http://jsfiddle.net/EMNGq/14/

score:3

Nautat provided good solution for your case.

My case is slightly more complicated. My data is bound below g-node I want to transform. In this case I cannot simply move .call(drag) to g-level.

I submitted a pull request to make base coordinate space customisable: https://github.com/mbostock/d3/pull/1055

score:7

I had the same issue as Darwin. The drag handler is on the child object that has D3 Data attached but the transform needs to be applied to the parent group (not d3).

I solved it by setting the origin function to return x:0, y:0 and then using the x value in the event rather than the dx.

e.g

var drag = d3.behavior.drag()
    .origin(function(d,i) { return {x:0, y:0}; })
    .on("drag", function (d) {  movePosition(d3.event.x);   });

Related Query