Reputation: 2119
I've been trying to get my force directed graph to go faster/smoother, and it seems commenting this part out of the "tick" function does the trick. Of course, it also makes all the edges disappear although the nodes still move together as if attached by invisible threads.
I have about 2-3 hundred nodes in a network-ish graph and when setting the opacity of each element I also check it's weight and if it's 1 I remove it.I repeat this for all nodes and text labels. (and edges using d.target.weight)
Is it just a number of nodes that weighing down everything? After removing the elements down to 20 or so why is it still so slow? Do I really have to piggyback my removal onto .style("opacity", function(d){//do stuff, return 1;})?
force.on("tick", function() {
// edges.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; })
// .style("stroke", function(d){
// return d.source.color;
// });
nodes.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
text.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; });
});
functions for drawing the svg elements if it helps:
//Create edges as lines
var edges = group.selectAll("line")
.data(dataset.edges)
.enter()
.append("line")
.style("stroke", function(d,i){
if (d.target.weight === 1)
d3.select(this).remove();
return "#FFFFFF";
})
.style("opacity",0.5)
.style("stroke-width", 2);
//Create nodes as circles
var nodes = group.selectAll("circle")
.data(dataset.nodes)
.enter()
.append("circle")
.style("opacity",0.8)
.attr("r", function(d,i){
if (d.weight === 1)
d3.select(this).remove();
return nodeScale(d.weight * 2);
})
.style("fill", function(d, i) {
return d.color;
})
.call(force.drag);
var text = group.selectAll("text")
.data(dataset.nodes)
.enter()
.append("text")
.attr("fill","black")
.style("font-size",function(d){
return d.size;
})
.style("text-anchor", "middle")
.text(function(d){
return d.name;
})
.style("opacity",function(d){
if (d.weight === 1)
d3.select(this).remove();
else
return 0.8;
})
.on("mouseover",function(){
d3.select(this)
.style("opacity",1)
.style("font-size", 25);
})
.on("mouseout",function(){
d3.select(this)
.style("font-size", function(d) { return d.size; });
})
.call(force.drag);
Also the initiation function, became quite random after I fiddle around with it a lot: (I also have a slider for each one that I play with when rendered)
var force = d3.layout.force()
.nodes(dataset.nodes)
.links(dataset.edges)
.size([w, h])
.linkDistance([50])
.charge([-2000])
.friction(0.5)
.gravity(0.5)
.theta(0.5)
.start();
Upvotes: 2
Views: 2641
Reputation: 2119
I believe the problem was that removing an element still doesn't affect the actual dataset being used which is composed of hundred of nodes in this case.
Changing the code to removing the element from the dataset and using exit().remove() makes it go faster.
Upvotes: 1