Home Manual Reference Source

src/screens/subscreens/resources/Graphs.jsx

import React, { useEffect, useState } from "react";
import { Dimensions, View, StyleSheet, Text, ScrollView, TouchableOpacity, StatusBar } from "react-native";
import { PieChart, BarChart, LineChart } from "react-native-chart-kit";
import FlashMessage, { showMessage } from "react-native-flash-message";
import { Ionicons } from '@expo/vector-icons';

import { useLoading } from "../../../Context";


const screenWidth = Dimensions.get("window").width;
const statusBarHeight = StatusBar.currentHeight ? StatusBar.currentHeight + 5 : 64;


export default function Graphs({ route, navigation }) {

    const { showLoading, hideLoading } = useLoading();

    const [moneyFlow, setMoneyFlow] = useState([]);
    const [incomeData, setIncomeData] = useState(null);
    const [expensesData, setExpensesData] = useState(null);

    useEffect(() => {

        showLoading();
        let dt = route.params.allData;

        //money flow
        let newFlow = [];
        if (dt.moneyFlow) {
            dt.moneyFlow.forEach(element => {
                newFlow.push({
                    name: element.name === "expenses" ? "Gastos" : "Receitas",
                    value: parseFloat(element.value),
                    color: element.name === "expenses" ? '#990000' : "#008060"
                })
            });
        }
        setMoneyFlow(newFlow);

        //income
        let incomes1 = dt.incomes;
        let newIncomes = {
            labels: [],
            datasets: [
                {
                    data: []
                }
            ]
        };
        if (incomes1) {
            incomes1.forEach(element => {
                newIncomes.labels.push(element.description);
                newIncomes.datasets[0].data.push(parseFloat(element.value));
            });
            setIncomeData(newIncomes);
        }

        //expenses
        let expenses1 = dt.expenses;
        let newExpenses = {
            labels: [],
            datasets: [
                {
                    data: []
                }
            ]
        };
        if (expenses1) {
            expenses1.forEach(element => {
                newExpenses.labels.push(element.description);
                newExpenses.datasets[0].data.push(parseFloat(element.value));
            });
            setExpensesData(newExpenses);
        }

        hideLoading();
    }, [])


    const chartConfig = {
        backgroundGradientFrom: "#fff",
        backgroundGradientFromOpacity: 0,
        backgroundGradientTo: "#fff",
        backgroundGradientToOpacity: 0,
        strokeWidth: 1,
        barPercentage: 0.5,
    };

    const lineChartConfig = {
        ...chartConfig,
        color: (opacity = 1) => `rgba(139, 16, 0, ${opacity})`
    }

    const barChartConfig = {
        ...chartConfig,
        color: (opacity = 1) => `rgba(0, 139, 93, ${opacity})`
    };


    return (
        <View style={{ marginTop: statusBarHeight, height: '100%' }}>
            <TouchableOpacity style={styles.back} onPress={() => { navigation.navigate("Home") }}>
                <Ionicons name="home" size={18} color="darkblue" />
            </TouchableOpacity>
            <Text style={[styles.title, { marginTop: 8, paddingHorizontal: 8 }]}>Minhas Finanças</Text>

            <ScrollView style={{ marginBottom: statusBarHeight + 20 }}>

                <View style={styles.graphGroup}>
                    <Text style={styles.graphTitle}>Gastos X Receitas</Text>
                    {moneyFlow ?
                        <PieChart
                            data={moneyFlow}
                            width={screenWidth - 20}
                            height={220}
                            chartConfig={{
                                ...chartConfig,
                                color: () => `rgba(0, 0, 139, 1)`
                            }}
                            accessor={"value"}
                            backgroundColor={"transparent"}
                        />
                        : <Text style={{ margin: 20 }}>Sem dados</Text>
                    }
                </View>

                <View style={styles.graphGroup}>
                    <Text style={styles.graphTitle}>Receitas</Text>
                    {incomeData ?
                        <BarChart
                            width={screenWidth}
                            height={300}
                            data={incomeData}
                            yAxisLabel="R$"
                            yLabelsOffset={0}
                            chartConfig={barChartConfig}
                            fromZero={true}
                        />
                        : <Text style={{ margin: 20 }}>Sem dados</Text>
                    }
                </View>

                <View style={styles.graphGroup}>
                    <Text style={styles.graphTitle}>Gastos</Text>
                    <FlashMessage duration={5000} />
                    {expensesData ?
                        <LineChart
                            bezier
                            width={screenWidth - 20}
                            height={300}
                            data={expensesData}
                            yAxisLabel="R$"
                            yAxisSuffix=""
                            verticalLabelRotation={20}
                            chartConfig={lineChartConfig}
                            fromZero={true}
                            onDataPointClick={({ value, index, getColor }) => {
                                showMessage({
                                    message: `R$ ${value}`,
                                    description: `${expensesData.labels[index]}`,
                                    backgroundColor: getColor(.5)
                                })
                            }
                            }
                        />
                        : <Text style={{ margin: 20 }}>Sem dados</Text>
                    }
                </View>
            </ScrollView>
        </View>
    )
}


const styles = StyleSheet.create({
    graphTitle: {
        fontSize: 18,
        fontWeight: 'bold',
        marginBottom: 16,
        textAlign: 'center'
    },
    graph: {
        fontSize: 16,
        textAlign: 'center'
    },
    graphGroup: {
        borderWidth: 1,
        borderColor: 'rgba(0, 0, 139,.2)',
        margin: 10,
        padding: 5
    },
    back: {
        marginHorizontal: 10,
        marginVertical: 8,
        position: 'absolute',
        top: 6,
        zIndex: 99,
        borderRadius: 100,
        borderWidth: 2,
        padding: 5,
        borderColor: 'darkblue'
    },
    title: {
        fontSize: 28,
        fontWeight: "bold",
        textAlign: "center"
    },
})