UNPKG

@naarni/design-system

Version:

Naarni React Native Design System for EV Fleet Apps

69 lines (68 loc) 2.57 kB
import React from 'react'; import { View, StyleSheet, Dimensions } from 'react-native'; import { Canvas, Path } from '@shopify/react-native-skia'; import { useSharedValue, withSpring, useDerivedValue } from 'react-native-reanimated'; import { useDeviceTheme } from '../../theme/deviceTheme'; export const LineChart = ({ data, width = Dimensions.get('window').width - 32, height = 200, color, strokeWidth = 2, animated = true, }) => { const { colors } = useDeviceTheme(); const progress = useSharedValue(0); React.useEffect(() => { if (animated) { progress.value = withSpring(1, { mass: 1, damping: 20, stiffness: 90, }); } else { progress.value = 1; } }, [animated]); const getPath = React.useCallback(() => { if (data.length === 0) return ''; const maxValue = Math.max(...data); const minValue = Math.min(...data); const range = maxValue - minValue || 1; const step = width / (data.length - 1); let path = `M 0 ${height - ((data[0] - minValue) / range) * height}`; for (let i = 1; i < data.length; i++) { const x = i * step; const y = height - ((data[i] - minValue) / range) * height; path += ` L ${x} ${y}`; } return path; }, [data, width, height]); const basePath = React.useMemo(() => getPath(), [getPath]); const animatedPath = useDerivedValue(() => { if (!animated) return basePath; const commands = basePath.split(' '); const result = []; for (let i = 0; i < commands.length; i++) { if (commands[i] === 'M' || commands[i] === 'L') { result.push(commands[i]); if (i + 1 < commands.length) { const [x, y] = commands[i + 1].split(' ').map(Number); const animatedX = x * progress.value; result.push(`${animatedX} ${y}`); i++; } } } return result.join(' '); }, [basePath, progress]); return (<View style={[styles.container, { width, height }]}> <Canvas style={styles.canvas}> <Path path={animatedPath.value} strokeWidth={strokeWidth} color={color || colors.primary.main} style="stroke"/> </Canvas> </View>); }; const styles = StyleSheet.create({ container: { backgroundColor: 'transparent', }, canvas: { flex: 1, }, });