How to snap svg element to grid while dragging in force layout

pberden

I have got this d3.js force layout where the nodes are rectangles with associated text. Whenever a node is dragged the position is fixed, like in mike's example.

I want the nodes to snap to an invisible grid when they are dragged. So that they are neatly aligned. Therefore I've added this to the drag event:

var grid = 50;
d3.select(this)
  .attr("x", function(d) { return Math.round(d3.event.x/grid)*grid; })
  .attr("y", function(d) { return Math.round(d3.event.y/grid)*grid; });

Somehow this is not working as expected. I guess it has something to do with the tick function of the force layout. But I'm not sure, hence the force.stop(), force.start() calls to see whether that helped.

I've also tried to nest the rect and text in a g element and use transform(translate) to position the nodes. But also without succes.

mgraham

https://jsfiddle.net/e5fxojvm/

function dblclick(d) {
  d3.select(this).classed("fixed", d.fixed = false);
}

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

function dragged(d,i) {
  //force.stop();
  var grid = 50;

  var nx = Math.round(d3.event.x/grid)*grid;
  var ny = Math.round(d3.event.y/grid)*grid;

  d.px = nx;
  d.py = ny;
}

function dragended(d) {
  //force.start();
  console.log(this);
}

the coordinates for nodes are taken from d.x and d.y for each data point in the nodes array, so though you update the on-screen element's x and y attributes, the next tick resets it to d.x and d.y, giving that little movement you see in your demo (though it doesn't move again after that point as the node is fixed)

You need to discretise the node position data - d.x and d.y - not just the node DOM element's position attributes, and unintuitively enough for fixed nodes this seems to be done through d.px and d.py - the previous node coordinates. It seems fixed nodes in the tick calculate d.x and d.y by setting them to d.px and d.py (https://github.com/mbostock/d3/blob/master/d3.js#L6299)?

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

d3 force layout snap to grid on drag

From Dev

Stop dragging on a force layout

From Dev

How to get the SVG root element in Snap.svg?

From Dev

jQuery draggable Snap to Center while dragging

From Dev

How to convert a DOM element into a Snap.svg element?

From Dev

Dragging SVG element over another SVG element

From Dev

How do I enable scrolling while dragging on my target element?

From Dev

How to change sortable element's style while dragging?

From Dev

how to tell if an input range element is increasing or decreasing while dragging

From Dev

Snap SVG - Animating a path element

From Dev

Snap SVG - Animating a path element

From Dev

Change element class while dragging

From Dev

How to trigger with Snap Svg?

From Dev

Snap SVG dragging and scaling: My rectangle won't stop scaling?

From Dev

Bounding snap.svg element to svg area

From Dev

ViewDragHelper - Child layout changes ignored while dragging

From Dev

Jquery:Draw Svg Line Dynamically While Dragging

From Dev

Jquery:Draw Svg Line Dynamically While Dragging

From Dev

How do I update an SVG text element using Snap.svg?

From Dev

How can I wrap/snap/fit divs into a grid layout, TETRIS style?

From Dev

How can I wrap/snap/fit divs into a grid layout, TETRIS style?

From Dev

How to make the Draggable element to get visible on top of all the element in the screen while dragging?

From Dev

Snap.svg Drag while Zoomed

From Dev

Is there any method to find element by snap id in Snap svg?

From Dev

How to persist Snap SVG objects?

From Dev

How to use Mina in Snap svg?

From Dev

Snap.svg - Select second text element?

From Dev

Snap SVG - Moving a loaded element around

From Dev

Snap SVG translate element that has rotation

Related Related

HotTag

Archive