diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..eb03241 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,7 @@ +module.exports = { + arrowParens: 'avoid', + bracketSpacing: true, + bracketSameLine: false, + singleQuote: true, + trailingComma: 'es5', +}; diff --git a/README.md b/README.md index 5ae6da6..976af3e 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,19 @@ Labels are useful while moving finger through the chart to show the exact value | `format` | reanimated worklet | `a => a` | Worklet for formatting data from the chart. It can be useful when your data is a timestamp or currency. | | ...props | `object` | `{}` | Rest of the props applied to `TextInput` including `style` | +### `CurrentPositionVerticalLine` & `OpeningPositionHorizontalLine` +CurrentPositionVerticalLine is a vertical line moving with user's finger through chart. + +OpeningPositionHorizontalLine is a horizontal static line on height of the first point. + +| Prop name | type | default | description | +|--------------|----------------------|----------|-------------| +| `color` | `string` | `#000000`| Color of the line. | +| `thickness` | `number` | `2` | Thickness of the line. | +| `length` | `number` | `null` | Length of the line. | +| ...props | `object` | `{}` | Rest of the props applied to svg's `Line`. | + +![](gifs/lines.png) ### Candle Charts diff --git a/gifs/lines.png b/gifs/lines.png new file mode 100644 index 0000000..e03d372 Binary files /dev/null and b/gifs/lines.png differ diff --git a/src/charts/linear/ChartLines.js b/src/charts/linear/ChartLines.js new file mode 100644 index 0000000..7e831ad --- /dev/null +++ b/src/charts/linear/ChartLines.js @@ -0,0 +1,58 @@ +import React, { useContext } from 'react'; +import Animated from 'react-native-reanimated'; +import { Svg, Line } from 'react-native-svg'; +import ChartContext from '../../helpers/ChartContext'; +import withReanimatedFallback from '../../helpers/withReanimatedFallback'; + +function ChartLineFactory(orientation) { + const isVertical = orientation == 'vertical'; + return function ChartLine({ + color = '#000000', + thickness = 2, + length, + ...props + }) { + const { + currentPositionVerticalLineStyle, + openingPositionHorizontalLineStyle, + } = useContext(ChartContext); + return ( + + + + + + ); + }; +} + +export const CurrentPositionVerticalLine = withReanimatedFallback( + ChartLineFactory('vertical') +); +export const OpeningPositionHorizontalLine = withReanimatedFallback( + ChartLineFactory('horizontal') +); diff --git a/src/charts/linear/ChartPath.js b/src/charts/linear/ChartPath.js index 8111573..f26802f 100644 --- a/src/charts/linear/ChartPath.js +++ b/src/charts/linear/ChartPath.js @@ -194,6 +194,7 @@ export default function ChartPathProvider({ state, setContextValue = () => {}, providedData = rawData, + proceededData, } = useContext(ChartContext) || generateValues(); const prevData = useSharedValue(valuesStore.current.prevData, 'prevData'); @@ -224,6 +225,7 @@ export default function ChartPathProvider({ return; } const [parsedData] = parse(data.points, data.yRange); + proceededData.value = parsedData; const [parsedoriginalData, newExtremes] = parse( data.nativePoints || data.points ); diff --git a/src/charts/linear/ChartPathProvider.js b/src/charts/linear/ChartPathProvider.js index 058219e..5030ae6 100644 --- a/src/charts/linear/ChartPathProvider.js +++ b/src/charts/linear/ChartPathProvider.js @@ -1,10 +1,15 @@ import React, { useMemo, useState } from 'react'; -import { useAnimatedStyle } from 'react-native-reanimated'; +import { + useAnimatedStyle, + useSharedValue, + withTiming, +} from 'react-native-reanimated'; import ChartContext, { useGenerateValues } from '../../helpers/ChartContext'; export default function ChartPathProvider({ data: providedData, children }) { const values = useGenerateValues(); + const proceededData = useSharedValue(null); const dotStyle = useAnimatedStyle( () => ({ opacity: values.dotScale.value, @@ -16,16 +21,50 @@ export default function ChartPathProvider({ data: providedData, children }) { }), [] ); + + const currentPositionVerticalLineStyle = useAnimatedStyle( + () => ({ + opacity: values.dotScale.value, + transform: [{ translateX: values.positionX.value }], + }), + [] + ); + + const openingPositionHorizontalLineStyle = useAnimatedStyle(() => { + return { + opacity: proceededData == null ? 0 : 1, + transform: [ + { + translateY: withTiming( + proceededData?.value?.[0].y * values?.layoutSize?.value?.height + + 10 || 0 + ), + }, + ], + }; + }, [proceededData]); + const [contextReanimatedValue, setContextValue] = useState({}); const contextValue = useMemo( () => ({ dotStyle, + currentPositionVerticalLineStyle, + openingPositionHorizontalLineStyle, ...values, ...contextReanimatedValue, providedData, + proceededData, setContextValue, }), - [dotStyle, values, contextReanimatedValue, providedData] + [ + dotStyle, + currentPositionVerticalLineStyle, + openingPositionHorizontalLineStyle, + values, + contextReanimatedValue, + providedData, + proceededData, + ] ); return ( diff --git a/src/index.js b/src/index.js index 30c3834..f2fe890 100644 --- a/src/index.js +++ b/src/index.js @@ -3,6 +3,10 @@ Animated.addWhitelistedNativeProps({ text: true }); export { default as ChartPathProvider } from './charts/linear/ChartPathProvider'; export { default as ChartDot } from './charts/linear/ChartDot'; +export { + CurrentPositionVerticalLine, + OpeningPositionHorizontalLine, +} from './charts/linear/ChartLines'; export { ChartYLabel, ChartXLabel } from './charts/linear/ChartLabels'; export { default as ChartPath } from './charts/linear/ChartPath'; export { default as useChartData } from './helpers/useChartData';