Reputation: 2115
I've got a line graph with 159 lines. When the graph first loads, I want them all to graph as a straight line, y=5. That works. Then I want them to beautifully transition to their bumpy selves.
Well, my dang transition is jerky, not beautiful. I think I need a remove() somewhere in here.
Graph is here. Ignore the drop-downs; they're not part of the original load. http://bl.ocks.org/greencracker/raw/f37dc463afa15bf17d91/
I think the key part may be in here:
var line = d3.svg.line()
.interpolate("basis")
.x(function (d) {return x(d.date); })
.y(function (d) {return y(d.rate) ; });
var flat_line = d3.svg.line()
.interpolate("basis")
.x(function (d, i) {return x(d.date); })
.y(function (d) {return y(5) ; });
Then further down:
function lineAnimate(selection) { // selection must be paths
selection.transition().duration(1150).ease("linear")
.attr("d", function (d) {return line(d.values);})
.style("opacity", 1)
.style("stroke", "red")
}
var counties = svg.selectAll(".county")
.data(data, function (d) {return d.key;})
.enter().append("g")
.attr("class", function (d) {return d.key + " " + d.wia + " county";})
.text(function (d) {return d.key});
counties.append("path")
.attr("class", function (d) {return d.key + " " + d.wia + " county" + " line";})
.attr("id", function (d) {return "a" + d.wia;})
.attr("d", function (d) {return flat_line(d.values); }) // flat line y=5
.attr("stroke", "gray")
.attr("stroke-width", "1px")
.style("opacity", 0.0)
counties.selectAll("path.line")
.call(lineAnimate)
Upvotes: 0
Views: 388
Reputation: 25157
It's just a lot of work to animate 159 lines simultaneously, and there's probably not much to do about that.
However, the SVG renderer is further bogged down by having to determine the resulting fills of all these overlapping semi-transparent lines. I suspect you can get a significant boost if you do away with the opacity change.
Finally, you might be able to improve the "line morph" animation by staggering the animations; i.e. the first line would begin (and finish) its animation a bit before the 2nd line, then the 3rd, etc. This way, only a subset of the lines is animating at any given point.
You'd do this by adding something like .delay( function(d, i) { return i * 100; })
after the .transition()
call. Might not be the effect you're going for though. Just a thought...
Upvotes: 1