barchartcustom back

mail@pastecode.io avatar
unknown
plain_text
2 months ago
5.3 kB
5
Indexable
Never
import React from "react";
import { ScrollView, StyleSheet, View } from "react-native";
import { BarChart } from "react-native-chart-kit";
import { G, Rect, Svg } from "react-native-svg";
import { width } from "../../constants/constants";
import { colors } from "../../theme";
import { Text } from "react-native";
import fonts from "../../assets/fonts";

interface BarChartCustomPropTypes {
    chartConfig: Object | any;
    data: any;
    trackersDataItems?: any;
    showXAxis?: boolean;
    showYAxis?: boolean;
    maxDataValue: number | null;
    showAverage?: boolean;
    trackerType?: string;
    graphWidth?: string | number;
}

export const BarChartCustom: React.FC<BarChartCustomPropTypes> = ({
    chartConfig,
    data,
    trackersDataItems,
    showXAxis,
    showYAxis,
    maxDataValue,
    showAverage,
    trackerType,
    graphWidth
}) => {

    interface IndicatorLinePropTypes {
        value: number | string;
        color: string;
        maxDataValue: number;
    }
    const maxVal = Math.max(...data.datasets[0]?.data);

    const IndicatorLine = ({ value, color, maxDataValue }: IndicatorLinePropTypes) => {

        const topPosition = ((maxVal - value) / maxVal) * 100 + '%';
        const spacing = 10;
        const dashes = new Array(Math.floor(width / spacing)).fill(null);

        return (
            <Svg style={{ ...styles.dashedLineStyles, top: topPosition }}>
                <G>
                    {dashes.map((_, index) => (
                        <Rect
                            key={index}
                            x="6"
                            y="0"
                            width="5"
                            height="1"
                            fill={color}
                            translateX={spacing * index}
                        />
                    ))}
                </G>
            </Svg>
        );
    }


    // const computeAverage = () => {
    //     if (!data || !data.datasets || !data.datasets[0] || !data.datasets[0].data) return 0;
    //     const sum = data.datasets[0].data.reduce((acc, value) => acc + value, 0);
    //     return Math.floor(sum / data.datasets[0].data.length);
    // };

    function computeAverageWithoutZeros(array) {

        const nonZeroValues = array.filter(value => value !== 0);
        
        if (nonZeroValues.length === 0) {
            return 0; 
        } else {
            const sum = nonZeroValues.reduce((acc, curr) => acc + curr, 0);
            const average = sum / nonZeroValues.length;
            return average;
        }
    }

    const averageValue = computeAverageWithoutZeros(data.datasets[0]?.data)?.toFixed(2);

    return (
        <View style={styles.graphContainer}>
            <ScrollView horizontal style={{ position: 'absolute', }}>
                <BarChart
                    data={data}
                    width={graphWidth}
                    height={width * .6111}
                    chartConfig={chartConfig}
                    withVerticalLabels={true}
                    withHorizontalLabels={false}
                    showValuesOnTopOfBars
                    showBarTops={false}
                    withInnerLines={false}
                    fromZero
                    style={{ paddingRight: 0, }}
                />
            </ScrollView>
            {showAverage &&
                <View style={styles.avgContainer}>
                    <View style={styles.greenBlock} />
                    <Text style={styles.fs12ppMedGreen}>Avg.{trackerType}: </Text>
                    <Text style={styles.fs12ppMed222}>{averageValue}</Text>
                </View>}
            <View style={{ height: width * .5 }}>
                {showAverage && <IndicatorLine maxDataValue={maxVal} value={averageValue} color={colors.green} />}
                {!showAverage && trackersDataItems && trackersDataItems.map((value, index) => (
                    <IndicatorLine maxDataValue={maxDataValue} key={index} value={value?.value} color={value?.color} />
                ))}
            </View>
            {showXAxis && <View style={styles.xAxis} />}
            {showYAxis && <View style={styles.yAxis} />}
        </View>
    )
}

const styles = StyleSheet.create({
    avgContainer: {
        flexDirection: 'row',
        alignItems: 'center',
        position: 'absolute',
        left: 6,
        top: -10
    },
    dashedLineStyles: {
        position: 'absolute',
        left: 0,
        right: 0,
    },
    fs12ppMed222: {
        fontSize: 12,
        fontFamily: fonts.PoppinsMedium,
        fontWeight: '500',
        color: colors.mainBlack
    },
    fs12ppMedGreen: {
        fontSize: 12,
        fontFamily: fonts.PoppinsMedium,
        fontWeight: '500',
        color: colors.green
    },
    graphContainer: {
        width: '100%',
        marginVertical: 36,
        position: 'relative',
    },
    greenBlock: {
        width: 4,
        height: 4,
        backgroundColor: colors.green,
        marginRight: 4
    },
    xAxis: {
        bottom: 0,
        width: '100%',
        height: 1,
        backgroundColor: 'rgba(0,0,0,.2)',
    },
    yAxis: {
        position: 'absolute',
        bottom: 0,
        left: 0,
        width: 1,
        height: '100%',
        backgroundColor: 'rgba(0,0,0,.2)',
    }
})
Leave a Comment