Animate by Scroll
This example uses new components introduced in 3.9 to animate the chart based on the scroll position. The animation controller is provided by a custom function that listens to the window scroll event and updates the animation time.
import {
Bar,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
AnimationControllerProvider,
AnimationController,
createHorizontalChart,
AnimationHandle,
OnAnimationStateUpdate,
CancelableTimeout,
} from 'recharts';
import { generateMockData, RechartsDevtools } from '@recharts/devtools';
const data = generateMockData(6, 10);
const Typed = createHorizontalChart<(typeof data)[0]>()({ Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend });
/**
* Custom animation controller which ignores the default timeoutController (which is based on requestAnimationFrame)
* and instead listens to window.scroll and uses the scroll value as time.
*
* This makes the chart animation listen to scroll position instead of a clock time.
*/
const scrollAnimationController: AnimationController = (
_timeoutController,
animationHandle: AnimationHandle,
listener: OnAnimationStateUpdate,
): CancelableTimeout => {
const handleScroll = () => {
const scrollTop = window.scrollY;
const docHeight = document.documentElement.scrollHeight - window.innerHeight;
const animationFinishesAt = docHeight / 2;
const scrollFraction = Math.min(Math.max(scrollTop / animationFinishesAt, 0), 1);
const animationDuration = animationHandle.getAnimationDuration();
const currentTime = scrollFraction * animationDuration;
animationHandle.tick(currentTime);
listener(animationHandle.getInterpolated());
};
animationHandle.tick(0);
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
};
const ScrollAnimateBarChart = () => {
return (
<AnimationControllerProvider value={scrollAnimationController}>
<Typed.BarChart
style={{ width: '100%', maxWidth: '700px', minHeight: '50vh', marginTop: '50vh', aspectRatio: 1.618 }}
responsive
data={data}
margin={{
top: 5,
right: 0,
left: 0,
bottom: 5,
}}
>
<CartesianGrid />
<Typed.XAxis dataKey="label" />
<Typed.YAxis width="auto" />
<Typed.Tooltip />
<Legend />
<Typed.Bar dataKey="y" activeBar radius={[10, 10, 0, 0]} />
<Typed.Bar dataKey="x" activeBar radius={[10, 10, 0, 0]} />
<RechartsDevtools />
</Typed.BarChart>
</AnimationControllerProvider>
);
};
export default ScrollAnimateBarChart;