Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow custom coordinate space while dragging #1055

Closed
wants to merge 1 commit into from
Closed

Conversation

darwin
Copy link

@darwin darwin commented Feb 5, 2013

Problem: when you modify grandparent's transform during drag callback you get discontinuity in d3.event data. This leads to poor experience during dragging as described here: http://stackoverflow.com/questions/13078535/stuttering-drag-when-using-d3-behavior-drag-and-transform

Solution: allow specification of custom node which will be taken as base coordinate space for the drag session.

In our case of modification grandparent's transform, this usage fixes the issue:

d3.behavior.drag().base(function(target) { return target.parentNode.parentNode; });

Problem: when you modify grandparent's transform during drag callback you get discontinuity in d3.event data. This leads to poor experience during dragging as described here: http://stackoverflow.com/questions/13078535/stuttering-drag-when-using-d3-behavior-drag-and-transform

Solution: allow specification of custom node which will be taken as base coordinate space for the drag session.

In our case of modification grandparent's transform, this usage fixes the issue:

    d3.behavior.drag().base(function(target) { return target.parentNode.parentNode; });
@mbostock
Copy link
Member

mbostock commented Feb 6, 2013

I prefer the other solution in the linked question. Why doesn’t that work for you? You say "my data is bound below [the] g-node I want to transform", but it’s not clear why you can’t bind the data on the same level you are transforming.

@mbostock mbostock closed this Feb 6, 2013
@darwin
Copy link
Author

darwin commented Feb 7, 2013

Ok, no worries. I will keep my copy of drag behaviour in my client code.

Maybe there is a better solution of restructuring SVG DOM and binding the data to lower level, but it is non-trivial in my case. At least I didn't find a solution.

Imagine a complex example of WYSIWYG SVG editor:
http://cmx.io/edit

gizmo-tree

I have a tree hierarchy of editable objects. Each editable object has a gizmo which may contain multiple bones with drag behaviour as children. Bone data structure is represented by datum which is bound to .marker element. I have a ".mov" bone which should transform whole subtree of gizmos. I have a ".rot" bone which should rotate whole subtree of gizmos. Those bones need to be effective on .gizmo.entity to move the whole subtree.

How can I modify this code to apply data to @ΔentityGizmo while giving me data granularity per ".marker"?

  selection = @ΔentityGizmo.selectAll(".marker")
    .data(@entityMarkers)
    .enter()
      .append("g")
        .attr("class", (marker) -> "control marker #{marker.kind}")
        .on("dblclick", doubleClick)
        .call(drag)
  selection.each(render)

@mcallistera
Copy link

This code would help me too.. parent element that can be dragged around by dragging on child element, various other drag handles also within the parent. I don't understand how to implement the suggested solution without removing nesting, which will be a pain.

@chrissound chrissound mentioned this pull request Apr 21, 2015
@ebengtso
Copy link

I'm having the same problem, and I have a rectangle with resize handles, which i use to resize my rectangle.

<g>
<g id="rects" transform="translate(x,y)"><rect></g>
<g id="handles" transform="translate(x,y)"><rect id="handle1"><rect id="handle2"></g>
</g>

I have added a drag listener on each handle, and then I resize the rects group and apply a transform on both rects and handles to reposition the rectangle and handles.

If I change the position of the parent during drag I reproduce the problem, and using the origin does not solve the problem.

The only workaround to my problem is removing the group of handles and applying a transform on each of them to reposition each handle

I applied the same solution proposed by Darwin to the latest version of D3 and it works.

Would you be kind to reopen this issue?

Thanks

@thesamprice
Copy link

Ran into this same issue. D3 now has the container function that cleans up jitter.

        let dragGroup = d3.select('#parentContainerId')
        let drag = d3.drag()
        .on("start", this.PieceDragStarted.bind(this))
        .on("drag",  this.PieceDrag.bind(this))
        .on("end",   this.PieceDragEnd.bind(this))
        .container(dragGroup.node().parentNode)
         g.call(drag)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants