Drag an svg element using a child element as a "handle"

1,443 views
Skip to first unread message

Jeff

unread,
Apr 15, 2012, 2:14:13 PM4/15/12
to d3...@googlegroups.com
Hello all,
Pretty new to d3, so first, a big thanks to Mike and contributors for a great library!

Now hoping for some enlightenment. When I try to move a parent element using a drag behavior defined on a child, I get jittery, back-and-forth movement of the translated parent object. I figure I'm missing some offset x,y property, but I'm not clear what it is. Can anyone shed some light?

Here's a minimal working example: http://jsfiddle.net/kU8Fm/

And here's the boiled down parts:

var drag = d3.behavior.drag()
    .on("drag", function(d) {
        d.x += d3.event.dx; // something missing here?
        d.y += d3.event.dy;
        parent.attr("transform", "translate(" + [d.x, d.y] + ")")
    });

var parent = svg.append("g") // ...drag this
    .data([{x: 0, y: 0}]);

var child = g.append("circle") // ... by grabbing this
    ...
    .call(drag);


Thanks in advance!

Cheers,
Jeff

Jeff

unread,
Apr 16, 2012, 1:39:32 PM4/16/12
to d3...@googlegroups.com
I got this working, but in reading the source for d3.behavior.drag, I have a follow up question. :)

I got the behavior I needed (http://jsfiddle.net/kU8Fm/1/) by capturing the mouse offset in the dragstart event:

var drag = d3.behavior.drag()
    .on("dragstart", function(d) {
        d.dragstart = d3.mouse(this); // store this
    })
    .on("drag", function(d) {
        var m = d3.mouse(this);
        d.x += m[0] - d.dragstart[0];
        d.y += m[1] - d.dragstart[1];
        parent.attr("transform", "translate(" + [d.x, d.y] + ")")
    })

Which brings me to my question: In d3.behavior.drag, there's a recently added function named 'origin' that seems capable of something similar to this, though perhaps not exactly. It's not listed in the API though. Is there an example of its usage anywhere? Is it designed for this?

Cheers,
Jeff

Mike Bostock

unread,
Apr 19, 2012, 1:53:22 AM4/19/12
to d3...@googlegroups.com
> In d3.behavior.drag, there's a recently added function named 'origin'
> that seems capable of something similar to this, though perhaps
> not exactly.

See the examples directory:

https://github.com/mbostock/d3/blob/master/examples/drag/drag.html

That example uses `Object` as the origin function, which is just
another way of using the identify function. In other words, the data
bound to the draggable element is an object with `x` and `y`
properties, so using the identity function as the origin lets the drag
behavior read the origin of the circle when you start dragging.

Mike

Reply all
Reply to author
Forward
0 new messages