score:4
Dirty fix
Change this...
.friction(0.9)
to this...
.friction(0)
Background
Inside the force layout module in d3, there is a force.tick
method that is called before every animation frame. This is where the node positions are recalculated. There is a calculation for links which takes into account link strength
, weights
and the target linkDistance
; a gravity
calculation which is a function of the distance of each node from the center of the layout; and a charge calculation which is based on the charge
, the chargeDistance
and the relative position of the nodes. There is also a calculation for friction
. All of these - except for the friction
calculation - take into account the current "temperature" of the layout (alpha
), which is really just an exponentially decaying value that is a function of how many ticks have elapsed since the layout was started.
These calculations are sequentially applied to all of the elements of the layout, the input positions for each step being the output of the previous. But "fixed" nodes are treated differently for the friction calculation and nodes being dragged are fixed
by the drag behavior.
friction
is not really "friction", it's more like velocity decay as explained in the WIKI, The friction
calculation is meant to maintain the velocity of the nodes by moving them away from their position at the end of the previous tick (px
, py
). The distance moved away is proportional to the velocity of each node which is based on the distance between (px
, py
) and the position calculated by the previous steps (links, charge and gravity) in the current tick
(in reality it's a little more complicated than that because the charge calculation is actually "non-causal" and changes the previous positions, but this doesn't affect the principle of the friction calculation).
During the drag, (px
, py
) is updated with the mouse position by the drag behavior on every mousemove
. Then, on the next tick, these values are copied to (x
, y
) in the force layout. So, during the drag, the previous position is actually the current position and vice versa! Therefore, when the drag ends, the velocity used in the friction calculation is in the opposite direction to it's actual velocity, so the friction
calc tries to maintain this... and that's why it jumps back.
Dead stop
My next move would be to find a way to set (px
, py
) to (x
, y
) in the dragend
event handler.
Like this for example...
var stdDragEnd = force.drag().on("dragend.force");
force.drag().on("dragend.force", myDragEnd);
function myDragEnd(d) {
d.px = d.x; d.py = d.y;
stdDragEnd.call(this, d)
}
You can put this anywhere in the code where your force
variable is already defined. The idea is to hook the standard behaviour rather than replace it.
Now, even if you set friction to 1.0, the node will stop dead after the dragend.
You don't need to preserve the this
context based on the current state of the code by the way, but anyway, it's good practice I guess. Who knows what the future will bring lah ;)
Source: stackoverflow.com
Related Query
- d3.js Node "jumps back" on fast drag in force layout
- Disable node drag in force layout
- d3.js force layout drag stops working after deleting a node
- d3 force layout zoom and pan conflict with node drag
- Fix Node Position in D3 Force Directed Layout
- D3 force directed graph with drag and drop support to make selected node position fixed when dropped
- d3.js: suggested node position in force layout
- D3 force layout fix root node at the center
- D3 Force Layout Graph - Self linking node
- Space out nodes evenly around root node in D3 force layout
- Add text label to d3 node in Force layout
- Align Marker on node edges D3 Force Layout
- Recentering D3 force layout diagram on node click
- Inserting a line break in D3 force layout node labels
- How to display a text when mouseover a node in D3 force layout
- Center force directed layout after tick using root node (return to center)
- How to get the same node positions in d3's force layout graph
- d3.js: Drag is disabled when use zoom with force layout
- D3 Force Layout : How to force a group of node to stay in a given area
- d3js force layout dynamically adding image or circle for each node
- Creating force layout node labels in d3.js
- How to add a force drag event in D3 and make the node stay where i leave it?
- Force layout inside force layout: How to drag inner nodes
- How to pan to a node using d3's force layout
- d3: Optionally add child elements based on node content in force layout
- d3.js Bottom to Top force layout - drag behavior
- Show div element on mouseover for node in D3 force layout
- Can't draw links by node property using D3 force layout
- Two labels on one node in a D3 force layout
- drag multiple nodes in d3 force directed layout
More Query from same tag
- Animating data motion between nodes in d3
- sorting bars in d3.js doesn't change bar position
- Replacing text instead of appending in d3 & Jquery
- d3.js: size of parents = sum of size of children
- Integrate data in html for Parallel Coordinates visualization in D3
- How to fix this toggle function in d3?
- Install D3 on Meteor Angular2
- splitting text for some bold and some not on functional javascript piece
- d3 can I recalculate data in place?
- How to proper zoom and pan only the y-axis in D3 v5 y-axis
- reading d3 data in from a file rather than hard coding it into a programme
- d3 circle onclick event not firing
- I am learning D3.js but I don't get the same console output as tutorials
- D3 + VueJs + Typescript | How to import D3.js Library?
- D3.js create a dynamic color() function
- d3 (v4) zoom using transitions doesn't seem to work
- Why would a string of methods need to be separated?
- d3.js force-directed graph maintain constant link distances
- NVD3 & IE Object doesn't support property or method addGraph
- How to zoom the path in d3.js
- Having trouble building a tree using d3.tree() in d3v4
- ES6 export of a script
- Is it possible to have a button start a download of a dom element?
- D3.JS Click Event problem, using a svg map
- d3.js limit panning in force layout
- Adding c3.js padding without cutting off graph
- d3.js data.columns doesn't exist?
- d3.js circles are not appearing
- How to rotate an object around the center in d3.js
- How to stop D3.js from creating infinite areas from linear polygons