React-Nenable-Chart-kit error when changing the date object

Asked

Viewed 36 times

1

I’m using the React-Native-Chart-kit library to render some graphics in my app. The basic structure of my code is as follows:;

<LineChart
   data={data}
   width={Dimensions.get("window").width}
   height={220}
   chartConfig={{
       backgroundColor: "#ffffff",
       useShadowColorFromDataset: true,
       propsForBackgroundLines: {
            strokeWidth:"1",
            stroke: "#dcdcdc",
            strokeDasharray:"0" 
       },
       backgroundGradientFrom: "#ffffff",
       backgroundGradientTo: "#ffffff",
       decimalPlaces: 0,
       paddingRight: 0,
       paddingTop: 0,
       color: (opacity = 1) => `rgba(0,0,0,0)`,
       labelColor: (opacity = 1) => `rgba(0, 0, 0, ${opacity})`,
   }}
   style={{
       marginLeft: -(((Dimensions.get("window").width -60) * 10) / 100)
   }} 
   bezier
/>

The date attribute is where the object goes with the data of the graph, start it with null but it has not yet been rendered on the screen, because I have a condition where if Data is equal to null it is not rendered, after taking the information on the back-end and build an object to set the new Data, when setting this new value the React-Native-Chart-kit returns me the following error.

TypeError: Cannot read property 'reduce' of undefined
This error is located at:

I believe the attribute is missing decorator but I found nothing related to this attribute and how to use it.

Parent component.

mport React, { useEffect, useState } from 'react';
import { Text, View, SafeAreaView, StyleSheet, ScrollView, Dimensions, TouchableOpacity, TouchableHighlight } from 'react-native';
import MainStyle from '../content/css/Main.styles';
import Icon from 'react-native-vector-icons/Ionicons';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { RFValue } from "react-native-responsive-fontsize";
import LinearGradient from 'react-native-linear-gradient';
import ChartMenuAcessoComponent from './Utils/components/Chart-menu-acesso/Chart-menu-acesso.component';
import Api from '../Api';

const sizePercent = (size=Number(0), percent) => {
    return (percent * size ) / 100;
}

//esse é um exemplo de como é o objeto data
// {
//     labels: ["Seg", "Ter", "Qua", "Qui", "Sex", "Sab"],
//     datasets: [
//         { 
//             data: [ 8,6,4,2,0,10 ], 
//             color: (opacity = 1) => "#7bedeb", 
//         },
//         {
//             data: [10,13,15,20,56,3],
//             color: (opacity = 1) => "#00bab3",
//         }
//     ]
// }



