From 06f2fd1bd4a2037174020dce6074b115b2771c17 Mon Sep 17 00:00:00 2001
From: Thomas Coldwell <31568400+thomas-coldwell@users.noreply.github.com>
Date: Tue, 25 Oct 2022 14:39:54 +0100
Subject: [PATCH 1/6] fix: Prettier semis
---
.../GraphExample.xcodeproj/project.pbxproj | 4 +-
example/src/screens/GraphPage.tsx | 89 ++---
src/AnimatedLineGraph.tsx | 303 +++++++++---------
src/LineGraphProps.ts | 70 ++--
4 files changed, 246 insertions(+), 220 deletions(-)
diff --git a/example/ios/GraphExample.xcodeproj/project.pbxproj b/example/ios/GraphExample.xcodeproj/project.pbxproj
index 962d37f..3004a62 100644
--- a/example/ios/GraphExample.xcodeproj/project.pbxproj
+++ b/example/ios/GraphExample.xcodeproj/project.pbxproj
@@ -265,7 +265,7 @@
TestTargetID = 13B07F861A680F5B00A75B9A;
};
13B07F861A680F5B00A75B9A = {
- DevelopmentTeam = CJW62Q77E7;
+ DevelopmentTeam = TFP6882UUN;
LastSwiftMigration = 1120;
};
2D02E47A1E0B4A5D006451C7 = {
@@ -542,7 +542,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = 1;
- DEVELOPMENT_TEAM = CJW62Q77E7;
+ DEVELOPMENT_TEAM = TFP6882UUN;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = GraphExample/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
diff --git a/example/src/screens/GraphPage.tsx b/example/src/screens/GraphPage.tsx
index c2fc13b..aa0b496 100644
--- a/example/src/screens/GraphPage.tsx
+++ b/example/src/screens/GraphPage.tsx
@@ -1,42 +1,44 @@
-import React, { useCallback, useMemo, useState } from 'react'
-import { View, StyleSheet, Text, Button } from 'react-native'
-import { LineGraph } from 'react-native-graph'
-import StaticSafeAreaInsets from 'react-native-static-safe-area-insets'
-import type { GraphRange } from '../../../src/LineGraphProps'
-import { SelectionDot } from '../components/CustomSelectionDot'
-import { Toggle } from '../components/Toggle'
+import React, { useCallback, useMemo, useState } from 'react';
+import { View, StyleSheet, Text, Button } from 'react-native';
+import { LineGraph } from 'react-native-graph';
+import StaticSafeAreaInsets from 'react-native-static-safe-area-insets';
+import type { GraphRange } from '../../../src/LineGraphProps';
+import { SelectionDot } from '../components/CustomSelectionDot';
+import { Toggle } from '../components/Toggle';
import {
generateRandomGraphData,
generateSinusGraphData,
-} from '../data/GraphData'
-import { useColors } from '../hooks/useColors'
-import { hapticFeedback } from '../utils/HapticFeedback'
+} from '../data/GraphData';
+import { useColors } from '../hooks/useColors';
+import { hapticFeedback } from '../utils/HapticFeedback';
-const POINT_COUNT = 70
-const POINTS = generateRandomGraphData(POINT_COUNT)
-const COLOR = '#6a7ee7'
-const GRADIENT_FILL_COLORS = ['#7476df5D', '#7476df4D', '#7476df00']
-const SMALL_POINTS = generateSinusGraphData(9)
+const POINT_COUNT = 70;
+const POINTS = generateRandomGraphData(POINT_COUNT);
+const COLOR = '#6a7ee7';
+const GRADIENT_FILL_COLORS = ['#7476df5D', '#7476df4D', '#7476df00'];
+const GRADIENT_LINE_COLORS = ['#FF0000', '#00FF00', '#0000FF'];
+const SMALL_POINTS = generateSinusGraphData(9);
export function GraphPage() {
- const colors = useColors()
+ const colors = useColors();
- const [isAnimated, setIsAnimated] = useState(true)
- const [enablePanGesture, setEnablePanGesture] = useState(true)
- const [enableFadeInEffect, setEnableFadeInEffect] = useState(false)
+ const [isAnimated, setIsAnimated] = useState(true);
+ const [enablePanGesture, setEnablePanGesture] = useState(true);
+ const [enableFadeInEffect, setEnableFadeInEffect] = useState(false);
const [enableCustomSelectionDot, setEnableCustomSelectionDot] =
- useState(false)
- const [enableGradient, setEnableGradient] = useState(false)
- const [enableRange, setEnableRange] = useState(false)
- const [enableIndicator, setEnableIndicator] = useState(false)
- const [indicatorPulsating, setIndicatorPulsating] = useState(false)
+ useState(false);
+ const [enableFillGradient, setEnableFillGradient] = useState(false);
+ const [enableLineGradient, setEnableLineGradient] = useState(false);
+ const [enableRange, setEnableRange] = useState(false);
+ const [enableIndicator, setEnableIndicator] = useState(false);
+ const [indicatorPulsating, setIndicatorPulsating] = useState(false);
- const [points, setPoints] = useState(POINTS)
+ const [points, setPoints] = useState(POINTS);
const refreshData = useCallback(() => {
- setPoints(generateRandomGraphData(POINT_COUNT))
- hapticFeedback('impactLight')
- }, [])
+ setPoints(generateRandomGraphData(POINT_COUNT));
+ hapticFeedback('impactLight');
+ }, []);
const highestDate = useMemo(
() =>
@@ -44,10 +46,10 @@ export function GraphPage() {
? points[points.length - 1]!.date
: undefined,
[points]
- )
+ );
const range: GraphRange | undefined = useMemo(() => {
// if range is disabled, default to infinite range (undefined)
- if (!enableRange) return undefined
+ if (!enableRange) return undefined;
if (points.length !== 0 && highestDate != null) {
return {
@@ -59,16 +61,16 @@ export function GraphPage() {
min: -200,
max: 200,
},
- }
+ };
} else {
return {
y: {
min: -200,
max: 200,
},
- }
+ };
}
- }, [enableRange, highestDate, points])
+ }, [enableRange, highestDate, points]);
return (
@@ -89,9 +91,11 @@ export function GraphPage() {
hapticFeedback('impactLight')}
@@ -126,9 +130,14 @@ export function GraphPage() {
setIsEnabled={setEnableCustomSelectionDot}
/>
+
- )
+ );
}
const styles = StyleSheet.create({
@@ -186,4 +195,4 @@ const styles = StyleSheet.create({
justifyContent: 'center',
paddingHorizontal: 15,
},
-})
+});
diff --git a/src/AnimatedLineGraph.tsx b/src/AnimatedLineGraph.tsx
index 2b3a882..ac8893b 100644
--- a/src/AnimatedLineGraph.tsx
+++ b/src/AnimatedLineGraph.tsx
@@ -1,5 +1,11 @@
-import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
-import { View, StyleSheet, LayoutChangeEvent } from 'react-native'
+import React, {
+ useCallback,
+ useEffect,
+ useMemo,
+ useRef,
+ useState,
+} from 'react';
+import { View, StyleSheet, LayoutChangeEvent } from 'react-native';
import {
Canvas,
runSpring,
@@ -16,16 +22,16 @@ import {
mix,
Circle,
Shadow,
-} from '@shopify/react-native-skia'
-import type { AnimatedLineGraphProps } from './LineGraphProps'
-import { SelectionDot as DefaultSelectionDot } from './SelectionDot'
+} from '@shopify/react-native-skia';
+import type { AnimatedLineGraphProps } from './LineGraphProps';
+import { SelectionDot as DefaultSelectionDot } from './SelectionDot';
import {
createGraphPath,
createGraphPathWithGradient,
getGraphPathRange,
GraphPathRange,
pixelFactorX,
-} from './CreateGraphPath'
+} from './CreateGraphPath';
import Reanimated, {
runOnJS,
useAnimatedReaction,
@@ -36,22 +42,22 @@ import Reanimated, {
withSequence,
withTiming,
withDelay,
-} from 'react-native-reanimated'
-import { getSixDigitHex } from './utils/getSixDigitHex'
-import { GestureDetector } from 'react-native-gesture-handler'
-import { usePanGesture } from './hooks/usePanGesture'
-import { getYForX } from './GetYForX'
-import { hexToRgba } from './utils/hexToRgba'
-
-const INDICATOR_RADIUS = 7
-const INDICATOR_BORDER_MULTIPLIER = 1.3
+} from 'react-native-reanimated';
+import { getSixDigitHex } from './utils/getSixDigitHex';
+import { GestureDetector } from 'react-native-gesture-handler';
+import { usePanGesture } from './hooks/usePanGesture';
+import { getYForX } from './GetYForX';
+import { hexToRgba } from './utils/hexToRgba';
+
+const INDICATOR_RADIUS = 7;
+const INDICATOR_BORDER_MULTIPLIER = 1.3;
const INDICATOR_PULSE_BLUR_RADIUS_SMALL =
- INDICATOR_RADIUS * INDICATOR_BORDER_MULTIPLIER
+ INDICATOR_RADIUS * INDICATOR_BORDER_MULTIPLIER;
const INDICATOR_PULSE_BLUR_RADIUS_BIG =
- INDICATOR_RADIUS * INDICATOR_BORDER_MULTIPLIER + 20
+ INDICATOR_RADIUS * INDICATOR_BORDER_MULTIPLIER + 20;
// weird rea type bug
-const ReanimatedView = Reanimated.View as any
+const ReanimatedView = Reanimated.View as any;
export function AnimatedLineGraph({
points,
@@ -75,27 +81,27 @@ export function AnimatedLineGraph({
BottomAxisLabel,
...props
}: AnimatedLineGraphProps): React.ReactElement {
- const [width, setWidth] = useState(0)
- const [height, setHeight] = useState(0)
- const interpolateProgress = useValue(0)
-
- const { gesture, isActive, x } = usePanGesture({ holdDuration: 300 })
- const circleX = useValue(0)
- const circleY = useValue(0)
- const pathEnd = useValue(0)
- const indicatorRadius = useValue(enableIndicator ? INDICATOR_RADIUS : 0)
+ const [width, setWidth] = useState(0);
+ const [height, setHeight] = useState(0);
+ const interpolateProgress = useValue(0);
+
+ const { gesture, isActive, x } = usePanGesture({ holdDuration: 300 });
+ const circleX = useValue(0);
+ const circleY = useValue(0);
+ const pathEnd = useValue(0);
+ const indicatorRadius = useValue(enableIndicator ? INDICATOR_RADIUS : 0);
const indicatorBorderRadius = useComputedValue(
() => indicatorRadius.current * INDICATOR_BORDER_MULTIPLIER,
[indicatorRadius]
- )
+ );
const pulseTrigger = useDerivedValue(() => {
- 'worklet'
- return isActive.value ? 1 : 0
- }, [])
- const indicatorPulseAnimation = useSharedValue(0)
- const indicatorPulseRadius = useValue(INDICATOR_PULSE_BLUR_RADIUS_SMALL)
- const indicatorPulseOpacity = useValue(1)
+ 'worklet';
+ return isActive.value ? 1 : 0;
+ }, []);
+ const indicatorPulseAnimation = useSharedValue(0);
+ const indicatorPulseRadius = useValue(INDICATOR_PULSE_BLUR_RADIUS_SMALL);
+ const indicatorPulseOpacity = useValue(1);
const positions = useComputedValue(
() => [
@@ -106,39 +112,39 @@ export function AnimatedLineGraph({
1,
],
[pathEnd]
- )
+ );
const onLayout = useCallback(
({ nativeEvent: { layout } }: LayoutChangeEvent) => {
- setWidth(Math.round(layout.width))
- setHeight(Math.round(layout.height))
+ setWidth(Math.round(layout.width));
+ setHeight(Math.round(layout.height));
},
[]
- )
+ );
const straightLine = useMemo(() => {
- const path = Skia.Path.Make()
- path.moveTo(0, height / 2)
+ const path = Skia.Path.Make();
+ path.moveTo(0, height / 2);
for (let i = 0; i < width - 1; i += 2) {
- const x = i
- const y = height / 2
- path.cubicTo(x, y, x, y, x, y)
+ const x = i;
+ const y = height / 2;
+ path.cubicTo(x, y, x, y, x, y);
}
- return path
- }, [height, width])
+ return path;
+ }, [height, width]);
- const paths = useValue<{ from?: SkPath; to?: SkPath }>({})
- const gradientPaths = useValue<{ from?: SkPath; to?: SkPath }>({})
- const commands = useRef([])
- const [commandsChanged, setCommandsChanged] = useState(0)
+ const paths = useValue<{ from?: SkPath; to?: SkPath }>({});
+ const gradientPaths = useValue<{ from?: SkPath; to?: SkPath }>({});
+ const commands = useRef([]);
+ const [commandsChanged, setCommandsChanged] = useState(0);
const pathRange: GraphPathRange = useMemo(
() => getGraphPathRange(points, range),
[points, range]
- )
+ );
const drawingWidth = useMemo(() => {
- const lastPoint = points[points.length - 1]!
+ const lastPoint = points[points.length - 1]!;
return Math.max(
Math.floor(
@@ -146,8 +152,8 @@ export function AnimatedLineGraph({
pixelFactorX(lastPoint.date, pathRange.x.min, pathRange.x.max)
),
0
- )
- }, [horizontalPadding, pathRange.x.max, pathRange.x.min, points, width])
+ );
+ }, [horizontalPadding, pathRange.x.max, pathRange.x.min, points, width]);
const indicatorX = useMemo(
() =>
@@ -155,31 +161,31 @@ export function AnimatedLineGraph({
? Math.floor(drawingWidth) + horizontalPadding
: undefined,
[commandsChanged, drawingWidth, horizontalPadding]
- )
+ );
const indicatorY = useMemo(
() =>
commandsChanged >= 0 && indicatorX != null
? getYForX(commands.current, indicatorX)
: undefined,
[commandsChanged, indicatorX]
- )
+ );
- const indicatorPulseColor = useMemo(() => hexToRgba(color, 0.4), [color])
+ const indicatorPulseColor = useMemo(() => hexToRgba(color, 0.4), [color]);
- const shouldFillGradient = gradientFillColors != null
+ const shouldFillGradient = gradientFillColors != null;
useEffect(() => {
if (height < 1 || width < 1) {
// view is not yet measured!
- return
+ return;
}
if (points.length < 1) {
// points are still empty!
- return
+ return;
}
- let path
- let gradientPath
+ let path;
+ let gradientPath;
const createGraphPathProps = {
points: points,
@@ -188,59 +194,59 @@ export function AnimatedLineGraph({
verticalPadding: verticalPadding,
canvasHeight: height,
canvasWidth: width,
- }
+ };
if (shouldFillGradient) {
const { path: pathNew, gradientPath: gradientPathNew } =
- createGraphPathWithGradient(createGraphPathProps)
+ createGraphPathWithGradient(createGraphPathProps);
- path = pathNew
- gradientPath = gradientPathNew
+ path = pathNew;
+ gradientPath = gradientPathNew;
} else {
- path = createGraphPath(createGraphPathProps)
+ path = createGraphPath(createGraphPathProps);
}
- commands.current = path.toCmds()
+ commands.current = path.toCmds();
if (gradientPath != null) {
- const previous = gradientPaths.current
- let from: SkPath = previous.to ?? straightLine
+ const previous = gradientPaths.current;
+ let from: SkPath = previous.to ?? straightLine;
if (previous.from != null && interpolateProgress.current < 1)
from =
- from.interpolate(previous.from, interpolateProgress.current) ?? from
+ from.interpolate(previous.from, interpolateProgress.current) ?? from;
if (gradientPath.isInterpolatable(from)) {
gradientPaths.current = {
from: from,
to: gradientPath,
- }
+ };
} else {
gradientPaths.current = {
from: gradientPath,
to: gradientPath,
- }
+ };
}
}
- const previous = paths.current
- let from: SkPath = previous.to ?? straightLine
+ const previous = paths.current;
+ let from: SkPath = previous.to ?? straightLine;
if (previous.from != null && interpolateProgress.current < 1)
from =
- from.interpolate(previous.from, interpolateProgress.current) ?? from
+ from.interpolate(previous.from, interpolateProgress.current) ?? from;
if (path.isInterpolatable(from)) {
paths.current = {
from: from,
to: path,
- }
+ };
} else {
paths.current = {
from: path,
to: path,
- }
+ };
}
- setCommandsChanged(commandsChanged + 1)
+ setCommandsChanged(commandsChanged + 1);
runSpring(
interpolateProgress,
@@ -251,7 +257,7 @@ export function AnimatedLineGraph({
damping: 400,
velocity: 0,
}
- )
+ );
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
height,
@@ -266,54 +272,58 @@ export function AnimatedLineGraph({
straightLine,
verticalPadding,
width,
- ])
+ ]);
const gradientColors = useMemo(() => {
- if (enableFadeInMask) {
- return [
- `${getSixDigitHex(color)}00`,
- `${getSixDigitHex(color)}ff`,
- `${getSixDigitHex(color)}ff`,
- `${getSixDigitHex(color)}33`,
- `${getSixDigitHex(color)}33`,
- ]
+ if (typeof color === 'string') {
+ if (enableFadeInMask) {
+ return [
+ `${getSixDigitHex(color)}00`,
+ `${getSixDigitHex(color)}ff`,
+ `${getSixDigitHex(color)}ff`,
+ `${getSixDigitHex(color)}33`,
+ `${getSixDigitHex(color)}33`,
+ ];
+ } else {
+ return [
+ color,
+ color,
+ color,
+ `${getSixDigitHex(color)}33`,
+ `${getSixDigitHex(color)}33`,
+ ];
+ }
} else {
- return [
- color,
- color,
- color,
- `${getSixDigitHex(color)}33`,
- `${getSixDigitHex(color)}33`,
- ]
+ return color;
}
- }, [color, enableFadeInMask])
+ }, [color, enableFadeInMask]);
const path = useComputedValue(
() => {
- const from = paths.current.from ?? straightLine
- const to = paths.current.to ?? straightLine
+ const from = paths.current.from ?? straightLine;
+ const to = paths.current.to ?? straightLine;
- return to.interpolate(from, interpolateProgress.current)
+ return to.interpolate(from, interpolateProgress.current);
},
// RN Skia deals with deps differently. They are actually the required SkiaValues that the derived value listens to, not react values.
[interpolateProgress]
- )
+ );
const gradientPath = useComputedValue(
() => {
- const from = gradientPaths.current.from ?? straightLine
- const to = gradientPaths.current.to ?? straightLine
+ const from = gradientPaths.current.from ?? straightLine;
+ const to = gradientPaths.current.to ?? straightLine;
- return to.interpolate(from, interpolateProgress.current)
+ return to.interpolate(from, interpolateProgress.current);
},
// RN Skia deals with deps differently. They are actually the required SkiaValues that the derived value listens to, not react values.
[interpolateProgress]
- )
+ );
const stopPulsating = useCallback(() => {
- cancelAnimation(indicatorPulseAnimation)
- indicatorPulseAnimation.value = 0
- }, [indicatorPulseAnimation])
+ cancelAnimation(indicatorPulseAnimation);
+ indicatorPulseAnimation.value = 0;
+ }, [indicatorPulseAnimation]);
const startPulsating = useCallback(() => {
indicatorPulseAnimation.value = withRepeat(
@@ -328,31 +338,34 @@ export function AnimatedLineGraph({
)
),
-1
- )
- }, [indicatorPulseAnimation])
+ );
+ }, [indicatorPulseAnimation]);
const setFingerX = useCallback(
(fingerX: number) => {
- const lowerBound = horizontalPadding
- const upperBound = drawingWidth + horizontalPadding
+ const lowerBound = horizontalPadding;
+ const upperBound = drawingWidth + horizontalPadding;
- const fingerXInRange = Math.min(Math.max(fingerX, lowerBound), upperBound)
- const y = getYForX(commands.current, fingerXInRange)
+ const fingerXInRange = Math.min(
+ Math.max(fingerX, lowerBound),
+ upperBound
+ );
+ const y = getYForX(commands.current, fingerXInRange);
if (y != null) {
- circleY.current = y
- circleX.current = fingerXInRange
+ circleY.current = y;
+ circleX.current = fingerXInRange;
}
if (fingerX > lowerBound && fingerX < upperBound && isActive.value)
- pathEnd.current = fingerX / width
+ pathEnd.current = fingerX / width;
- const actualFingerX = fingerX - horizontalPadding
+ const actualFingerX = fingerX - horizontalPadding;
- const index = Math.round((actualFingerX / upperBound) * points.length)
- const pointIndex = Math.min(Math.max(index, 0), points.length - 1)
- const dataPoint = points[pointIndex]
- if (dataPoint != null) onPointSelected?.(dataPoint)
+ const index = Math.round((actualFingerX / upperBound) * points.length);
+ const pointIndex = Math.min(Math.max(index, 0), points.length - 1);
+ const dataPoint = points[pointIndex];
+ if (dataPoint != null) onPointSelected?.(dataPoint);
},
[
circleX,
@@ -365,7 +378,7 @@ export function AnimatedLineGraph({
points,
width,
]
- )
+ );
const setIsActive = useCallback(
(active: boolean) => {
@@ -374,15 +387,15 @@ export function AnimatedLineGraph({
stiffness: 1000,
damping: 50,
velocity: 0,
- })
+ });
if (active) {
- onGestureStart?.()
- stopPulsating()
+ onGestureStart?.();
+ stopPulsating();
} else {
- onGestureEnd?.()
- pathEnd.current = 1
- startPulsating()
+ onGestureEnd?.();
+ pathEnd.current = 1;
+ startPulsating();
}
},
[
@@ -393,37 +406,37 @@ export function AnimatedLineGraph({
startPulsating,
stopPulsating,
]
- )
+ );
useAnimatedReaction(
() => x.value,
(fingerX) => {
if (isActive.value || fingerX) {
- runOnJS(setFingerX)(fingerX)
+ runOnJS(setFingerX)(fingerX);
}
},
[isActive, setFingerX, width, x]
- )
+ );
useAnimatedReaction(
() => isActive.value,
(active) => {
- runOnJS(setIsActive)(active)
+ runOnJS(setIsActive)(active);
},
[isActive, setIsActive]
- )
+ );
useEffect(() => {
if (points.length !== 0 && commands.current.length !== 0)
- pathEnd.current = 1
- }, [commands, pathEnd, points.length])
+ pathEnd.current = 1;
+ }, [commands, pathEnd, points.length]);
useEffect(() => {
if (indicatorPulsating) {
- startPulsating()
+ startPulsating();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [indicatorPulsating])
+ }, [indicatorPulsating]);
useSharedValueEffect(
() => {
@@ -432,15 +445,19 @@ export function AnimatedLineGraph({
indicatorPulseAnimation.value,
INDICATOR_PULSE_BLUR_RADIUS_SMALL,
INDICATOR_PULSE_BLUR_RADIUS_BIG
- )
- indicatorPulseOpacity.current = mix(indicatorPulseAnimation.value, 1, 0)
+ );
+ indicatorPulseOpacity.current = mix(
+ indicatorPulseAnimation.value,
+ 1,
+ 0
+ );
} else {
- indicatorPulseRadius.current = 0
+ indicatorPulseRadius.current = 0;
}
},
indicatorPulseAnimation,
pulseTrigger
- )
+ );
return (
@@ -538,7 +555,7 @@ export function AnimatedLineGraph({
- )
+ );
}
const styles = StyleSheet.create({
@@ -554,4 +571,4 @@ const styles = StyleSheet.create({
axisRow: {
height: 17,
},
-})
+});
diff --git a/src/LineGraphProps.ts b/src/LineGraphProps.ts
index 172eef0..5afc6aa 100644
--- a/src/LineGraphProps.ts
+++ b/src/LineGraphProps.ts
@@ -1,112 +1,112 @@
-import type React from 'react'
-import type { ViewProps } from 'react-native'
-import type { GraphPathRange } from './CreateGraphPath'
-import type { SharedValue } from 'react-native-reanimated'
-import type { Color, SkiaMutableValue } from '@shopify/react-native-skia'
+import type React from 'react';
+import type { ViewProps } from 'react-native';
+import type { GraphPathRange } from './CreateGraphPath';
+import type { SharedValue } from 'react-native-reanimated';
+import type { Color, SkiaMutableValue } from '@shopify/react-native-skia';
export interface GraphPoint {
- value: number
- date: Date
+ value: number;
+ date: Date;
}
-export type GraphRange = Partial
+export type GraphRange = Partial;
export interface SelectionDotProps {
- isActive: SharedValue
- color: BaseLineGraphProps['color']
- lineThickness: BaseLineGraphProps['lineThickness']
- circleX: SkiaMutableValue
- circleY: SkiaMutableValue
+ isActive: SharedValue;
+ color: BaseLineGraphProps['color'];
+ lineThickness: BaseLineGraphProps['lineThickness'];
+ circleX: SkiaMutableValue;
+ circleY: SkiaMutableValue;
}
interface BaseLineGraphProps extends ViewProps {
/**
* All points to be marked in the graph. Coordinate system will adjust to scale automatically.
*/
- points: GraphPoint[]
+ points: GraphPoint[];
/**
* Range of the graph's x and y-axis. The range must be greater
* than the range given by the points.
*/
- range?: GraphRange
+ range?: GraphRange;
/**
- * Color of the graph line (path)
+ * Color of the graph line (path) either as a single solid color or an array of colors for a line gradient
*/
- color: string
+ color: string | Color[];
/**
* (Optional) Colors for the fill gradient below the graph line
*/
- gradientFillColors?: Color[]
+ gradientFillColors?: Color[];
/**
* The width of the graph line (path)
*
* @default 3
*/
- lineThickness?: number
+ lineThickness?: number;
/**
* Enable the Fade-In Gradient Effect at the beginning of the Graph
*/
- enableFadeInMask?: boolean
+ enableFadeInMask?: boolean;
}
export type StaticLineGraphProps = BaseLineGraphProps & {
/* any static-only line graph props? */
-}
+};
export type AnimatedLineGraphProps = BaseLineGraphProps & {
/**
* Whether to enable Graph scrubbing/pan gesture.
*/
- enablePanGesture?: boolean
+ enablePanGesture?: boolean;
/**
* The color of the selection dot when the user is panning the graph.
*/
- selectionDotShadowColor?: string
+ selectionDotShadowColor?: string;
/**
* Horizontal padding applied to graph, so the pan gesture dot doesn't get cut off horizontally
*/
- horizontalPadding?: number
+ horizontalPadding?: number;
/**
* Vertical padding applied to graph, so the pan gesture dot doesn't get cut off vertically
*/
- verticalPadding?: number
+ verticalPadding?: number;
/**
* Enables an indicator which is displayed at the end of the graph
*/
- enableIndicator?: boolean
+ enableIndicator?: boolean;
/**
* Let's the indicator pulsate
*/
- indicatorPulsating?: boolean
+ indicatorPulsating?: boolean;
/**
* Called for each point while the user is scrubbing/panning through the graph
*/
- onPointSelected?: (point: GraphPoint) => void
+ onPointSelected?: (point: GraphPoint) => void;
/**
* Called once the user starts scrubbing/panning through the graph
*/
- onGestureStart?: () => void
+ onGestureStart?: () => void;
/**
* Called once the user stopped scrubbing/panning through the graph
*/
- onGestureEnd?: () => void
+ onGestureEnd?: () => void;
/**
* The element that renders the selection dot
*/
- SelectionDot?: React.ComponentType | null
+ SelectionDot?: React.ComponentType | null;
/**
* The element that gets rendered above the Graph (usually the "max" point/value of the Graph)
*/
- TopAxisLabel?: () => React.ReactElement | null
+ TopAxisLabel?: () => React.ReactElement | null;
/**
* The element that gets rendered below the Graph (usually the "min" point/value of the Graph)
*/
- BottomAxisLabel?: () => React.ReactElement | null
-}
+ BottomAxisLabel?: () => React.ReactElement | null;
+};
export type LineGraphProps =
| ({ animated: true } & AnimatedLineGraphProps)
- | ({ animated: false } & StaticLineGraphProps)
+ | ({ animated: false } & StaticLineGraphProps);
From 7e514bd98112c6f22610f03546471167004343e5 Mon Sep 17 00:00:00 2001
From: Thomas Coldwell <31568400+thomas-coldwell@users.noreply.github.com>
Date: Tue, 25 Oct 2022 14:50:41 +0100
Subject: [PATCH 2/6] fix: Conflicting prettier rules
---
example/src/screens/GraphPage.tsx | 74 ++++----
package.json | 8 +-
src/AnimatedLineGraph.tsx | 275 ++++++++++++++----------------
3 files changed, 173 insertions(+), 184 deletions(-)
diff --git a/example/src/screens/GraphPage.tsx b/example/src/screens/GraphPage.tsx
index aa0b496..6b96767 100644
--- a/example/src/screens/GraphPage.tsx
+++ b/example/src/screens/GraphPage.tsx
@@ -1,44 +1,44 @@
-import React, { useCallback, useMemo, useState } from 'react';
-import { View, StyleSheet, Text, Button } from 'react-native';
-import { LineGraph } from 'react-native-graph';
-import StaticSafeAreaInsets from 'react-native-static-safe-area-insets';
-import type { GraphRange } from '../../../src/LineGraphProps';
-import { SelectionDot } from '../components/CustomSelectionDot';
-import { Toggle } from '../components/Toggle';
+import React, { useCallback, useMemo, useState } from 'react'
+import { View, StyleSheet, Text, Button } from 'react-native'
+import { LineGraph } from 'react-native-graph'
+import StaticSafeAreaInsets from 'react-native-static-safe-area-insets'
+import type { GraphRange } from '../../../src/LineGraphProps'
+import { SelectionDot } from '../components/CustomSelectionDot'
+import { Toggle } from '../components/Toggle'
import {
generateRandomGraphData,
generateSinusGraphData,
-} from '../data/GraphData';
-import { useColors } from '../hooks/useColors';
-import { hapticFeedback } from '../utils/HapticFeedback';
+} from '../data/GraphData'
+import { useColors } from '../hooks/useColors'
+import { hapticFeedback } from '../utils/HapticFeedback'
-const POINT_COUNT = 70;
-const POINTS = generateRandomGraphData(POINT_COUNT);
-const COLOR = '#6a7ee7';
-const GRADIENT_FILL_COLORS = ['#7476df5D', '#7476df4D', '#7476df00'];
-const GRADIENT_LINE_COLORS = ['#FF0000', '#00FF00', '#0000FF'];
-const SMALL_POINTS = generateSinusGraphData(9);
+const POINT_COUNT = 70
+const POINTS = generateRandomGraphData(POINT_COUNT)
+const COLOR = '#6a7ee7'
+const GRADIENT_FILL_COLORS = ['#7476df5D', '#7476df4D', '#7476df00']
+const GRADIENT_LINE_COLORS = ['#FF0000', '#00FF00', '#0000FF']
+const SMALL_POINTS = generateSinusGraphData(9)
export function GraphPage() {
- const colors = useColors();
+ const colors = useColors()
- const [isAnimated, setIsAnimated] = useState(true);
- const [enablePanGesture, setEnablePanGesture] = useState(true);
- const [enableFadeInEffect, setEnableFadeInEffect] = useState(false);
+ const [isAnimated, setIsAnimated] = useState(true)
+ const [enablePanGesture, setEnablePanGesture] = useState(true)
+ const [enableFadeInEffect, setEnableFadeInEffect] = useState(false)
const [enableCustomSelectionDot, setEnableCustomSelectionDot] =
- useState(false);
- const [enableFillGradient, setEnableFillGradient] = useState(false);
- const [enableLineGradient, setEnableLineGradient] = useState(false);
- const [enableRange, setEnableRange] = useState(false);
- const [enableIndicator, setEnableIndicator] = useState(false);
- const [indicatorPulsating, setIndicatorPulsating] = useState(false);
+ useState(false)
+ const [enableFillGradient, setEnableFillGradient] = useState(false)
+ const [enableLineGradient, setEnableLineGradient] = useState(false)
+ const [enableRange, setEnableRange] = useState(false)
+ const [enableIndicator, setEnableIndicator] = useState(false)
+ const [indicatorPulsating, setIndicatorPulsating] = useState(false)
- const [points, setPoints] = useState(POINTS);
+ const [points, setPoints] = useState(POINTS)
const refreshData = useCallback(() => {
- setPoints(generateRandomGraphData(POINT_COUNT));
- hapticFeedback('impactLight');
- }, []);
+ setPoints(generateRandomGraphData(POINT_COUNT))
+ hapticFeedback('impactLight')
+ }, [])
const highestDate = useMemo(
() =>
@@ -46,10 +46,10 @@ export function GraphPage() {
? points[points.length - 1]!.date
: undefined,
[points]
- );
+ )
const range: GraphRange | undefined = useMemo(() => {
// if range is disabled, default to infinite range (undefined)
- if (!enableRange) return undefined;
+ if (!enableRange) return undefined
if (points.length !== 0 && highestDate != null) {
return {
@@ -61,16 +61,16 @@ export function GraphPage() {
min: -200,
max: 200,
},
- };
+ }
} else {
return {
y: {
min: -200,
max: 200,
},
- };
+ }
}
- }, [enableRange, highestDate, points]);
+ }, [enableRange, highestDate, points])
return (
@@ -158,7 +158,7 @@ export function GraphPage() {
- );
+ )
}
const styles = StyleSheet.create({
@@ -195,4 +195,4 @@ const styles = StyleSheet.create({
justifyContent: 'center',
paddingHorizontal: 15,
},
-});
+})
diff --git a/package.json b/package.json
index 56912dc..6bb1110 100644
--- a/package.json
+++ b/package.json
@@ -112,7 +112,8 @@
"tabWidth": 2,
"semi": false,
"trailingComma": "es5",
- "useTabs": false
+ "useTabs": false,
+ "semi": false
}
]
}
@@ -126,7 +127,8 @@
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
- "useTabs": false
+ "useTabs": false,
+ "semi": false
},
"react-native-builder-bob": {
"source": "src",
@@ -142,4 +144,4 @@
]
]
}
-}
+}
\ No newline at end of file
diff --git a/src/AnimatedLineGraph.tsx b/src/AnimatedLineGraph.tsx
index ac8893b..e0d838e 100644
--- a/src/AnimatedLineGraph.tsx
+++ b/src/AnimatedLineGraph.tsx
@@ -1,11 +1,5 @@
-import React, {
- useCallback,
- useEffect,
- useMemo,
- useRef,
- useState,
-} from 'react';
-import { View, StyleSheet, LayoutChangeEvent } from 'react-native';
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
+import { View, StyleSheet, LayoutChangeEvent } from 'react-native'
import {
Canvas,
runSpring,
@@ -22,16 +16,16 @@ import {
mix,
Circle,
Shadow,
-} from '@shopify/react-native-skia';
-import type { AnimatedLineGraphProps } from './LineGraphProps';
-import { SelectionDot as DefaultSelectionDot } from './SelectionDot';
+} from '@shopify/react-native-skia'
+import type { AnimatedLineGraphProps } from './LineGraphProps'
+import { SelectionDot as DefaultSelectionDot } from './SelectionDot'
import {
createGraphPath,
createGraphPathWithGradient,
getGraphPathRange,
GraphPathRange,
pixelFactorX,
-} from './CreateGraphPath';
+} from './CreateGraphPath'
import Reanimated, {
runOnJS,
useAnimatedReaction,
@@ -42,22 +36,22 @@ import Reanimated, {
withSequence,
withTiming,
withDelay,
-} from 'react-native-reanimated';
-import { getSixDigitHex } from './utils/getSixDigitHex';
-import { GestureDetector } from 'react-native-gesture-handler';
-import { usePanGesture } from './hooks/usePanGesture';
-import { getYForX } from './GetYForX';
-import { hexToRgba } from './utils/hexToRgba';
-
-const INDICATOR_RADIUS = 7;
-const INDICATOR_BORDER_MULTIPLIER = 1.3;
+} from 'react-native-reanimated'
+import { getSixDigitHex } from './utils/getSixDigitHex'
+import { GestureDetector } from 'react-native-gesture-handler'
+import { usePanGesture } from './hooks/usePanGesture'
+import { getYForX } from './GetYForX'
+import { hexToRgba } from './utils/hexToRgba'
+
+const INDICATOR_RADIUS = 7
+const INDICATOR_BORDER_MULTIPLIER = 1.3
const INDICATOR_PULSE_BLUR_RADIUS_SMALL =
- INDICATOR_RADIUS * INDICATOR_BORDER_MULTIPLIER;
+ INDICATOR_RADIUS * INDICATOR_BORDER_MULTIPLIER
const INDICATOR_PULSE_BLUR_RADIUS_BIG =
- INDICATOR_RADIUS * INDICATOR_BORDER_MULTIPLIER + 20;
+ INDICATOR_RADIUS * INDICATOR_BORDER_MULTIPLIER + 20
// weird rea type bug
-const ReanimatedView = Reanimated.View as any;
+const ReanimatedView = Reanimated.View as any
export function AnimatedLineGraph({
points,
@@ -81,27 +75,27 @@ export function AnimatedLineGraph({
BottomAxisLabel,
...props
}: AnimatedLineGraphProps): React.ReactElement {
- const [width, setWidth] = useState(0);
- const [height, setHeight] = useState(0);
- const interpolateProgress = useValue(0);
-
- const { gesture, isActive, x } = usePanGesture({ holdDuration: 300 });
- const circleX = useValue(0);
- const circleY = useValue(0);
- const pathEnd = useValue(0);
- const indicatorRadius = useValue(enableIndicator ? INDICATOR_RADIUS : 0);
+ const [width, setWidth] = useState(0)
+ const [height, setHeight] = useState(0)
+ const interpolateProgress = useValue(0)
+
+ const { gesture, isActive, x } = usePanGesture({ holdDuration: 300 })
+ const circleX = useValue(0)
+ const circleY = useValue(0)
+ const pathEnd = useValue(0)
+ const indicatorRadius = useValue(enableIndicator ? INDICATOR_RADIUS : 0)
const indicatorBorderRadius = useComputedValue(
() => indicatorRadius.current * INDICATOR_BORDER_MULTIPLIER,
[indicatorRadius]
- );
+ )
const pulseTrigger = useDerivedValue(() => {
- 'worklet';
- return isActive.value ? 1 : 0;
- }, []);
- const indicatorPulseAnimation = useSharedValue(0);
- const indicatorPulseRadius = useValue(INDICATOR_PULSE_BLUR_RADIUS_SMALL);
- const indicatorPulseOpacity = useValue(1);
+ 'worklet'
+ return isActive.value ? 1 : 0
+ }, [])
+ const indicatorPulseAnimation = useSharedValue(0)
+ const indicatorPulseRadius = useValue(INDICATOR_PULSE_BLUR_RADIUS_SMALL)
+ const indicatorPulseOpacity = useValue(1)
const positions = useComputedValue(
() => [
@@ -112,39 +106,39 @@ export function AnimatedLineGraph({
1,
],
[pathEnd]
- );
+ )
const onLayout = useCallback(
({ nativeEvent: { layout } }: LayoutChangeEvent) => {
- setWidth(Math.round(layout.width));
- setHeight(Math.round(layout.height));
+ setWidth(Math.round(layout.width))
+ setHeight(Math.round(layout.height))
},
[]
- );
+ )
const straightLine = useMemo(() => {
- const path = Skia.Path.Make();
- path.moveTo(0, height / 2);
+ const path = Skia.Path.Make()
+ path.moveTo(0, height / 2)
for (let i = 0; i < width - 1; i += 2) {
- const x = i;
- const y = height / 2;
- path.cubicTo(x, y, x, y, x, y);
+ const x = i
+ const y = height / 2
+ path.cubicTo(x, y, x, y, x, y)
}
- return path;
- }, [height, width]);
+ return path
+ }, [height, width])
- const paths = useValue<{ from?: SkPath; to?: SkPath }>({});
- const gradientPaths = useValue<{ from?: SkPath; to?: SkPath }>({});
- const commands = useRef([]);
- const [commandsChanged, setCommandsChanged] = useState(0);
+ const paths = useValue<{ from?: SkPath; to?: SkPath }>({})
+ const gradientPaths = useValue<{ from?: SkPath; to?: SkPath }>({})
+ const commands = useRef([])
+ const [commandsChanged, setCommandsChanged] = useState(0)
const pathRange: GraphPathRange = useMemo(
() => getGraphPathRange(points, range),
[points, range]
- );
+ )
const drawingWidth = useMemo(() => {
- const lastPoint = points[points.length - 1]!;
+ const lastPoint = points[points.length - 1]!
return Math.max(
Math.floor(
@@ -152,8 +146,8 @@ export function AnimatedLineGraph({
pixelFactorX(lastPoint.date, pathRange.x.min, pathRange.x.max)
),
0
- );
- }, [horizontalPadding, pathRange.x.max, pathRange.x.min, points, width]);
+ )
+ }, [horizontalPadding, pathRange.x.max, pathRange.x.min, points, width])
const indicatorX = useMemo(
() =>
@@ -161,31 +155,31 @@ export function AnimatedLineGraph({
? Math.floor(drawingWidth) + horizontalPadding
: undefined,
[commandsChanged, drawingWidth, horizontalPadding]
- );
+ )
const indicatorY = useMemo(
() =>
commandsChanged >= 0 && indicatorX != null
? getYForX(commands.current, indicatorX)
: undefined,
[commandsChanged, indicatorX]
- );
+ )
- const indicatorPulseColor = useMemo(() => hexToRgba(color, 0.4), [color]);
+ const indicatorPulseColor = useMemo(() => hexToRgba(color, 0.4), [color])
- const shouldFillGradient = gradientFillColors != null;
+ const shouldFillGradient = gradientFillColors != null
useEffect(() => {
if (height < 1 || width < 1) {
// view is not yet measured!
- return;
+ return
}
if (points.length < 1) {
// points are still empty!
- return;
+ return
}
- let path;
- let gradientPath;
+ let path
+ let gradientPath
const createGraphPathProps = {
points: points,
@@ -194,59 +188,59 @@ export function AnimatedLineGraph({
verticalPadding: verticalPadding,
canvasHeight: height,
canvasWidth: width,
- };
+ }
if (shouldFillGradient) {
const { path: pathNew, gradientPath: gradientPathNew } =
- createGraphPathWithGradient(createGraphPathProps);
+ createGraphPathWithGradient(createGraphPathProps)
- path = pathNew;
- gradientPath = gradientPathNew;
+ path = pathNew
+ gradientPath = gradientPathNew
} else {
- path = createGraphPath(createGraphPathProps);
+ path = createGraphPath(createGraphPathProps)
}
- commands.current = path.toCmds();
+ commands.current = path.toCmds()
if (gradientPath != null) {
- const previous = gradientPaths.current;
- let from: SkPath = previous.to ?? straightLine;
+ const previous = gradientPaths.current
+ let from: SkPath = previous.to ?? straightLine
if (previous.from != null && interpolateProgress.current < 1)
from =
- from.interpolate(previous.from, interpolateProgress.current) ?? from;
+ from.interpolate(previous.from, interpolateProgress.current) ?? from
if (gradientPath.isInterpolatable(from)) {
gradientPaths.current = {
from: from,
to: gradientPath,
- };
+ }
} else {
gradientPaths.current = {
from: gradientPath,
to: gradientPath,
- };
+ }
}
}
- const previous = paths.current;
- let from: SkPath = previous.to ?? straightLine;
+ const previous = paths.current
+ let from: SkPath = previous.to ?? straightLine
if (previous.from != null && interpolateProgress.current < 1)
from =
- from.interpolate(previous.from, interpolateProgress.current) ?? from;
+ from.interpolate(previous.from, interpolateProgress.current) ?? from
if (path.isInterpolatable(from)) {
paths.current = {
from: from,
to: path,
- };
+ }
} else {
paths.current = {
from: path,
to: path,
- };
+ }
}
- setCommandsChanged(commandsChanged + 1);
+ setCommandsChanged(commandsChanged + 1)
runSpring(
interpolateProgress,
@@ -257,7 +251,7 @@ export function AnimatedLineGraph({
damping: 400,
velocity: 0,
}
- );
+ )
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
height,
@@ -272,7 +266,7 @@ export function AnimatedLineGraph({
straightLine,
verticalPadding,
width,
- ]);
+ ])
const gradientColors = useMemo(() => {
if (typeof color === 'string') {
@@ -283,7 +277,7 @@ export function AnimatedLineGraph({
`${getSixDigitHex(color)}ff`,
`${getSixDigitHex(color)}33`,
`${getSixDigitHex(color)}33`,
- ];
+ ]
} else {
return [
color,
@@ -291,39 +285,39 @@ export function AnimatedLineGraph({
color,
`${getSixDigitHex(color)}33`,
`${getSixDigitHex(color)}33`,
- ];
+ ]
}
} else {
- return color;
+ return color
}
- }, [color, enableFadeInMask]);
+ }, [color, enableFadeInMask])
const path = useComputedValue(
() => {
- const from = paths.current.from ?? straightLine;
- const to = paths.current.to ?? straightLine;
+ const from = paths.current.from ?? straightLine
+ const to = paths.current.to ?? straightLine
- return to.interpolate(from, interpolateProgress.current);
+ return to.interpolate(from, interpolateProgress.current)
},
// RN Skia deals with deps differently. They are actually the required SkiaValues that the derived value listens to, not react values.
[interpolateProgress]
- );
+ )
const gradientPath = useComputedValue(
() => {
- const from = gradientPaths.current.from ?? straightLine;
- const to = gradientPaths.current.to ?? straightLine;
+ const from = gradientPaths.current.from ?? straightLine
+ const to = gradientPaths.current.to ?? straightLine
- return to.interpolate(from, interpolateProgress.current);
+ return to.interpolate(from, interpolateProgress.current)
},
// RN Skia deals with deps differently. They are actually the required SkiaValues that the derived value listens to, not react values.
[interpolateProgress]
- );
+ )
const stopPulsating = useCallback(() => {
- cancelAnimation(indicatorPulseAnimation);
- indicatorPulseAnimation.value = 0;
- }, [indicatorPulseAnimation]);
+ cancelAnimation(indicatorPulseAnimation)
+ indicatorPulseAnimation.value = 0
+ }, [indicatorPulseAnimation])
const startPulsating = useCallback(() => {
indicatorPulseAnimation.value = withRepeat(
@@ -338,34 +332,31 @@ export function AnimatedLineGraph({
)
),
-1
- );
- }, [indicatorPulseAnimation]);
+ )
+ }, [indicatorPulseAnimation])
const setFingerX = useCallback(
(fingerX: number) => {
- const lowerBound = horizontalPadding;
- const upperBound = drawingWidth + horizontalPadding;
+ const lowerBound = horizontalPadding
+ const upperBound = drawingWidth + horizontalPadding
- const fingerXInRange = Math.min(
- Math.max(fingerX, lowerBound),
- upperBound
- );
- const y = getYForX(commands.current, fingerXInRange);
+ const fingerXInRange = Math.min(Math.max(fingerX, lowerBound), upperBound)
+ const y = getYForX(commands.current, fingerXInRange)
if (y != null) {
- circleY.current = y;
- circleX.current = fingerXInRange;
+ circleY.current = y
+ circleX.current = fingerXInRange
}
if (fingerX > lowerBound && fingerX < upperBound && isActive.value)
- pathEnd.current = fingerX / width;
+ pathEnd.current = fingerX / width
- const actualFingerX = fingerX - horizontalPadding;
+ const actualFingerX = fingerX - horizontalPadding
- const index = Math.round((actualFingerX / upperBound) * points.length);
- const pointIndex = Math.min(Math.max(index, 0), points.length - 1);
- const dataPoint = points[pointIndex];
- if (dataPoint != null) onPointSelected?.(dataPoint);
+ const index = Math.round((actualFingerX / upperBound) * points.length)
+ const pointIndex = Math.min(Math.max(index, 0), points.length - 1)
+ const dataPoint = points[pointIndex]
+ if (dataPoint != null) onPointSelected?.(dataPoint)
},
[
circleX,
@@ -378,7 +369,7 @@ export function AnimatedLineGraph({
points,
width,
]
- );
+ )
const setIsActive = useCallback(
(active: boolean) => {
@@ -387,15 +378,15 @@ export function AnimatedLineGraph({
stiffness: 1000,
damping: 50,
velocity: 0,
- });
+ })
if (active) {
- onGestureStart?.();
- stopPulsating();
+ onGestureStart?.()
+ stopPulsating()
} else {
- onGestureEnd?.();
- pathEnd.current = 1;
- startPulsating();
+ onGestureEnd?.()
+ pathEnd.current = 1
+ startPulsating()
}
},
[
@@ -406,37 +397,37 @@ export function AnimatedLineGraph({
startPulsating,
stopPulsating,
]
- );
+ )
useAnimatedReaction(
() => x.value,
(fingerX) => {
if (isActive.value || fingerX) {
- runOnJS(setFingerX)(fingerX);
+ runOnJS(setFingerX)(fingerX)
}
},
[isActive, setFingerX, width, x]
- );
+ )
useAnimatedReaction(
() => isActive.value,
(active) => {
- runOnJS(setIsActive)(active);
+ runOnJS(setIsActive)(active)
},
[isActive, setIsActive]
- );
+ )
useEffect(() => {
if (points.length !== 0 && commands.current.length !== 0)
- pathEnd.current = 1;
- }, [commands, pathEnd, points.length]);
+ pathEnd.current = 1
+ }, [commands, pathEnd, points.length])
useEffect(() => {
if (indicatorPulsating) {
- startPulsating();
+ startPulsating()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [indicatorPulsating]);
+ }, [indicatorPulsating])
useSharedValueEffect(
() => {
@@ -445,19 +436,15 @@ export function AnimatedLineGraph({
indicatorPulseAnimation.value,
INDICATOR_PULSE_BLUR_RADIUS_SMALL,
INDICATOR_PULSE_BLUR_RADIUS_BIG
- );
- indicatorPulseOpacity.current = mix(
- indicatorPulseAnimation.value,
- 1,
- 0
- );
+ )
+ indicatorPulseOpacity.current = mix(indicatorPulseAnimation.value, 1, 0)
} else {
- indicatorPulseRadius.current = 0;
+ indicatorPulseRadius.current = 0
}
},
indicatorPulseAnimation,
pulseTrigger
- );
+ )
return (
@@ -555,7 +542,7 @@ export function AnimatedLineGraph({
- );
+ )
}
const styles = StyleSheet.create({
@@ -571,4 +558,4 @@ const styles = StyleSheet.create({
axisRow: {
height: 17,
},
-});
+})
From cae0adb4b0f175d786065115751bb6ca2bed8206 Mon Sep 17 00:00:00 2001
From: Thomas Coldwell <31568400+thomas-coldwell@users.noreply.github.com>
Date: Tue, 25 Oct 2022 15:21:31 +0100
Subject: [PATCH 3/6] fix: Prettier
---
src/LineGraphProps.ts | 68 +++++++++++++++++++++----------------------
1 file changed, 34 insertions(+), 34 deletions(-)
diff --git a/src/LineGraphProps.ts b/src/LineGraphProps.ts
index 5afc6aa..445c8e8 100644
--- a/src/LineGraphProps.ts
+++ b/src/LineGraphProps.ts
@@ -1,112 +1,112 @@
-import type React from 'react';
-import type { ViewProps } from 'react-native';
-import type { GraphPathRange } from './CreateGraphPath';
-import type { SharedValue } from 'react-native-reanimated';
-import type { Color, SkiaMutableValue } from '@shopify/react-native-skia';
+import type React from 'react'
+import type { ViewProps } from 'react-native'
+import type { GraphPathRange } from './CreateGraphPath'
+import type { SharedValue } from 'react-native-reanimated'
+import type { Color, SkiaMutableValue } from '@shopify/react-native-skia'
export interface GraphPoint {
- value: number;
- date: Date;
+ value: number
+ date: Date
}
-export type GraphRange = Partial;
+export type GraphRange = Partial
export interface SelectionDotProps {
- isActive: SharedValue;
- color: BaseLineGraphProps['color'];
- lineThickness: BaseLineGraphProps['lineThickness'];
- circleX: SkiaMutableValue;
- circleY: SkiaMutableValue;
+ isActive: SharedValue
+ color: BaseLineGraphProps['color']
+ lineThickness: BaseLineGraphProps['lineThickness']
+ circleX: SkiaMutableValue
+ circleY: SkiaMutableValue
}
interface BaseLineGraphProps extends ViewProps {
/**
* All points to be marked in the graph. Coordinate system will adjust to scale automatically.
*/
- points: GraphPoint[];
+ points: GraphPoint[]
/**
* Range of the graph's x and y-axis. The range must be greater
* than the range given by the points.
*/
- range?: GraphRange;
+ range?: GraphRange
/**
* Color of the graph line (path) either as a single solid color or an array of colors for a line gradient
*/
- color: string | Color[];
+ color: string | string[]
/**
* (Optional) Colors for the fill gradient below the graph line
*/
- gradientFillColors?: Color[];
+ gradientFillColors?: Color[]
/**
* The width of the graph line (path)
*
* @default 3
*/
- lineThickness?: number;
+ lineThickness?: number
/**
* Enable the Fade-In Gradient Effect at the beginning of the Graph
*/
- enableFadeInMask?: boolean;
+ enableFadeInMask?: boolean
}
export type StaticLineGraphProps = BaseLineGraphProps & {
/* any static-only line graph props? */
-};
+}
export type AnimatedLineGraphProps = BaseLineGraphProps & {
/**
* Whether to enable Graph scrubbing/pan gesture.
*/
- enablePanGesture?: boolean;
+ enablePanGesture?: boolean
/**
* The color of the selection dot when the user is panning the graph.
*/
- selectionDotShadowColor?: string;
+ selectionDotShadowColor?: string
/**
* Horizontal padding applied to graph, so the pan gesture dot doesn't get cut off horizontally
*/
- horizontalPadding?: number;
+ horizontalPadding?: number
/**
* Vertical padding applied to graph, so the pan gesture dot doesn't get cut off vertically
*/
- verticalPadding?: number;
+ verticalPadding?: number
/**
* Enables an indicator which is displayed at the end of the graph
*/
- enableIndicator?: boolean;
+ enableIndicator?: boolean
/**
* Let's the indicator pulsate
*/
- indicatorPulsating?: boolean;
+ indicatorPulsating?: boolean
/**
* Called for each point while the user is scrubbing/panning through the graph
*/
- onPointSelected?: (point: GraphPoint) => void;
+ onPointSelected?: (point: GraphPoint) => void
/**
* Called once the user starts scrubbing/panning through the graph
*/
- onGestureStart?: () => void;
+ onGestureStart?: () => void
/**
* Called once the user stopped scrubbing/panning through the graph
*/
- onGestureEnd?: () => void;
+ onGestureEnd?: () => void
/**
* The element that renders the selection dot
*/
- SelectionDot?: React.ComponentType | null;
+ SelectionDot?: React.ComponentType | null
/**
* The element that gets rendered above the Graph (usually the "max" point/value of the Graph)
*/
- TopAxisLabel?: () => React.ReactElement | null;
+ TopAxisLabel?: () => React.ReactElement | null
/**
* The element that gets rendered below the Graph (usually the "min" point/value of the Graph)
*/
- BottomAxisLabel?: () => React.ReactElement | null;
-};
+ BottomAxisLabel?: () => React.ReactElement | null
+}
export type LineGraphProps =
| ({ animated: true } & AnimatedLineGraphProps)
- | ({ animated: false } & StaticLineGraphProps);
+ | ({ animated: false } & StaticLineGraphProps)
From 3f25cf4336997ee8224760fdde0e46f7178d914c Mon Sep 17 00:00:00 2001
From: Thomas Coldwell <31568400+thomas-coldwell@users.noreply.github.com>
Date: Tue, 25 Oct 2022 15:22:19 +0100
Subject: [PATCH 4/6] feat: Line gradient positions
---
src/AnimatedLineGraph.tsx | 40 ++++++++++++++++++++++++++-------------
1 file changed, 27 insertions(+), 13 deletions(-)
diff --git a/src/AnimatedLineGraph.tsx b/src/AnimatedLineGraph.tsx
index e0d838e..79079f8 100644
--- a/src/AnimatedLineGraph.tsx
+++ b/src/AnimatedLineGraph.tsx
@@ -97,16 +97,20 @@ export function AnimatedLineGraph({
const indicatorPulseRadius = useValue(INDICATOR_PULSE_BLUR_RADIUS_SMALL)
const indicatorPulseOpacity = useValue(1)
- const positions = useComputedValue(
- () => [
- 0,
- Math.min(0.15, pathEnd.current),
- pathEnd.current,
- pathEnd.current,
- 1,
- ],
- [pathEnd]
- )
+ const positions = useComputedValue(() => {
+ if (typeof color === 'string') {
+ return [
+ 0,
+ Math.min(0.15, pathEnd.current),
+ pathEnd.current,
+ pathEnd.current,
+ 1,
+ ]
+ } else {
+ return color.map((_, index) => index / (color.length - 1))
+ }
+ }, [pathEnd, color])
+
const onLayout = useCallback(
({ nativeEvent: { layout } }: LayoutChangeEvent) => {
setWidth(Math.round(layout.width))
@@ -115,6 +119,8 @@ export function AnimatedLineGraph({
[]
)
+ console.log(positions, color)
+
const straightLine = useMemo(() => {
const path = Skia.Path.Make()
path.moveTo(0, height / 2)
@@ -164,7 +170,15 @@ export function AnimatedLineGraph({
[commandsChanged, indicatorX]
)
- const indicatorPulseColor = useMemo(() => hexToRgba(color, 0.4), [color])
+ const primaryColor = useMemo(() => {
+ if (typeof color === 'string') return color
+ return color[0] ?? '#FFF'
+ }, [color])
+
+ const indicatorPulseColor = useMemo(
+ () => hexToRgba(primaryColor, 0.4),
+ [primaryColor]
+ )
const shouldFillGradient = gradientFillColors != null
@@ -494,7 +508,7 @@ export function AnimatedLineGraph({
{SelectionDot != null && (
)}
From 47ba80364c5a80fa9fba049040f560c1db6e5695 Mon Sep 17 00:00:00 2001
From: Thomas Coldwell <31568400+thomas-coldwell@users.noreply.github.com>
Date: Tue, 25 Oct 2022 15:32:18 +0100
Subject: [PATCH 5/6] fix: Add support to static line graph
---
src/AnimatedLineGraph.tsx | 2 --
src/StaticLineGraph.tsx | 19 +++++++++++++++----
2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/src/AnimatedLineGraph.tsx b/src/AnimatedLineGraph.tsx
index 79079f8..ec6160c 100644
--- a/src/AnimatedLineGraph.tsx
+++ b/src/AnimatedLineGraph.tsx
@@ -119,8 +119,6 @@ export function AnimatedLineGraph({
[]
)
- console.log(positions, color)
-
const straightLine = useMemo(() => {
const path = Skia.Path.Make()
path.moveTo(0, height / 2)
diff --git a/src/StaticLineGraph.tsx b/src/StaticLineGraph.tsx
index b7149bf..00ffc5b 100644
--- a/src/StaticLineGraph.tsx
+++ b/src/StaticLineGraph.tsx
@@ -47,12 +47,23 @@ export function StaticLineGraph({
[height, lineThickness, pathRange, points, width]
)
+ const primaryColor = useMemo(() => {
+ if (typeof color === 'string') return color
+ return color[0] ?? '#FFF'
+ }, [color])
+
const gradientColors = useMemo(
- () => [`${getSixDigitHex(color)}00`, `${getSixDigitHex(color)}ff`],
+ () =>
+ typeof color === 'string'
+ ? [`${getSixDigitHex(color)}00`, `${getSixDigitHex(color)}ff`]
+ : color,
[color]
)
const gradientFrom = useMemo(() => vec(0, 0), [])
- const gradientTo = useMemo(() => vec(width * 0.15, 0), [width])
+ const gradientTo = useMemo(
+ () => vec(typeof color === 'string' ? width * 0.15 : width, 0),
+ [width, color]
+ )
return (
@@ -60,12 +71,12 @@ export function StaticLineGraph({
- {enableFadeInMask && (
+ {(enableFadeInMask || typeof color !== 'string') && (
Date: Tue, 25 Oct 2022 16:03:29 +0100
Subject: [PATCH 6/6] fix: selection dot color
---
src/SelectionDot.tsx | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/SelectionDot.tsx b/src/SelectionDot.tsx
index e72098b..499749e 100644
--- a/src/SelectionDot.tsx
+++ b/src/SelectionDot.tsx
@@ -1,4 +1,4 @@
-import React, { useCallback } from 'react'
+import React, { useCallback, useMemo } from 'react'
import { runOnJS, useAnimatedReaction } from 'react-native-reanimated'
import {
runSpring,
@@ -45,6 +45,11 @@ export function SelectionDot({
[isActive, setIsActive]
)
+ const primaryColor = useMemo(() => {
+ if (typeof color === 'string') return color
+ return color[0] ?? '#FFF'
+ }, [color])
+
return (
-
+