diff --git a/src/components/Charts/CasesAndDeaths/index.js b/src/components/Charts/CasesAndDeaths/index.js new file mode 100644 index 0000000..6cde505 --- /dev/null +++ b/src/components/Charts/CasesAndDeaths/index.js @@ -0,0 +1,176 @@ +import React, { useEffect, useState } from 'react'; +import { Style } from '../styles'; +import moment from 'moment'; + +import api from '../api'; + +import {Line} from 'react-chartjs-2'; +import Chart from 'chart.js'; + +const CasesAndDeaths = (props) => { + const [responseAPI, setResponseAPI] = useState([]); + + const [lastDayCasesAndDeaths, setLastDayCasesAndDeaths] = useState(null); + const [lastDayFormatedCasesAndDeaths, setLastDayFormatedCasesAndDeaths] = useState(null); + + const [labelsCasesAndDeaths, setLabelsCasesAndDeaths] = useState([]); + const [valuesDeaths, setValuesDeaths] = useState([]); + const [valuesCases, setValuesCases] = useState([]); + + const [graphicCasesAndDeaths, setGraphicCasesAndDeaths] = useState(null); + + useEffect(() => { + getLastDay(); + }, []); + + useEffect(() => { + + if(!lastDayCasesAndDeaths || !lastDayFormatedCasesAndDeaths){ + return + } + + const maxDays = 20; + + const daysYMD = []; + const daysMD = []; + + for(let index = 0; index <= maxDays; index++){ + //pega o "i" dia antes do último retornado pela api + let day = moment(lastDayCasesAndDeaths).subtract(index, 'days'); + //coloca no array o dia no formato da api y-m-d + daysYMD.push(moment(day).format('YYYY-MM-DD')); + //coloca no array o dia no formato dd/m + daysMD.push(moment(day._d).format('l').split('/').reverse().slice(1).join('/')); + } + + const newValuesDeath = daysYMD.map(day => { + let totalDeaths = responseAPI.reduce((currentTotal, item) => { + if(item.date == day){ + return currentTotal + item.totaldeaths + } + return currentTotal + }, 0); + return totalDeaths; + }); + + const newValuesCases = daysYMD.map(day => { + let totalCases = responseAPI.reduce((currentTotal, item) => { + if(item.date == day){ + return currentTotal + item.totalcases + } + return currentTotal + }, 0); + + return totalCases; + }); + + setLabelsCasesAndDeaths(daysMD); + setValuesDeaths(newValuesDeath); + setValuesCases(newValuesCases); + + }, [lastDayCasesAndDeaths, lastDayFormatedCasesAndDeaths]); + + useEffect(() => { + if(!labelsCasesAndDeaths.length > 0 || !valuesDeaths.length > 0 || !valuesCases.length > 0){ + return + } + + setGraphicCasesAndDeaths( + { + labels: labelsCasesAndDeaths.reverse(), + datasets: [ + { + fill: false, + lineTension: 0.1, + backgroundColor: '#BDBDBD', + borderColor: '#BDBDBD', + borderCapStyle: 'round', + borderJoinStyle: 'miter', + pointBorderColor: '#BDBDBD', + pointBackgroundColor: '#BDBDBD', + borderWidth: 4, + pointBorderWidth: 2, + pointHoverRadius: 5, + pointRadius: 0, + pointHitRadius: 10, + data: valuesDeaths.reverse(), + }, + { + fill: false, + lineTension: 0.1, + backgroundColor: '#EF5350', + borderColor: '#EF5350', + borderCapStyle: 'round', + borderJoinStyle: 'miter', + pointBorderColor: '#EF5350', + pointBackgroundColor: '#EF5350', + borderWidth: 4, + pointBorderWidth: 2, + pointHoverRadius: 5, + pointRadius: 0, + pointHitRadius: 10, + data: valuesCases.reverse(), + } + ] + } + ); + }, [labelsCasesAndDeaths, valuesDeaths, valuesCases]); + + async function getLastDay(){ + const response = await api.get(`https://api.covidzero.com.br/data_api/v1/cases/datasus`); + + const resultsData = response.data.sus_list; + + setResponseAPI(resultsData); + + const lastItem = resultsData[resultsData.length - 1]; + + const lastItemFormated = moment(lastItem.date).format('l').split('/').reverse().slice(1).join('/'); + + setLastDayCasesAndDeaths(lastItem.date); + setLastDayFormatedCasesAndDeaths(lastItemFormated); + }; + + + return( + + {props.title} + + {graphicCasesAndDeaths && } + + + + ); + +} + +export default CasesAndDeaths; \ No newline at end of file diff --git a/src/components/Charts/DailyDeaths/index.js b/src/components/Charts/DailyDeaths/index.js new file mode 100644 index 0000000..8648bd0 --- /dev/null +++ b/src/components/Charts/DailyDeaths/index.js @@ -0,0 +1,143 @@ +import React, { useEffect, useState } from 'react'; +import { Style } from '../styles'; +import moment from 'moment'; + +import api from '../api'; + +import {Bar} from 'react-chartjs-2'; +import Chart from 'chart.js'; + +const DailyDeaths = (props) => { + const [responseAPI, setResponseAPI] = useState([]); + + const [lastDay, setLastDay] = useState(null); + const [lastDayFormated, setLastDayFormated] = useState(null); + + const [labels, setLabels] = useState([]); + const [values, setValues] = useState([]); + + const [graphic, setGraphic] = useState(null); + + + useEffect(() => { + getLastDay(); + }, []); + + useEffect(() => { + + if(!lastDay || !lastDayFormated){ + return + } + + const maxDays = 20; + + const daysYMD = []; + const daysMD = []; + + for(let index = 0; index <= maxDays; index++){ + //pega o "i" dia antes do último retornado pela api + let day = moment(lastDay).subtract(index, 'days'); + //coloca no array o dia no formato da api y-m-d + daysYMD.push(moment(day).format('YYYY-MM-DD')); + + //coloca no array o dia no formato dd/m + daysMD.push(moment(day._d).format('l').split('/').reverse().slice(1).join('/')); + + } + + const newValues = daysYMD.map(day => { + let totalNewDeaths = responseAPI.reduce((currentTotal, item) => { + if(item.date == day){ + return currentTotal + item.newdeaths + } + return currentTotal + + }, 0); + + return totalNewDeaths; + }); + + setLabels(daysMD); + setValues(newValues); + + }, [lastDay, lastDayFormated]); + + useEffect(() => { + if(!labels.length > 0 || !values.length > 0){ + return + } + + + setGraphic( + { + labels: labels.reverse(), + datasets: [ + { + backgroundColor: '#BDBDBD', + hoverbackgroundColor: '#BDBDBD', + data: values.reverse(), + } + ] + } + ); + }, [labels, values]); + + async function getLastDay(){ + const response = await api.get(); + + const resultsData = response.data.sus_list; + + setResponseAPI(resultsData); + + const lastItem = resultsData[resultsData.length - 1]; + + const lastItemFormated = moment(lastItem.date).format('l').split('/').reverse().slice(1).join('/'); + + setLastDay(lastItem.date); + setLastDayFormated(lastItemFormated); + }; + + + return( + + {props.title} + + { graphic && } + + + + ); + +} + +export default DailyDeaths; \ No newline at end of file diff --git a/src/components/Charts/NewCasesPrediction/index.js b/src/components/Charts/NewCasesPrediction/index.js new file mode 100644 index 0000000..594e0dc --- /dev/null +++ b/src/components/Charts/NewCasesPrediction/index.js @@ -0,0 +1,142 @@ +import React, { useEffect, useState } from 'react'; +import { Style } from '../styles'; +import moment from 'moment'; + +import apiPrediction from '../predictionService'; + +import {Bar} from 'react-chartjs-2'; +import Chart from 'chart.js'; + +const NewCasesPrediction = (props) => { + const [responseAPI, setResponseAPI] = useState([]); + + const [lastDayPrediction, setLastDayPrediction] = useState(null); + const [lastDayPredictionFormated, setLastPredictionDayFormated] = useState(null); + + const [labels, setLabels] = useState([]); + const [values, setValues] = useState([]); + + const [graphic, setGraphic] = useState(null); + + + useEffect(() => { + getLastDay(); + }, []); + + useEffect(() => { + + if(!lastDayPrediction || !lastDayPredictionFormated){ + return + } + + const maxDays = 7; + + const daysYMD = []; + const daysMD = []; + + for(let index = 0; index <= maxDays; index++){ + //pega o "i" dia antes do último retornado pela api + let day = moment(lastDayPrediction).subtract(index, 'days'); + //coloca no array o dia no formato da api y-m-d + daysYMD.push(moment(day).format('YYYY-MM-DD')); + + //coloca no array o dia no formato dd/m + daysMD.push(moment(day._d).format('l').split('/').reverse().slice(1).join('/')); + + } + + const newValues = daysYMD.map(day => { + let totalNewCases = responseAPI.reduce((currentTotal, item) => { + if(item.date == day){ + + return currentTotal + item.predictcases + } + return currentTotal + + }, 0); + + return totalNewCases; + }); + + setLabels(daysMD); + setValues(newValues); + + }, [lastDayPrediction, lastDayPredictionFormated]); + + useEffect(() => { + if(!labels.length > 0 || !values.length > 0){ + return + } + + setGraphic( + { + labels: labels.reverse(), + datasets: [ + { + backgroundColor: '#FFCC00', + hoverbackgroundColor: '#FFCC00', + data: values.reverse(), + } + ] + } + ); + }, [labels, values]); + + async function getLastDay(){ + const response = await apiPrediction.get(); + console.log(response); + const resultsData = response.data; + setResponseAPI(resultsData); + + const lastItem = resultsData[resultsData.length - 1]; + + const lastItemFormated = moment(lastItem.date).format('l').split('/').reverse().slice(1).join('/'); + + setLastDayPrediction(lastItem.date); + setLastPredictionDayFormated(lastItemFormated); + }; + + + return( + + {props.title} + + { graphic && } + + + + ); + +} + +export default NewCasesPrediction; \ No newline at end of file diff --git a/src/components/Charts/TotalPredictionWeek/index.js b/src/components/Charts/TotalPredictionWeek/index.js new file mode 100644 index 0000000..8dec2ff --- /dev/null +++ b/src/components/Charts/TotalPredictionWeek/index.js @@ -0,0 +1,173 @@ +import React, { useEffect, useState } from 'react'; +import { Style } from '../styles'; +import moment from 'moment'; + +import apiPrediction from '../predictionService'; + +import {Line} from 'react-chartjs-2'; +import Chart from 'chart.js'; + +const TotalPredictionWeek = (props) => { + const [responseAPI, setResponseAPI] = useState([]); + + const [lastDayPrediction, setLastDayPrediction] = useState(null); + const [lastDayPredictionFormated, setLastPredictionDayFormated] = useState(null); + + const [labels, setLabels] = useState([]); + const [values, setValues] = useState([]); + + let valuesAccumulateds = []; + + const [graphic, setGraphic] = useState(null); + + + useEffect(() => { + getLastDay(); + valuesAccumulateds = []; + }, []); + + useEffect(() => { + + if(!lastDayPrediction || !lastDayPredictionFormated){ + return + } + + const maxDays = 7; + + const daysYMD = []; + const daysMD = []; + + for(let index = 0; index <= maxDays; index++){ + //pega o "i" dia antes do último retornado pela api + let day = moment(lastDayPrediction).subtract(index, 'days'); + //coloca no array o dia no formato da api y-m-d + daysYMD.push(moment(day).format('YYYY-MM-DD')); + + //coloca no array o dia no formato dd/m + daysMD.push(moment(day._d).format('l').split('/').reverse().slice(1).join('/')); + + } + + const newValues = daysYMD.map(day => { + let totalNewCases = responseAPI.reduce((currentTotal, item) => { + if(item.date == day){ + return currentTotal + item.predictcases + } + return currentTotal + + }, 0); + + return totalNewCases; + }); + + setLabels(daysMD); + setValues(newValues); + }, [lastDayPrediction, lastDayPredictionFormated]); + + useEffect(() => { + if(!labels.length > 0 || !values.length > 0){ + return + } + + setGraphic( + { + labels: labels.reverse(), + datasets: [ + { + fill: false, + lineTension: 0.1, + borderColor: '#FFCC00', + borderCapStyle: 'round', + borderJoinStyle: 'miter', + pointBorderColor: '#FFCC00', + pointBackgroundColor: '#FFCC00', + borderWidth: 4, + pointBorderWidth: 2, + pointHoverRadius: 5, + pointRadius: 0, + pointHitRadius: 10, + backgroundColor: '#FFCC00', + data: valuesAccumulateds, + } + ] + } + ); + getAccumulatedValues(); + }, [labels, values]); + + async function getLastDay(){ + const response = await apiPrediction.get(); + console.log(response); + const resultsData = response.data; + setResponseAPI(resultsData); + + const lastItem = resultsData[resultsData.length - 1]; + + const lastItemFormated = moment(lastItem.date).format('l').split('/').reverse().slice(1).join('/'); + + setLastDayPrediction(lastItem.date); + setLastPredictionDayFormated(lastItemFormated); + }; + + + function getAccumulatedValues(){ + let i = 0; + console.log("antes do while"); + while(i < values.length-1){ + + if(i == 0){ + console.log(valuesAccumulateds); + valuesAccumulateds.push(values[i]); + }else{ + valuesAccumulateds.push(values[i] + valuesAccumulateds[i - 1]); + console.log(valuesAccumulateds); + } + i++; + } + + return valuesAccumulateds; + } + + return( + + {props.title} + + { graphic && } + + + + ); + +} + +export default TotalPredictionWeek; \ No newline at end of file diff --git a/src/components/Charts/predictionService.js b/src/components/Charts/predictionService.js new file mode 100644 index 0000000..7bd6eb0 --- /dev/null +++ b/src/components/Charts/predictionService.js @@ -0,0 +1,7 @@ +import axios from 'axios'; + +const apiPrediction = axios.create({ + baseURL: 'https://api.covidzero.com.br/data_api/v1/cases/predict_cases' +}); + +export default apiPrediction; \ No newline at end of file diff --git a/src/components/index.js b/src/components/index.js index 785c2e2..7853449 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -17,6 +17,10 @@ import DailyCases from "./Charts/DailyCases"; import TotalCases from "./Charts/TotalCases"; import RegionCases from "./Charts/RegionCases"; import TotalDeaths from "./Charts/TotalDeaths"; +import DailyDeaths from "./Charts/DailyDeaths"; +import CasesAndDeaths from "./Charts/CasesAndDeaths"; +import NewCasesPrediction from "./Charts/NewCasesPrediction"; +import TotalPredictionWeek from "./Charts/TotalPredictionWeek"; import MapArea from "./MapArea"; import Marker from "./Marker"; export { @@ -38,6 +42,10 @@ export { TotalCases, RegionCases, TotalDeaths, + DailyDeaths, + CasesAndDeaths, + NewCasesPrediction, + TotalPredictionWeek, MapArea, Marker, MapBrazil diff --git a/src/pages/Brazil/index.js b/src/pages/Brazil/index.js index ca32991..10e992e 100644 --- a/src/pages/Brazil/index.js +++ b/src/pages/Brazil/index.js @@ -5,7 +5,7 @@ import ReactTooltip from "react-tooltip"; import * as Styled from "./styles.js"; -import { CardStats, DailyCases, TotalCases, RegionCases, TotalDeaths } from "~/components"; +import { CardStats, DailyCases, TotalCases, RegionCases, TotalDeaths, DailyDeaths, CasesAndDeaths, NewCasesPrediction, TotalPredictionWeek } from "~/components"; import { Header } from "~/components"; import { MapBrazil } from "~/components"; import { Chips } from "~/components"; @@ -95,11 +95,29 @@ const Brazil = () => { + + + + + + + + + + + + + + + + + +

Somos um projeto OpenSource. Para acesso ao nosso código fonte e fontes utilizadas, clique aqui.