@naarni/design-system
Version:
Naarni React Native Design System for EV Fleet Apps
69 lines (68 loc) • 2.57 kB
JavaScript
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,
},
});