import React, { createContext, useMemo } from 'react'; import { useAnimatedReaction, useSharedValue } from 'react-native-reanimated'; import { scheduleOnRN } from 'react-native-worklets'; import type { TLineChartData, TLineChartDataProp } from './types'; import { LineChartDataProvider } from './Data'; import type { TLineChartContext, YRangeProp } from './types'; import { getDomain, lineChartDataPropToArray } from './utils'; export const LineChartContext = createContext({ currentX: { value: -1 } as TLineChartContext['currentX'], currentIndex: { value: -1 } as TLineChartContext['currentIndex'], domain: [0, 0], isActive: { value: false } as TLineChartContext['isActive'], yDomain: { min: 0, max: 0, }, xDomain: undefined, xLength: 0, }); type LineChartProviderProps = { children: React.ReactNode; data: TLineChartDataProp; yRange?: YRangeProp; onCurrentIndexChange?: (x: number) => void; xLength?: number; xDomain?: [number, number]; }; export function LineChartProvider({ children, data = [], yRange, onCurrentIndexChange, xLength, xDomain, }: LineChartProviderProps) { const currentX = useSharedValue(-1); const currentIndex = useSharedValue(-1); const isActive = useSharedValue(false); const domain = useMemo( () => getDomain( Array.isArray(data) ? data : Object.values(data)[0] as TLineChartData ), [data] ); const values = useMemo(() => lineChartDataPropToArray(data).map(({ value }) => value), [data] ); const yDomainValues = useMemo(() => ({ min: yRange?.min ?? Math.min(...values), max: yRange?.max ?? Math.max(...values), }), [values, yRange?.min, yRange?.max]); const contextValue = useMemo(() => { const domainRows = Array.isArray(data) ? data : Object.values(data)[0] as TLineChartData; return { currentX, currentIndex, isActive, domain, yDomain: yDomainValues, xDomain, xLength: xLength ?? domainRows.length, }; }, [ currentIndex, currentX, data, domain, isActive, yDomainValues, xLength, xDomain, ]); useAnimatedReaction( () => currentIndex.value, (x, prevX) => { if (x !== prevX && onCurrentIndexChange) { scheduleOnRN(onCurrentIndexChange, x); } } ); return ( {children} ); } LineChartProvider.displayName = 'LineChartProvider';