Reputation: 344
How can i disable the animation while dragging the current node in the force simulation in the d3 version 4
Below is the code which is used for drag the node
var node = svg.selectAll(".node")
.data(json.nodes)
.enter().append("g")
.attr("class", "node")
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
function dragstarted(d) {
if (!d3.event.active) force.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) force.alphaTarget(0.3);
// d.fx = null;
//d.fy = null;
}
When i tried to stop the force while in dragged method it doesn't work out. Please suggest me the best way to stop the animation
Please check this fiddle
Upvotes: 2
Views: 2581
Reputation: 911
Its actually very easy. Simply don't define :
.call(d3.drag().on("start", drag_start)
.on("drag", drag_drag)
.on("end", drag_end))
This is what is controlling the animation part, and yet you find problem in late loading of your graph due to huge data or something then i suggest add a property called .alphaDecay(0.9), this particular thing will decrease the link length thus decreasing your load time of graph.
Upvotes: 0
Reputation: 102174
It's not exactly clear what you mean by "disable the animation". I suppose that you're talking about the movement of the other nodes... well, that's quite the expected behaviour, since you're reheating the simulation.
A possible solution is setting the fx
and fy
property of all nodes when the simulation ends:
simulation.on("end", function() {
node.each(function(d) {
d.fx = d.x;
d.fy = d.y;
})
})
Here is your code with that change. Wait until the simulation ends (aprox. 5 seconds) and then drag the nodes:
var nodes = [{
"id": 1,
"name": "server 1"
}, {
"id": 2,
"name": "server 2"
}, {
"id": 3,
"name": "server 3"
}, {
"id": 4,
"name": "server 4"
}, {
"id": 5,
"name": "server 5"
}, {
"id": 6,
"name": "server 6"
}, {
"id": 7,
"name": "server 7"
}, {
"id": 8,
"name": "server 8"
}, {
"id": 9,
"name": "server 9"
}]
var links = [{
source: 1,
target: 2
}, {
source: 1,
target: 3
}, {
source: 1,
target: 4
}, {
source: 2,
target: 5
}, {
source: 2,
target: 6
}, {
source: 3,
target: 7
}, {
source: 5,
target: 8
}, {
source: 6,
target: 9
}, ]
var index = 10;
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
node,
link;
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) {
return d.id;
}))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2));
update();
function update() {
link = svg.selectAll(".link")
.data(links, function(d) {
return d.target.id;
})
link = link.enter()
.append("line")
.attr("class", "link");
node = svg.selectAll(".node")
.data(nodes, function(d) {
return d.id;
})
node = node.enter()
.append("g")
.attr("class", "node")
.on("click", click)
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
node.append("circle")
.attr("r", 2.5)
node.append("title")
.text(function(d) {
return d.id;
});
node.append("text")
.attr("dy", 3)
.text(function(d) {
return d.name;
});
simulation
.nodes(nodes)
.on("tick", ticked)
.on("end", function() {
node.each(function(d) {
d.fx = d.x;
d.fy = d.y;
})
})
simulation.force("link")
.links(links);
}
function click(d) {
nodes.push({
id: index,
name: "server " + index
});
links.push({
source: d.id,
target: index
});
index++;
update();
}
function ticked() {
link
.attr("x1", function(d) {
return d.source.x;
})
.attr("y1", function(d) {
return d.source.y;
})
.attr("x2", function(d) {
return d.target.x;
})
.attr("y2", function(d) {
return d.target.y;
});
node
.attr("transform", function(d) {
return "translate(" + d.x + ", " + d.y + ")";
});
}
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart()
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
}
.link {
stroke: #aaa;
}
.node {
pointer-events: all;
stroke: none;
stroke-width: 40px;
cursor: pointer;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="600" height="400"></svg>
Upvotes: 1
Reputation: 327
Take a look at this example: http://bl.ocks.org/norrs/2883411 as it seems to accomplish what you are after.
As indicated in the example and the related SO question (D3 force directed graph with drag and drop support to make selected node position fixed when dropped) you will probably be better off creating and using your own drag listener to achieve this specific behaviour.
Upvotes: 0