UPDATED QUESTION I've updated this to be a little more succinct..:
In this fiddle: http://jsfiddle.net/pX2Xb/4/ I have some raphael code that draws 3000 circles to a page. It then attempts to animate all circles at once (changes fill colour) over 10 seconds, which results in a clunky visual animation. Change the number of circles to 20 to see a much smoother animation for comparison.
My questions are (a) is it possible for me to make the update to the 3000 elements smoother and (b) if so, what does the code to do that look like?
Some notes:
older details, in case it helps
I'm creating a large map of US counties, of which there are over 3000; I'm using this Wikipedia svg file to get the relevant SVG paths to create the map, and am rendering the map using RaphaelJs.
Accordingly, I end up with over 3000 statements similar to the following:
var cc_02130 = rsr.path("M 140.66674,.... 320.11635"); // county path
cc_02130.attr({id: '02130',.. .."marker-start": 'none'}); // init attrs
I'm also creating a Paper.set()
object to hold all of these elements:
var myset = paper.set([cc_56039, cc_56040, cc_56041 ...])
Forgetting for a moment that the file actually generated here is quite large, I would very much appreciate suggestions of how I can apply changes to the volume of objects detailed above, that is both quick and reasonably ok CPU wise (possible a big ask).
I'm definitely open to changing the structure of my code/objects, as long as I can individually change attributes of specific counties. For example, I would like to be able to apply a different colour to each path content in a second or two (for all 3000+).
The challenge I'm facing is not how to apply the colour changes, animations, etc, but how to do this quickly and efficiently. Right now, my machine screams at me if I loop and apply changes over the 3000+ objects; as an alternative, I was using setTimeout
to break the changes out into smaller chunks (maybe 10 at a go, with a 40 ms delay). Over 3000 items, this becomes quite slow, and still uses a lot of CPU.
Thanks, oli
I don't know why, but D3.js is more efficient when animating a large number of elements at once. You can make them both work seamlessly by creating a Raphael function that receives a set and returns the html objects you want to animate:
Raphael.st.nodes = function() {
var elements = [];
this.forEach(function (i) {
elements.push(i.node);
});
return elements;
}
And then you let d3 take it from there
//circleholder is a Raphael set
elements = circleholder.nodes()
d3.selectAll(elements)
.transition()
.attr("fill", function(d,i){return colours[randomNum(14)]})
.duration(ANIMATION_DELAY)
Here is the jsfiddle: http://jsfiddle.net/mFecs/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With