I’m trying to use d3.js’s d3.behavior.drag() drag event to update my data model (without setting the element position immediately), then run my “draw” function to update all elements based on the updated model. Additionally, I’m using a translate transform on the containing group element in order to move all the elements associated with the dragged object (I removed the extra elements from the example linked below). This causes the dragged elements to stutter as it’s dragged, which gets worse the faster you drag it.
See this stripped-down example on jsFiddle.
Here’s the code of the example:
blocks = [
{ x: 0, y: 0 }
];
drag = d3.behavior.drag()
.origin(Object)
.on("drag", function(d) {
d.x = d3.event.x;
d.y = d3.event.y;
draw();
});
svg = d3.select("body")
.append("svg:svg")
.attr("width", 600)
.attr("height", 600);
function draw() {
g = svg.selectAll("g")
.data(blocks);
gEnter = g.enter().append("g");
g.attr("transform", function(d) { return "translate("+d.x+","+d.y+")"; });
gEnter.append("rect")
.attr("height", 100)
.attr("width", 100)
.call(drag);
}
draw();
You are calling
dragon therectelement, but you’re transforming its parent: thegelement.The problem is that the drag component uses the mouse location relative to the parent to determine the new
d3.event.xandd3.event.y. So, if you move (i.e.transform) the parent while the user drags, things get messed up.The solution is to call
dragon the same element that you are moving around; in this case thegelement:See corrected Fiddle: http://jsfiddle.net/EMNGq/14/