export default props => {
    

    const [userInfos, setUserInfos] = useState(null);
    const [tempInfos, setTempInfos] = useState(null);
    const [dadosChart, setDadosChart] = useState(null);

    const coletInfos = async () => {
        setUserInfos(JSON.parse(await AsyncStorage.getItem("__Verifica_usuario")));
        setTempInfos(JSON.parse(await AsyncStorage.getItem("__Verifica_Temp_Acesso")));
    }

    const generateName = () => {
        return  (
            <Text style={[MainStyle.__TextBold,style.textUser]}>{userInfos.nome.split(' ').length > 1 ? `${userInfos.nome.split(' ')[0][0]}${userInfos.nome.split(' ')[1][0]}` : userInfos.nome[0]}</Text>
        )
    }

    const getDadosChart = async () => {
        let response = await Api.getAndPostRequestJSON('v1/relatorio/acessos-ultimos-dias', null, "GET");
        if(response.eu && response.outros){
            let data = {
                labels: generateLabels(response.eu),
                datasets: generateDatasets(response.eu, response.outros)
            };
            setDadosChart(data);
        }
    }

    const generateLabels = labels => {
        let l = [];
        
        labels.forEach((v) => {
            l.push(String(v.periodo));
        });
       
        return l;
    }

    const generateDatasets = (e,o) => {
        let eu = {
            data: [],
            color:  (opacity = 1) => "#7bedeb",
        }

        let outros = {
            data: [],
            color:  (opacity = 1) => "#00bab3"
        }

        e.forEach( _ => {
            eu.data.push(_.quantidade);
        });

        o.forEach(_ => {
            outros.data.push(_.quantidade);
        });

        return [eu,outros]
    }

    useEffect(() => {
        coletInfos();
        getDadosChart();
    }, []);

    return (
        <SafeAreaView style={MainStyle.__Container}>
            <ScrollView style={MainStyle.__Container}>
                
                <View style={style.flexView}>
                    <View style={style.viewIcon}>
                        <Icon name="notifications" size={30} color="#8daac8" />
                    </View>
                    <View style={style.viewContentFlexView}>
                        
                        <View style={style.userBox}>
                            {userInfos == null ? false : generateName()}
                        </View>

                        <TouchableOpacity style={style.buttonSeta}>
                            <Icon name="chevron-down" size={30} color="#b4c2d5" />
                        </TouchableOpacity>

                        <View style={style.flexInfosUser}>
                            <Text style={[MainStyle.__TextNormal, style.textInfoDefault]}>{tempInfos !==  null ? tempInfos.empresa.nome_fantasia : false}</Text>
                            <Text style={[MainStyle.__TextBold, style.textInfoDefault, {fontSize: RFValue(17)}]}>{userInfos !== null ? userInfos.nome.split(" ")[0] : false}</Text>
                            <Text style={[MainStyle.__TextNormal, style.textInfoDefault]}>{userInfos !== null ? userInfos.papel_empresa : false}</Text>
                        </View>

                    </View>
                </View>
                
                <View style={style.separator}/>

                <View style={style.viewFlexCriarConteudo}>
                    <View style={style.viewFlexTitle}>
                        <Icon name="star" size={30} color="#b4c2d5"/>
                        <Text style={[MainStyle.__TextBold, style.textTitle]}>Atalho</Text>
                    </View>

                    <View style={style.viewButtonCriarConteudo}>
                        <View style={style.buttonView}>
                            <LinearGradient start={{x: 0, y: 0}} end={{x: 1, y: 0}} colors={['#00B2FE', '#00E294']} style={[MainStyle.__GradienteFlex, {borderRadius: 5}]}>
                                <View style={style.flexFullView}>
                                    <TouchableHighlight style={style.buttonConteudo}>
                                        <Text style={[MainStyle.__TextNormal, style.textButton]}>Criar conteúdo</Text>
                                    </TouchableHighlight>
                                    <TouchableHighlight style={style.buttonConteudoOption}>
                                        <Icon name="caret-down"  size={15} color="#ffffff" />
                                    </TouchableHighlight>
                                </View>
                            </LinearGradient>
                        </View>
                    </View>
                </View>

                <View style={style.separator}/>

                <View style={style.viewFlexChart}>
                    <View style={style.viewFlexTitle}>
                        <Icon name="shield-checkmark" size={30} color="#b4c2d5"/>
                        <Text style={[MainStyle.__TextBold, style.textTitle]}>Acessos à plataforma</Text>
                    </View>

                    <View style={style.viewChartFlex}>
                        {dadosChart == null ? false : (
                            <ChartMenuAcessoComponent props={props} dadosChart={dadosChart} />
                        )

                        }
                    </View>
                    
                </View>
            
            </ScrollView>                
        </SafeAreaView>
    )
}


const style = StyleSheet.create({
    flexView: {
        width: "100%",
        height: 130,
        flexDirection: "row",
        justifyContent: "space-between"
    },
    viewIcon: {
        flex: .4,
        flexDirection: "row",
        alignItems: 'center',
    },
    viewContentFlexView: {
        flex: 2,
        display: 'flex',
        position: 'relative',
        flexDirection: 'row',
        alignItems: 'center'
    },

    userBox: {
        width: sizePercent((Dimensions.get("window").width - 60) - 100, 25),
        height: sizePercent((Dimensions.get("window").width - 60) - 100, 25),
        borderRadius: sizePercent((Dimensions.get("window").width - 60) - 100, 30) / 2,
        backgroundColor: "#d5e6fa",
        justifyContent: 'center',
        alignItems: 'center',
    },

    textUser: {
        color: '#2C7BE5',
        fontSize: RFValue(22),
    },

    buttonSeta: {
        width: 30,
        height: 30,
        marginLeft: 10,
        justifyContent: 'center',
        alignItems: 'center',
    },

    textInfoDefault: {
        color: '#97a9c6',
        fontSize: RFValue(15),
    },

    flexInfosUser: {
        flex: 1,
        height: "100%",
        justifyContent: 'center',
        alignItems: 'flex-start',
        marginLeft: 15
    },

    separator: {
        width: "100%",
        height: 2,
        backgroundColor: "#eff2f6",
    },

    viewFlexCriarConteudo: {
        width: "100%",
        marginTop: 5,
        height: 130,
        justifyContent: 'center',
    },

    viewFlexTitle: {
        width: "100%",
        height: 30,
        flexDirection: "row",
        alignItems: 'center',

    },

    textTitle: {
        color: '#97a9c6',
        fontSize: RFValue(20),
        marginLeft: 10,
    },

    viewButtonCriarConteudo: {
        width:"100%",
        height: 70,
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center',
    },

    buttonView: {
        width: '50%',
        height: 41,
    },

    flexFullView: {
        flex: 1,
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center'
    },
    
    buttonConteudo: {
        flex: 1,
        height: 41,
        justifyContent: 'center',
        alignItems: 'center',
    },

    buttonConteudoOption: {
        flex: .3,
        borderLeftColor: "#dbdbdb", //#01d69f
        borderLeftWidth: 1,
        height: 41,
        justifyContent: 'center',
        alignItems: 'center',
    },

    textButton: {
        color: "#ffffff",
        fontSize: RFValue(16)
    },

    viewFlexChart: {
        width: "100%",
        marginTop: 20,
        justifyContent: 'center',
    },

    viewChartFlex: {
        width: "100%",
        alignItems: 'center',
        marginTop: 20,
    }
});

