Reputation: 4590
I created a D3 force directed graph having reactangles as nodes and links joining them at the end of the perimeter. Since I need to align the divs according to the rectaengles, I have created two svgs and links in svg1 and acc to z-index, above it are divs and above divs is second svg containing rectangles/nodes( having opacity 0 so that divs are visible). The issue I am having is that the graph is slow in IPAD and it's browser minimizes about 80% times on opening of the page on which the graph was drawn. On debugging, I saw that the problem is with my tick function, whose code is here,
force.start();
q = d3.geom.quadtree(nodes),count=0;
// define what to do one each tick of the animation
force.on("tick", function() {
i = 0;
//applying collision detection to avoid overlapping by default
if(!mapCreated){
while (++i < nodes.length) q.visit(collide(nodes[i]));
}
//this checks if node tries to move out (limitToCorners does that)
node.attr("x", function(d) { return d.x = limitToCorners(d.x,"x"); })
.attr("y", function(d) { return d.y = limitToCorners(d.y,"y"); });
//this puts the link attribute to link directly to center of rectangle
link.attr("x1", function(d) { return d.source.x+nodeModel.width/2; })
.attr("y1", function(d) { return d.source.y+nodeModel.height/2; })
.attr("x2", function(d) { return d.target.x+nodeModel.width/2; })
.attr("y2", function(d) { return d.target.y+nodeModel.height/2; });
//changing the CSS so that divs are in same place as the nodes
changeGoalsPosition(refList);
// changing the attributes of lines on svg so that it comes to the end of rectange (calculateLinkEndPoints does that)
for(i=0;i<lines.length;i++){
var obj = {};
obj.source = {
x: parseInt(linksRefList[i].attr("x1")),
y: parseInt(linksRefList[i].attr("y1"))
};
obj.target = {
x: parseInt(linksRefList[i].attr("x2")),
y: parseInt(linksRefList[i].attr("y2"))
};
$(lines[i]).attr("x1", function(d) { return calculateLinkEndPoints(obj,"sx"); })
.attr("y1", function(d) { return calculateLinkEndPoints(obj,"sy"); })
.attr("x2", function(d) { return calculateLinkEndPoints(obj,"tx"); })
.attr("y2", function(d) { return calculateLinkEndPoints(obj,"ty"); });
}
});
Upvotes: 2
Views: 1541
Reputation: 109232
The processing you're doing in the tick
function is quite expensive. You basically have 2 options.
tick
events.Whether you can do the former will depend on your application. For the latter, you could do something like this to skip every other event.
var process = 1;
force.on("tick", function() {
if(process) {
// do processing
}
process = 1 - process;
});
You could of course skip more events in a similar fashion. At some point, you might notice that the layout becomes "jumpier" because of the skipped events. You can mitigate this problem by moving the elements to their new positions using a transition instead of simply setting them.
Upvotes: 4