Reputation: 373
I have set up a D3 circle animation with a transition. I'm using the min date as the initial data point and the max date as the final data point for the transition. My questions is:
I'm using a rather large dataset, I'm afraid that since I'm only telling the transition to go from min to max, it will miss all the other points in between, for example what if circle A has a crazy jump in between? When I tested it out, it seemed as if it had just skipped the jump.
Is there a better way to set the transition to account for all the points in between?
Upvotes: 1
Views: 798
Reputation: 10824
If you tell the object to translate from min to max it will only respect those two values and as you said it will skip any funny jumps in between.
I guess you currently draw the chart once by pushing in all the data. Instead you could push the data to the chart step by step:
var data = [{id: o1, v: []}, {id: o2, v: []}]; // values for 2 objects
function getTransform(d) {
return "translate(" + d.v[d.v.length-1] + ")";
}
function update() {
var elems = d3.selectAll(...).data(data, function(d) {return d.id;})
elems.enter()
.append(...) //append DOM/SVG objects and
.attr(...) //initalize their start values and
.attr("transform", getTransform ) //their start animation values
// animate the existing elements to move to their new values
elems.transition().attr("transform", getTransform )
}
function play(){
// pushing in "crazy" values
data[0].v.push( Math.random()*10 );
data[1].v.push( Math.random()*10 );
update();
}
setTimeout(play, 500)
setTimeout(play, 1000)
setTimeout(play, 1500)
The basic idea is to not throw all data at d3 at once, but add the data in the order and timeliness that you want it to be animated.
In addition, or alternatively you could set a time index and use it in the getTransform
function to animate to any state you want. If you do this step by step, you make the animation use your "crazy" values.
var time = 0;
var maxTime = 2;
function getTransform(d) {
return "translate(" + d.v[time] + ")";
}
function next(){
update();
if(time++ < maxTime) setTimeout(next, 500)
}
play(); play(); play(); // add some data ;)
next() // start index based playback from `time` to `maxTime`
You may need to match the timeout value 500
with your desired animation duration(..)
speed to make the animation hit your crazy spikes. Otherwise d3 might smooth the animation path (if you update faster than you animate).
Upvotes: 2