barchart
unknown
javascript
4 years ago
4.1 kB
5
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...