question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Dragging does not seem to work for elements UNLESS created with `data(data).enter().append()`

See original GitHub issue

I have a project with a draggable circle. In the process of upgrading from D3 v3 > v4 the drag behaviour broke. It only seems to work when the draggable element is created using data([1]).enter().append('circle'). See the simple jsfiddle example for a simplified version:

// Circle dragging: OK
d3
  .select("svg")
  .selectAll("circle")
  .data([1])
  .enter()
  .append("circle")
  .style("fill", 'blue')
  .attr("r", 30)        
  .attr("cx", 2*30)
  .attr("cy", 2*30)

// Circle dragging: FAILS
d3
  .select("svg")
  .append("circle")
  .style("fill", 'green')
  .attr("r", 30)     
  .attr("cx", 4*30)
  .attr("cy", 4*30)

d3
  .select("svg")
  .selectAll("circle")
  .call(d3.drag()
    .on("start", dragstarted)
    .on("drag", dragged)
    .on("end", dragended))


function dragstarted(d) {
  d3.select(this).raise().classed("active", true);
}

function dragged(d) {
  d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
}

function dragended(d) {
  d3.select(this).classed("active", false);
}

Can someone take a look?

Discussion on StackOverflow here

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
mbostockcommented, Aug 1, 2016

Your question pertains more to the JavaScript language than D3, so it’d probably be more appropriate for you to take it to Stack Overflow than to tack it on to the end of this issue. That said, here’s my answer.

An assignment expression d.x = value in JavaScript evaluates to value, so if you want to assign a property and pass a value to a function (such as selection.attr) you can save a few characters by doing both at the same time. It doesn’t really matter whether you assign d.x as a separate statement or as part of the call to selection.attr.

If you don’t set d.x and d.y, then you’re updating the DOM (the circle’s cx and cy attributes), but you’re not updating the data values (the circle’s datum d). So if you then reset the circle’s cx and cy attributes to the data (which you didn’t update while dragging), you’d be reverting the circle’s position back to its old position. The drag behavior doesn’t update the data for you—it just reports the new position, and it’s your responsibility to use that however you like, whether it’s to update the DOM or to update your data.

1reaction
erikodocommented, Jul 30, 2016

Mike, would you mind explaining this piece of code?

function dragged(d) {
  d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
}

How is it that a variable assignment inside the attr method reassigns d.x and also sets the attribute “cx” to d3.event.x?

This is what I would have written:

function dragged(d) {
  d.x = d3.event.x;
  d.y = d3.event.y;
  d3.select(this).attr("cx", d3.event.x).attr("cy", d3.event.y);
}

Still, why does the circle snap back to it’s original position if d.x and d.y are not set to d3.event?

I don’t understand why a new drag event makes the circle revert back to it’s old attributes. Thanks!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Attaching drag behaviour without using data().enter() in D3 v4 ...
When dragging circle elements in SVG, the default subject is the ... If the subject is null or undefined, no drag gesture is...
Read more >
Using enter and append - Jonathan Soma
After you bring data, .enter() is a way of talking about all of the data points that don't have an element yet. ......
Read more >
D3 Data Joins | D3 in Depth
A data join creates a correspondence between an array of data and a selection of HTML or SVG elements. Joining an array to...
Read more >
Drag operations - Web APIs - MDN Web Docs - Mozilla
If the drag contains no drag data items, or all of the items have been subsequently cleared, then no drag will occur. Setting...
Read more >
Aggregate, Join, or Union Data - Tableau Help
Aggregate, join, or union your data to group or combine data for analysis. Note: Starting in version 2020.4.1, you can now create and...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found