Open nandorojo opened 2 years ago
I found the issue: it seems that it may be related to reanimated's animatedProps
or something not rendering synchronously? In any case, using Path
instead of AnimatedPath
inside of LineChartPath
solved it.
I opted to render Path
directly when transitions are disabled.
import * as React from 'react';
import Animated, {
useAnimatedProps,
useAnimatedReaction,
useSharedValue,
withTiming,
} from 'react-native-reanimated';
import { Path, PathProps } from 'react-native-svg';
import { LineChartDimensionsContext } from './Chart';
import interpolatePath from './interpolatePath';
import { usePrevious } from '../../utils';
const AnimatedPath = Animated.createAnimatedComponent(Path);
export type LineChartPathProps = Animated.AnimateProps<PathProps> & {
color?: string;
width?: number;
isInactive?: boolean;
/**
* Default: `true`.
*
* If `false`, changes in the chart's path will not animate.
*
* While this use case is rare, it may be useful on web, where animations might not work as well.
*
* **Example**
*
* ```tsx
* <LineChart.Path
* pathProps={{ isTransitionEnabled: Platform.OS !== 'web' }}
* />
* ```
*/
isTransitionEnabled?: boolean;
};
export function LineChartPath({
color = 'black',
width: strokeWidth = 3,
isInactive,
isTransitionEnabled = true,
...props
}: LineChartPathProps) {
const { path } = React.useContext(LineChartDimensionsContext);
////////////////////////////////////////////////
const transition = useSharedValue(0);
const previousPath = usePrevious(path);
useAnimatedReaction(
() => {
return path;
},
(_, previous) => {
if (previous) {
transition.value = 0;
transition.value = withTiming(1);
}
},
[path]
);
const animatedProps = useAnimatedProps(() => {
let d = path || '';
if (previousPath && isTransitionEnabled) {
const pathInterpolator = interpolatePath(previousPath, path, null);
d = pathInterpolator(transition.value);
}
return {
d,
};
});
const pathProps: React.ComponentProps<typeof Path> = {
fill: 'transparent',
stroke: color,
strokeWidth,
strokeOpacity: isInactive ? 0.2 : 1,
}
if (!isTransitionEnabled) {
return <Path d={path || ''} {...pathProps} />
}
////////////////////////////////////////////////
return (
<AnimatedPath
animatedProps={animatedProps}
{...pathProps}
{...props}
/>
);
}
Would you accept a PR for this?
Hi @nandorojo,
Thanks for raising this. I would be happy to look at a PR if you have one.
I'm having a slightly weird issue. The LineChart path is slow to update. I have transitions disabled. It may require looking closely. However, notice that when I change time ranges, the color changes a split second before the chart path does.
Video
https://www.loom.com/share/e5713040946c4145ba64433167b1dd73
Explanation
The color changes for a second before the actual path changes. It's bizarre.
To see it clearly: when I set the time range to
1D
, notice that the horizontal line shows half a second before the chart path changes. I can't seem to think of what would cause this. My only guess is if internally there is some sort of state getting set inside of an effect? Or is there some sort of interpolation happening when it shouldn't?I haven't tried to repro yet, but I will when I get the chance.
It's not like terrible but it makes the app seem laggy. There are no network requests being sent when you toggle the time range; it's all pre-fetched. It only has one state update.
Anything come to mind @jxom?
Thanks again!