Fix Node Position in D3 Force Directed Layout
Set d.fixed
on the desired nodes to true, and initialize d.x
and d.y
to the desired position. These nodes will then still be part of the simulation, and you can use the normal display code (e.g., setting a transform attribute); however, because they are marked as fixed, they can only be moved by dragging and not by the simulation.
See the force layout documentation for more details (v3 docs, current docs), and also see how the root node is positioned in this example.
d3js create a force layout with fixed nodes
the solution is simple insert into the nodes object x,y coordinates and fixed:true like this
{ name: "Sara", id:"1", x:239.31191418045182, y:296.78520431471384, fixed:true},
{ name: "Raul", id:"2", x:261.1651006560272, y:200.78448049334696, fixed:true},
{ name: "Stefano", id:"3", fixed:false},
{ name: "Michele", id:"4", fixed:false}
this is a working example http://jsbin.com/omokap/8/edit please add yourself d3js library.
for my purpose works fine.
Fix position of force-graph node using D3.js
I have found a solution:
.nodeVal(node => {
node.fx = 500;
node.fy = 500
})
Using the nodeVal
method, I can access the attributes of the nodes to fix it. Adding a if
statement would allow me to change it only if it the specific nodes I need. Thanks for everyone's help!
Fixed nodes not being fixed (d3 Force Directed Graph)
d3.js v4 does not have a fixed
property. Instead, you need to set the nodes fx
and fy
attributes. Note, your drag functions are already doing this.
.nodes(graph.nodes.map(c => {
if(latlong[c.code] === undefined) {
console.log(c,'missing lat/long data')
return c
}
c.fx = c.x = (+latlong[c.code][0])
c.fy = c.y = (+latlong[c.code][1])
return c
}))
https://codepen.io/anon/pen/ZKXmVe
Fix only one dimension of a node in force layout?
This isn't directly supported in D3, but you can do it manually by resetting the coordinate you want to remain constant in the tick
handler function.
force.on("tick", function() {
nodes.each(function(d) {
d.x = d.px = d.savedX; // similar for y
});
// do other stuff
});
This requires you to store the desired value with the data bound to the nodes, in the example in an attribute savedX
(although you can obviously use any other name as long as it's not used by anything else).
D3.js version 4 make nodes sticky
Not sure if the answer is needed but I was able to make Nodes sticky, actually it was pretty simple fix in your code and I learnt it when I reviewed this Issue on GitHub - Issue #35
The idea of fixing a node is very simple now in v4 of d3 library, in your above code just comment following two lines:
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
//d.fx = null;
//d.fy = null;
}
Theory is, to fix the node, we need to set node.fx
& node.fy
which your code is actually setting in dragged()
function definition.
Hope it helps, as it does to me.
The same is also mentioned in the documentation here - D3 V4 - API
To fix a node in a given position, you may specify two additional
properties:
fx
- the node’s fixed x-positionfy
- the node’s fixed y-position
Related Topics
Typescript Type 'String' Is Not Assignable to Type
Sort Objects in an Array Alphabetically on One Property of the Array
Jquery .On() Method with Multiple Event Handlers to One Selector
Validate That a String Is a Positive Integer
Node.Js Tail-Call Optimization: Possible or Not
Javascript: How to Get Chrome to Break on All Errors
How to Get the Current Time Only in JavaScript
Split String Only on First Instance of Specified Character
How to Reload or Re-Render the Entire Page Using Angularjs
How to Check Whether an Object Is a Date
Chrome Extension: How to Save a File on Disk
Convert Js Date Time to MySQL Datetime
What's the Difference Between Reflow and Repaint
Meteor: Proper Use of Meteor.Wrapasync on Server