I am trying to transition the gradient stop attribute based on the rank values in the data. Right now, the transition is delayed by index values. I would like each curve with the highest rank to move faster than others each month and the subsequent curves to move slower based on their ranking. That way each curve should speed up or slow down based on their ranks each month.
Could this notebook example be applied to my notebook? Would implementing the keyframes with svg transition help in achieving the path transition race? Any pointers would be helpful, thank you! Bar Chart Race, Explained / D3 / Observable
Yes, I have wrangled my dataset to match the keyframes data structure. But somehow, the paths do not appear, I’m making an error in the data join part. Anyway, I’m still trying to figure it out.
Yes I did try the duration change but it’s not giving me the desired effect I’m looking for. Thank you for your response, I really appreciate you trying to help me with this.
For simplicity, let’s assume your values are a time series with constant time steps.
For each distance between two data points n and n+1 you determine the (relative) duration it should take for the animation to pass along that distance.
Since you want the speed to increase when y increases, you can simply take the absolute value as duration.
We can get the time steps via d3.cumsum(), but before doing so they need to be rescaled so that there are no negative values. While we’re at it, we rescale to [1, .1], where .1 is the minimum duration a step can have. In summary: domain = d3.extent(values), range = [1, .1].
Now we create a running total from the individual durations.
We also need to ensure that our running total stays in the [0…1] range, so we rescale it again to [0…1].
Lastly we need an interpolator that maps from [0…1] to our actual duration at that point in time. We can make our life easy by using d3.interpolateBasis(runningTotal).
Hm, interpolateBasis is actually not the right choice. Instead you’d need something like
return t => {
let i = d3.bisectRight(offsets, t);
const a = runningTotal[i-1];
const b = runningTotal[i];
if(b !== a) i += (t - a) / (b - a);
return (i-1) / maxIndex;
};