In my ReactJS application i need to display data in Graphs and i'm using chart-js-2 library. In the dashboard i've implemented a Doughnut chart and Bar chart. The graphs are initially populated using useEffect, but the data contained can be filtered by year and by type of tax. Specifically, on the donut chart, when filter by reference year, even if the data is retrieved correctly, the chart does not update. If I then filter again, the graph updates, but with the data of the previous filter, falling behind by one event.
For example: Initially I show data for all years, filter for a specific year (ex: 2022) and the graph does not change. Then filter again by year (Ex: 2021), the filter indicates 2021 but the graph is updated with the data relating to the filter year = 2022.
Do you have any suggestions or advice? I'm fairly new to React, am I doing something wrong?
-my Code:
import React, { useEffect, useState } from "react";
import Grid from "@material-ui/core/Grid";
import DashCard from "./DashboardCard" // eliminabile
import HomeDoughChart from '../charts_js/HomeDoughChart'
import tableIcons from '../templates/TableIcons';
import HomeBarChart from "../charts_js/HomeBarChart";
import MaterialTable from "material-table";
import {
getDashboard_Data,
getDashboard_Data_byYear,
getDashboard_TributeFiler,
getDashboard_YearFiler,
getDashboard_Data_byYear_andTribute,
getDashboard_Contribuenti_byYear_andTribute,
getTableData
} from "../../repo/dashboardRepo";
import { Card, CardContent, CardHeader } from "@material-ui/core";
import { SettingsBackupRestoreOutlined } from "@material-ui/icons";
const DashboardContent = () => {
const [chart, setChart] = useState([])
const [barchart, setBarChart] = useState([])
const [barchart1, setBarChart1] = useState([])
const [barchart2, setBarChart2] = useState([])
const [barchart3, setBarChart3] = useState([])
const [trib, setTributi] = useState([])
const [year, setAnni] = useState([])
const [dashboardfilter, setDashboardFilter] = useState({ year: "", tributo: "" });
const [barTribute, setBarTribute] = useState([]);
const [graphData, setGraphData] = useState([]);
function handleYearChange(evt) {
setDashboardFilter({ year: evt.target.value, tributo: dashboardfilter.tributo });
const yf = async () => {
const res = (dashboardfilter.year !== "") ? await getDashboard_Data_byYear_andTribute(dashboardfilter.year, dashboardfilter.tributo) : await getDashboard_Data();
//const res1 = (dashboardfilter.year !== "") ? await getDashboard_Contribuenti_byYear_andTribute(dashboardfilter.year, dashboardfilter.tributo) : await getDashboard_Contribuenti_byYear_andTribute();
setChart(res.data.data);
}
yf();
}
function handleTributeChange(evt) {
setDashboardFilter({ year: dashboardfilter.year, tributo: evt.target.value });
const yf = async () => {
const res = (dashboardfilter.tributo !== "") ? await getDashboard_Data_byYear_andTribute(dashboardfilter.year, dashboardfilter.tributo) : await getDashboard_Data();
//const res1 = (dashboardfilter.year !== "") ? await getDashboard_Contribuenti_byYear_andTribute(dashboardfilter.year, dashboardfilter.tributo) : await getDashboard_Contribuenti_byYear_andTribute();
setChart(res.data.data);
}
yf();
}
function handleBarTributeChange(evt) {
setBarTribute({ b_trib: evt.target.value });
const tf = async () => {
const res1 = (barTribute.b_trib === "Tutti") ? await getDashboard_Data_byYear(2022) : await getDashboard_Data_byYear_andTribute(2022, barTribute.b_trib);
const res2 = (barTribute.b_trib === "Tutti") ? await getDashboard_Data_byYear(2021) : await getDashboard_Data_byYear_andTribute(2021, barTribute.b_trib);
const res3 = (barTribute.b_trib === "Tutti") ? await getDashboard_Data_byYear(2020) : await getDashboard_Data_byYear_andTribute(2020, barTribute.b_trib);
const res4 = (barTribute.b_trib === "Tutti") ? await getDashboard_Data_byYear(2019) : await getDashboard_Data_byYear_andTribute(2019, barTribute.b_trib);
setBarChart(res1.data.data);
setBarChart1(res2.data.data);
setBarChart2(res3.data.data);
setBarChart3(res4.data.data);
}
tf();
}
useEffect(() => {
const a = async () => {
if (dashboardfilter.year === "" && dashboardfilter.tributo === "") {
const res = await getDashboard_Data();
//const res1 = await getDashboard_Contribuenti_byYear_andTribute();
setChart(res.data.data);
}
}
a()
}, [])
useEffect(() => {
var today = new Date();
const year = today.getFullYear()
const b = async () => {
const res1 = await getDashboard_Data_byYear(year);
const res2 = await getDashboard_Data_byYear(year-1);
const res3 = await getDashboard_Data_byYear(year-2);
const res4 = await getDashboard_Data_byYear(year-3);
setBarChart(res1.data.data);
setBarChart1(res2.data.data);
setBarChart2(res3.data.data);
setBarChart3(res4.data.data);
}
b()
}, [])
useEffect(() => {
const c = async () => {
const res2 = await getDashboard_TributeFiler();
const res3 = await getDashboard_YearFiler();
setTributi(res2.data.data);
setAnni(res3.data.data);
}
c();
}, [])
useEffect(() => {
const t = async () => {
const res = await getTableData();
setGraphData(res.data.data);
}
t();
}, []);
return (
<div>
<div style={{ display: "flex", flex: "1", flexDirection: "row", alignItems: "stretch", justifyContent: 'space-evenly' }}>
<Card style={{ marginLeft: 30, responsive: true, marginTop: 30, marginRight: 30, flex: 0.85 }}>
<CardHeader title={"Consuntivo totale dei pagamenti"} style={{ textAlign: "left" }} />
<CardContent>
<Grid container direction="row" style={{ marginTop: '10px', marginLeft: '20px', marginBottom: '60px' }} >
<div>
<form justifyContent="left">
<label>Filtra per anno di riferimento </label>
<select name="year" value={dashboardfilter.year} onChange={handleYearChange}>
<option value="">Tutti gli anni</option>
{year.map(y => {
return (
<option key={y.anno} value={y.anno}>
{y.anno}
</option>
)
})}
</select>
<br />
<label>Filtra per tributo </label>
<select name="tributo" value={dashboardfilter.tributo} onChange={handleTributeChange}>
<option value="">Tutti i tributi</option>
{trib.map(tributi => {
return (
<option key={tributi.descrizioneServizio} value={tributi.descrizioneServizio}>
{tributi.descrizioneServizio}
</option>
)
})}
</select>
</form>
<br />
<h3>Totale da riscuotere: {Intl.NumberFormat('it-IT', { style: 'currency', currency: 'EUR' }).format(chart.totaleDaPagare)} </h3>
<HomeDoughChart chart={chart} />
</div>
</Grid>
</CardContent>
</Card>
<Card style={{ marginLeft: 30, responsive: true, marginTop: 30, marginRight: 30, flex: 1 }}>
<CardHeader title={"Consuntivo dei pagamenti per anno"} style={{ textAlign: "left" }} />
<CardContent >
{/* qui dobbiamo inserire i filtri, il titolo del grafico e il valore del filtro per tributo del grafico a istogramma */}
<Grid container direction="row" justify="left" alignItems="center" style={{ marginTop: '10px', marginLeft: '20px', marginBottom: '60px' }}>
<div>
<form>
<label>Filtra per tributo </label>
<select name="tributoBar" value={barTribute.b_trib} onChange={handleBarTributeChange}>
<option value="Tutti">Tutti i tributi</option>
{trib.map(tributi => {
return (
<option key={tributi.descrizioneServizio} value={tributi.descrizioneServizio}>
{tributi.descrizioneServizio}
</option>
)
})}
</select>
</form>
<br />
<h3>Tributo di riferimento: {barTribute.b_trib}</h3>
</div>
<HomeBarChart barchart={barchart} barchart1={barchart1} barchart2={barchart2} barchart3={barchart3} />
</Grid>
</CardContent>
</Card>
</div>
<div style={{ display: "flex", flex: "1", flexDirection: "row", alignItems: "center", responsive: true }}>
<Grid container spacing={1} style={{ marginLeft: 30, marginTop: 30, marginRight: 30, flex: 1 }}>
<MaterialTable
title="Consuntivo posizioni"
options={{
sorting: true,
actionsColumnIndex: -1,
pageSize: 5,
toolbar: true,
paging: false,
responsive: true,
exportButton: true,
exportAllData: true,
exportFileName: "ConsuntivoPosizioni",
filtering: false,
grouping: true,
}}
icons={tableIcons}
columns={[
{ title: 'Tributo', field: 'tributo' },
{ title: 'Anno Riferimento', field: 'docAnnoRif', defaultGroupSort: "desc"},
{ title: '#Contribuenti', field: 'totcontribuenti' },
{ title: '#Documenti', field: 'atti', type: 'numeric' },
{ title: 'Importo pagamento', field: 'totaleDovuto',type: "currency", currencySetting:{ currencyCode:'EUR', minimumFractionDigits:2, maximumFractionDigits:2} },
{ title: 'Importo pagato', field: 'totaleVersato',type: "currency", currencySetting:{ currencyCode:'EUR', minimumFractionDigits:2, maximumFractionDigits:2} },
{ title: 'Importo restante', field: 'restante', type: "currency", render: rowData => (Intl.NumberFormat('it-IT', { style: 'currency', currency: 'EUR' }).format(rowData.totaleDovuto-rowData.totaleVersato)) },
]}
data={(dashboardfilter.year === "" && dashboardfilter.tributo === "") ? graphData : graphData.filter(element => element.docAnnoRif === dashboardfilter.year)}
/>
</Grid>
</div>
</div>
)
}
export default DashboardContent;