barchart
unknown
javascript
3 years ago
4.1 kB
4
Indexable
import { StyleSheet, Text, View } from 'react-native'; import React from 'react'; import GridDivider from './components/grid_divider'; import ColumnItem from './components/column_item'; const _data = [ { x: '12/2021', y: 2 }, { x: '1/2022', y: 11 }, { x: '2/2022', y: 4 }, { x: '3/2022', y: 0 }, { x: '4/2022', y: 0 }, ]; const getYMin = YAxis => { let min = YAxis[0]; for (let i = 1; i < YAxis.length; i++) { if ((YAxis[i] < min && YAxis[i] !== 0) || min === 0) { min = YAxis[i]; } } return min; }; const BarChart = React.forwardRef( ( { onPressColumn, data = _data, renderYAxis = e => ( <Text key={`${e}`} style={styles.txtYAxis}> {e}M </Text> ), renderXAxis = e => <Text style={styles.txtXAxis}>{e.x}</Text>, }, ref, ) => { const [currentIndex, setCurrentIndex] = React.useState(-1); const _yAxis = React.useMemo(() => data.map(e => e.y), [data]); const yMin = React.useMemo(() => Math.round(getYMin(_yAxis)), [_yAxis]); const yMax = React.useMemo(() => { let max = Math.ceil(Math.max(..._yAxis)); if (max % 2 === 1) { return max + 1; } return max; }, [_yAxis]); const yAxisDisplay = React.useMemo(() => { if (yMin === yMax) { return [yMax, (yMax + yMax / 2) / 2, yMax / 2, 0]; } return [yMax, (yMax + yMin) / 2, yMin, 0]; }); const percents = React.useMemo(() => { if (yMin === 0) return [0, 0, 0, 0, 0]; if (yMin !== yMax) { return data.map(e => { if (e.y === 0) return 0; return heightCell + ((e.y - yMin) / (yMax - yMin)) * heightCell * 2; }); } else { return data.map(e => { if (e.y === yMin) return heightCell * 3; return 0; }); } }, [data]); // list height item) React.useImperativeHandle(ref, () => ({ selectAll: () => { setCurrentIndex(-1); }, })); return ( <View style={styles.container}> <View style={styles.containerTop}> <View style={styles.yAxis}> {yAxisDisplay.map(e => renderYAxis(e))} </View> <View style={styles.containerChart}> <GridDivider length={data.length} /> {percents.map((e, i) => ( <ColumnItem height={e} key={`${i}`} index={i} onPress={index => { onPressColumn && onPressColumn(data[index]); setCurrentIndex(index); }} selected={currentIndex === i || currentIndex === -1} /> ))} </View> </View> <View style={styles.bottom}> {data.map((e, i) => { return ( <View style={styles.itemXAxis} key={`${e.x}`}> {i === 0 || i === data.length - 1 ? renderXAxis(e) : null} </View> ); })} </View> </View> ); }, ); export default React.memo(BarChart); const widthYAxis = 40; const heightCell = 50; const widthCell = 60; const heightContainerChart = heightCell * 3; const widthContainerChart = widthCell * 5; const heightYAxis = heightContainerChart + 17; const widthChart = widthContainerChart + widthYAxis; const styles = StyleSheet.create({ container: { width: widthChart, backgroundColor: '#1B222D', }, containerTop: { flexDirection: 'row', alignItems: 'center', }, yAxis: { width: 40, justifyContent: 'space-between', height: heightYAxis, backgroundColor: '#1B222D', }, txtYAxis: { fontSize: 12, fontWeight: '500', color: '#8492A7', }, containerChart: { flexDirection: 'row', height: heightContainerChart, width: widthContainerChart, }, bottom: { flexDirection: 'row', paddingLeft: widthYAxis, paddingBottom: 8, }, txtXAxis: { fontSize: 12, fontWeight: '500', color: '#8492A7', }, itemXAxis: { flex: 1, alignItems: 'center', justifyContent: 'center', }, });
Editor is loading...