Skip to content

Commit fb9b563

Browse files
committed
feat(ChartPath): implement chart background gradient
1 parent eb9c828 commit fb9b563

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

README.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,16 +115,21 @@ This component is used for showing the path itself.
115115
| `smoothingWhileTransitioningEnabled` | `number` | `false` | Although smoothing is not complex computing, it might impact performance in some low-end devices so while having a big set of data it might be worth disable smoothing while transitioning. |
116116
| `height` | `number` | obligatory | Height od the SVG canvas |
117117
| `width` | `number` | obligatory | Width od the SVG canvas |
118+
| `stroke` | `string` | `transparent` | Color of the path. |
118119
| `strokeWidth` | `number` | `1` | Width of the path. |
119120
| `selectedStrokeWidth` | `number` | `1` | Width of the path selected. |
120121
| `gestureEnabled` | `boolean` | `true` | Defines if interaction with the chart should be allowed or not |
121122
| `longPressGestureHandlerProps` | `object` | `{maxDist: 100000, minDurationMs: 0, shouldCancelWhenOutside: false}` | Under the hood we're using `LongPressGestureHandler` for handling interactions. It's recommended to not override its props. However, it might be useful while interacting with another GH. |
122123
| `selectedOpacity` | `number` | `0.7` | Target opacity of the path while touching the chart.
123-
| `hitSlop` | `number` | `0` | While scrubbing the chart touching edges of the screen you may want make points on the edges more accessible. With `hitSlop` it's possible to access points on edges doubling the speed of scrubbing beyond this margin. |
124-
| `hapticsEnabled` | `boolean` | `false` | On pressing in/out on the chart it might be expected to make haptic feedback. It will happen with `hapticsEnabled` set to `true`. |
125-
| `springConfig` | object | `{damping: 15, mass: 1, stiffness: 600}` | Object [defining the spring animation](https://docs.swmansion.com/react-native-reanimated/docs/next/animations). This spring is used for a dot's scale.
126-
| `timingFeedbackConfig` | object | `{duration: 80}` | Object [defining the timing animation](https://docs.swmansion.com/react-native-reanimated/docs/next/animations). `timingFeedbackConfig` is used for a path's opacity and width.
127-
| `timingAnimationConfig` | object | `{duration: 300}` | Object [defining the timing animation](https://docs.swmansion.com/react-native-reanimated/docs/next/animations). `timingAnimationConfig` is used for the transition between chart's data.
124+
| `hitSlop` | `number` | `0` | While scrubbing the chart touching edges of the screen you may want make points on the edges more accessible. With `hitSlop` it's possible to access points on edges doubling the speed of scrubbing beyond this margin. |
125+
| `hapticsEnabled` | `boolean` | `false` | On pressing in/out on the chart it might be expected to make haptic feedback. It will happen with `hapticsEnabled` set to `true`. |
126+
| `springConfig` | object | `{damping: 15, mass: 1, stiffness: 600}` | Object [defining the spring animation](https://docs.swmansion.com/react-native-reanimated/docs/next/animations). This spring is used for a dot's scale. |
127+
| `timingFeedbackConfig` | object | `{duration: 80}` | Object [defining the timing animation](https://docs.swmansion.com/react-native-reanimated/docs/next/animations). `timingFeedbackConfig` is used for a path's opacity and width. |
128+
| `timingAnimationConfig` | object | `{duration: 300}` | Object [defining the timing animation](https://docs.swmansion.com/react-native-reanimated/docs/next/animations). `timingAnimationConfig` is used for the transition between chart's data. |
129+
| `gradientEnabled` | `boolean` | `false` | Specify if background gradient should be enabled for the path under the chart, if not provided it defaults to `false` |
130+
| `backgroundGradientFrom` | `string` | `stroke` | Start color of the chart path background gradient, if a value is not provided for this prop, it defaults to the stroke color, and if no stroke color is specified, it defaults to `#000000` |
131+
| `backgroundGradientTo` | `string` | `#FFFFFF` | Stop color of the chart path background gradient, if a value is not provided for this prop, it defaults to `#FFFFFF` |
132+
| `stopOpacity` | `number` | `0` | Opacity of the path background gradient stop color. Defaults to `0` if not provided. |
128133
| ...rest | `object` | `{}` | Props applied to SVG [Path](https://github.com/react-native-community/react-native-svg#path). |
129134

130135

gifs/gradient.png

36.1 KB
Loading

src/charts/linear/ChartPath.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,13 @@ import Animated, {
1717
withSpring,
1818
withTiming,
1919
} from 'react-native-reanimated';
20-
import { Path, Svg } from 'react-native-svg';
20+
import {
21+
Path,
22+
Svg,
23+
Defs,
24+
Stop,
25+
LinearGradient
26+
} from 'react-native-svg';
2127

2228
import ChartContext, {
2329
useGenerateValues as generateValues,
@@ -673,6 +679,16 @@ function ChartPath({
673679
return props;
674680
}, []);
675681

682+
const gradientAnimatedProps = useAnimatedStyle(() => {
683+
const pathValue = path.value.replace('M', 'L');
684+
const gradientD = pathValue.length > 0 ? `M 0,${height} C 0,0 0,0 0,0 ${pathValue} L ${width},${height}` : '';
685+
const props = {
686+
d: gradientD,
687+
688+
};
689+
return props;
690+
}, []);
691+
676692
const animatedStyle = useAnimatedStyle(() => {
677693
return {
678694
opacity: pathOpacity.value * (1 - selectedOpacity) + selectedOpacity,
@@ -683,6 +699,7 @@ function ChartPath({
683699
<InternalContext.Provider
684700
value={{
685701
animatedProps,
702+
gradientAnimatedProps,
686703
animatedStyle,
687704
gestureEnabled,
688705
height,
@@ -705,6 +722,7 @@ export function SvgComponent() {
705722
height,
706723
width,
707724
animatedProps,
725+
gradientAnimatedProps,
708726
props,
709727
onLongPressGestureEvent,
710728
gestureEnabled,
@@ -725,6 +743,23 @@ export function SvgComponent() {
725743
viewBox={`0 0 ${width} ${height}`}
726744
width={width}
727745
>
746+
<AnimatedPath
747+
animatedProps={gradientAnimatedProps}
748+
fill="url(#prefix__paint0_linear)"
749+
/>
750+
{
751+
props.gradientEnabled &&
752+
<Defs>
753+
<LinearGradient id="prefix__paint0_linear" x1="100%" y1="0%" x2="100%" y2="120%">
754+
<Stop stopColor={props.backgroundGradientFrom ?? props.stroke} />
755+
<Stop
756+
offset="100%"
757+
stopColor={props.backgroundGradientTo ?? '#FFFFFF'}
758+
stopOpacity={props.stopOpacity ?? 0}
759+
/>
760+
</LinearGradient>
761+
</Defs>
762+
}
728763
<AnimatedPath
729764
animatedProps={animatedProps}
730765
{...props}

0 commit comments

Comments
 (0)