This is the son Component.

import React, {useState , useEffect} from 'react';
import { StyleSheet, View, Text,Dimensions } from 'react-native';
import { RFValue } from 'react-native-responsive-fontsize';
import MainStyles from '../../../../content/css/Main.styles';
import { LineChart } from "react-native-chart-kit";


export default (props, dadosChart) => {

    const [data, setData] = useState({
        labels: [""],
        datasets: [
            {data: [0], color: (opacity) => "#00bab3"}
        ],
    });

    useEffect(() => {
    
        setData(dadosChart);
    }, []);


    return (
        <View style={style.fullContainer}>
            <View style={style.headerChart}>
                <View style={style.labelView}>
                    <View  style={[style.circleBox, {backgroundColor: "#00bab3"}]}/>
                    <Text style={[MainStyles.__TextLight, style.textLabel]}>Eu</Text>
                </View>
                <View style={style.labelView}>
                    <View  style={[style.circleBox, {backgroundColor: "#7bedeb"}]}/>
                    <Text style={[MainStyles.__TextLight, style.textLabel]}>Outros</Text>
                </View>
            </View>

            <View style={style.ViewGrafico}>

                <LineChart
                    data={data}
                    width={Dimensions.get("window").width}
                    height={220}
                    chartConfig={{
                        backgroundColor: "#ffffff",
                        useShadowColorFromDataset: true,
                        propsForBackgroundLines: {
                            strokeWidth:"1",
                            stroke: "#dcdcdc",
                            strokeDasharray:"0" 
                        },
                        backgroundGradientFrom: "#ffffff",
                        backgroundGradientTo: "#ffffff",
                        decimalPlaces: 0,
                        paddingRight: 0,
                        paddingTop: 0,

                        color: (opacity = 1) => `rgba(0,0,0,0)`,
                        labelColor: (opacity = 1) => `rgba(0, 0, 0, ${opacity})`,
                    }}

                    style={{
                        marginLeft: -(((Dimensions.get("window").width -60) * 10) / 100)
                    }} 
                    bezier
                 />
            </View>


        </View>
    )
}


const style = StyleSheet.create({

    fullContainer: {
        width: '100%',
    },

    headerChart: {
        width: '100%',
        height: 30,
        flexDirection: 'row',
        justifyContent: 'center',
    },

    labelView: {
        flexDirection: 'row',
        alignItems: 'center',
        marginHorizontal: 15,
    },

    circleBox: {
        width: 10,
        height: 10,
        borderRadius: 5,
        marginRight: 10
    },

    textLabel: {
        fontSize: RFValue(17),
        color: "#4e5a6b"
    },

    ViewGrafico: {
        width: '100%',
        marginTop: 15,
    }
});

Reproduction of the error error

  • I edited the question, put the Components that are involved in this error!

  • Take a look at this Snack, I tried to reproduce the problem but I couldn’t. Try to create a [mcve] in a Snack.

  • Good morning, I edited the code there at the expo reproducing the problem. error

  • In the archive Chart.js write export default ({props, dadosChart}), amid {}. That’s the problem... You’re passing the props props and dadosChart, everything comes within a single object in its component.

  • Our guy kkkk what a silly mistake, I was so hooked on the developer that I didn’t even notice that kkkkk Thank you!

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.