react-smooth
react-smooth copied to clipboard
Causes chart to prematurely stop rendering
There are some indications from users that Animations from react-smooth are causing the graph to render partially / in an incomplete state. Users have been using isAnimationActive={false}
to disable animations to workaround the bug. See recharts
issues:
https://github.com/recharts/recharts/issues/1426 https://github.com/recharts/recharts/issues/1821
The issue seems to be related to the frequency in which your parent component needs to rerender, or possibly how often your data array reference changes. The workaround seems to be to do two things:
- Force your chart to rerender when your parent component re-renders
- Ensure your parent component does not rerender during the animation if possible. For me, I found that a parent component issue was causing my chart to rerender too often. That fix is not shown here.
I set a unique key on the Chart or ResponsiveContainer
that forces the chart to rerender when the parent component rerenders. This can lead to issues with your chart reanimating on each rerender, which may not be your desired effect. Here is how I worked that out. Note that I'm turning off animations after a timeout to prevent duplicate animations after the key change. You would think that I could simply turn the animation off at onAnimationEnd
but that callback seems to be called before the animation actually ends for some reason. It's also possible that your component will never actually finish the animation if this bug does happen to occur during the animation. I had better luck with the following approach:
const RingChart = ({data, colors, angle = 140}) => {
let [animate, setAnimate] = useState(true)
const onAnimationStart = useCallback(() => {
setTimeout(() => {
setAnimate(false)
}, 2000)
}, [])
return (<div>
<div ref={ref} className={"absolute w-grid-7 h-grid-1 l-grid-7 t-grid-7"}/>
<ResponsiveContainer key={uniqid()}>
<PieChart>
<Pie
isAnimationActive={animate}
data={data}
startAngle={angle}
endAngle={angle + 360}
cx={'50%'}
cy={'50%'}
outerRadius={'70%'}
innerRadius={'47%'}
fill="#8884d8"
dataKey="value"
paddingAngle={0}
labelLine={<LabelLine/>}
label={<Label/>}
onAnimationStart={onAnimationStart}
>
{data.map((entry, index) => (
<Cell key={`cell-${index}`} fill={colors[index % colors.length]} stroke="none"/>
))}
</Pie>
</PieChart>
</ResponsiveContainer>
</div>
)
}
any updates ?
It's worth noting that when the Animate
component unmounts, it does not call onAnimationEnd
. This makes it impossible for recharts
to clean up any outstanding animations when Animate
unmounts.
Perhaps there could be an onAnimationStopped
prop to address cases where the AnimateManager
is stopped abruptly.
We would love a contribution from your side @pl12133 , calling the onAnimationEnd on unmount
Merged https://github.com/recharts/react-smooth/pull/80 which calls onAnimationEnd
on unmount - this should solve part of this