LFFE-10 rdial bar with two types / making progress and making hook of fetching data for charts
This commit is contained in:
@@ -474,7 +474,11 @@
|
||||
"loan_progress": "درصد پیشرفت تسویه وام",
|
||||
"loan_distribution": "درصد توزیع وام ها در هر مرحله",
|
||||
"filter_as": "فیلتر های اعمال شده",
|
||||
"loan_details": "اطلاعات وام ها"
|
||||
"loan_details": "جزئیات وام ها",
|
||||
"cost_of_loan_refer_to_bank": "مبلغ وام های معرفی به بانک",
|
||||
"number_of_loan_refer_to_bank": "تعداد وام های معرفی به بانک",
|
||||
"cost_of_payed_loan": "مبلغ وام های پرداخت شده",
|
||||
"number_of_payed_loan": "تعداد وام های پرداخت شده"
|
||||
},
|
||||
"filters": {
|
||||
"provinces": "استان های",
|
||||
|
||||
@@ -3,6 +3,7 @@ import {useFormik} from "formik";
|
||||
import ProvinceFilter from "./ProvinceFilter";
|
||||
import YearFilter from "./YearFilter";
|
||||
import FilterAltIcon from '@mui/icons-material/FilterAlt';
|
||||
import EqualizerIcon from '@mui/icons-material/Equalizer';
|
||||
import {useTranslations} from "next-intl";
|
||||
import TroubleshootIcon from '@mui/icons-material/Troubleshoot';
|
||||
import moment from "jalali-moment";
|
||||
@@ -46,6 +47,7 @@ const Filter = ({title, filterItem, expanded}) => {
|
||||
<AccordionSummary>
|
||||
<Box sx={{width: "100%", display: "flex", alignItems: "center", justifyContent: "space-between"}}>
|
||||
<Box sx={{display: "flex", alignItems: "center", gap: 0.5}}>
|
||||
<EqualizerIcon sx={{color: "primary.main"}}/>
|
||||
<Typography sx={{fontWeight: 500, color: "primary.main"}}>{title}</Typography>
|
||||
<Typography variant="caption" sx={{fontWeight: 500}} color="error">
|
||||
{filteredText.province} {filteredText.year}
|
||||
|
||||
@@ -1,35 +1,33 @@
|
||||
import Chart from "@/core/components/Chart";
|
||||
import {calculateGradientColor} from "@/core/utils/gradientColorHandler";
|
||||
|
||||
const RadialBarChart = ({data}) => {
|
||||
const RadialBarSemiCircularChart = ({data, label}) => {
|
||||
const specialOption = {
|
||||
title: {
|
||||
text: undefined,
|
||||
},
|
||||
plotOptions: {
|
||||
radialBar: {
|
||||
startAngle: -90,
|
||||
endAngle: 90,
|
||||
startAngle: -110,
|
||||
endAngle: 110,
|
||||
track: {
|
||||
background: "#e7e7e7",
|
||||
strokeWidth: '90%',
|
||||
margin: 5, // margin is in pixels
|
||||
dropShadow: {
|
||||
enabled: true,
|
||||
top: 2,
|
||||
left: 0,
|
||||
color: '#999',
|
||||
opacity: 1,
|
||||
blur: 2
|
||||
}
|
||||
strokeWidth: '80%',
|
||||
},
|
||||
dataLabels: {
|
||||
name: {
|
||||
show: false
|
||||
fontSize: '20px',
|
||||
offsetY: 110,
|
||||
color: "#8c8c8c"
|
||||
},
|
||||
value: {
|
||||
offsetY: -2,
|
||||
fontSize: '22px'
|
||||
offsetY: 50,
|
||||
fontSize: '50px',
|
||||
fontWeight: 500,
|
||||
color: "#8c8c8c",
|
||||
formatter: function (val) {
|
||||
return val + "%";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,6 +35,7 @@ const RadialBarChart = ({data}) => {
|
||||
fill: {
|
||||
colors: calculateGradientColor(data)
|
||||
},
|
||||
labels: [label],
|
||||
};
|
||||
const series = [data]
|
||||
return (
|
||||
@@ -44,4 +43,4 @@ const RadialBarChart = ({data}) => {
|
||||
)
|
||||
};
|
||||
|
||||
export default RadialBarChart;
|
||||
export default RadialBarSemiCircularChart;
|
||||
@@ -0,0 +1,51 @@
|
||||
import Chart from "@/core/components/Chart";
|
||||
import {calculateGradientColor} from "@/core/utils/gradientColorHandler";
|
||||
import {useTranslations} from "next-intl";
|
||||
|
||||
const RadialBarStrokedChart = ({data, label}) => {
|
||||
const t = useTranslations();
|
||||
const specialOption = {
|
||||
title: {
|
||||
text: undefined,
|
||||
},
|
||||
plotOptions: {
|
||||
radialBar: {
|
||||
startAngle: -110,
|
||||
endAngle: 110,
|
||||
track: {
|
||||
background: "#e7e7e7",
|
||||
strokeWidth: '80%',
|
||||
},
|
||||
dataLabels: {
|
||||
name: {
|
||||
fontSize: '20px',
|
||||
offsetY: 110,
|
||||
color: "#8c8c8c"
|
||||
},
|
||||
value: {
|
||||
offsetY: 50,
|
||||
fontSize: '50px',
|
||||
fontWeight: 500,
|
||||
color: "#8c8c8c",
|
||||
formatter: function (val) {
|
||||
return val + "%";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
stroke: {
|
||||
dashArray: 4
|
||||
},
|
||||
fill: {
|
||||
colors: calculateGradientColor(data)
|
||||
},
|
||||
labels: [label],
|
||||
};
|
||||
const series = [data]
|
||||
return (
|
||||
<Chart chartId="LoanProgressBar" type="radialBar" specialOption={specialOption} series={series}/>
|
||||
)
|
||||
};
|
||||
|
||||
export default RadialBarStrokedChart;
|
||||
@@ -1,7 +1,9 @@
|
||||
import {Grid, Paper} from "@mui/material";
|
||||
import {useTranslations} from "next-intl";
|
||||
import Filter from "@/components/dashboard/reports/Filter";
|
||||
import RadialBarChart from "@/components/dashboard/reports/LoanDetails/RadialBarChart";
|
||||
import RadialBarSemiCircularChart from "@/components/dashboard/reports/LoanDetails/RadialBarSemiCircularChart";
|
||||
import RadialBarStrokedChart from "@/components/dashboard/reports/LoanDetails/RadialBarStrokedChart";
|
||||
|
||||
|
||||
const LoanDetails = () => {
|
||||
const t = useTranslations();
|
||||
@@ -13,15 +15,18 @@ const LoanDetails = () => {
|
||||
{type: "year", type_fa: "سال", multiple: false}
|
||||
]}
|
||||
/>
|
||||
<Grid container spacing={2} sx={{justifyContent: "space-between"}}>
|
||||
<Grid item xs={4} sx={{height: "300px"}}>
|
||||
<RadialBarChart data={90}/>
|
||||
<Grid container sx={{justifyContent: {xs: "center", md: "space-between"}}}>
|
||||
<Grid item xs={12} sm={10} md={5} sx={{aspectRatio: "1/0.75"}}>
|
||||
<RadialBarSemiCircularChart data={20} label={t("reports.cost_of_loan_refer_to_bank")}/>
|
||||
</Grid>
|
||||
<Grid item xs={4} sx={{height: "300px"}}>
|
||||
<RadialBarChart data={50}/>
|
||||
<Grid item xs={12} sm={10} md={5} sx={{aspectRatio: "1/0.75"}}>
|
||||
<RadialBarSemiCircularChart data={60} label={t("reports.number_of_loan_refer_to_bank")}/>
|
||||
</Grid>
|
||||
<Grid item xs={4} sx={{height: "300px"}}>
|
||||
<RadialBarChart data={10}/>
|
||||
<Grid item xs={12} sm={10} md={5} sx={{aspectRatio: "1/0.75"}}>
|
||||
<RadialBarSemiCircularChart data={95} label={t("reports.cost_of_payed_loan")}/>
|
||||
</Grid>
|
||||
<Grid item xs={12} sm={10} md={5} sx={{aspectRatio: "1/0.75"}}>
|
||||
<RadialBarStrokedChart data={15} label={t("reports.number_of_payed_loan")}/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Paper>
|
||||
|
||||
@@ -48,11 +48,11 @@ const LoanDistribution = () => {
|
||||
{type: "year", type_fa: "سال", multiple: false}
|
||||
]}
|
||||
/>
|
||||
<Grid container spacing={2} sx={{justifyContent: "space-between"}}>
|
||||
<Grid item xs={5} sx={{height: "300px"}}>
|
||||
<Grid container sx={{justifyContent: {xs: "center", md: "space-between"}}}>
|
||||
<Grid item xs={12} sm={10} md={5} sx={{aspectRatio: "1/0.75"}}>
|
||||
<PolarChart data={fakeData}/>
|
||||
</Grid>
|
||||
<Grid item xs={5} sx={{height: "300px"}}>
|
||||
<Grid item xs={12} sm={10} md={5} sx={{aspectRatio: "1/0.75"}}>
|
||||
<Pie data={fakeData}/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import Chart from "@/core/components/Chart";
|
||||
import {calculateGradientColor} from "@/core/utils/gradientColorHandler";
|
||||
import Chart from "@/core/components/Chart";
|
||||
|
||||
const BarChart = ({data}) => {
|
||||
const usableArray = data.map(({name, data, ...rest}) => ({
|
||||
x: name,
|
||||
y: data,
|
||||
...rest
|
||||
console.log(data)
|
||||
const usableArray = data.map(({province_name, percentage, ...rest}) => ({
|
||||
x: province_name,
|
||||
y: percentage,
|
||||
...rest,
|
||||
}));
|
||||
let colorArray = data.map(obj => calculateGradientColor(obj.data));
|
||||
let colorArray = data.map((obj) => calculateGradientColor(obj.percentage));
|
||||
const specialOption = {
|
||||
title: {
|
||||
text: undefined,
|
||||
@@ -29,19 +30,19 @@ const BarChart = ({data}) => {
|
||||
trim: false,
|
||||
style: {
|
||||
fontWeight: 600,
|
||||
fontSize: "11px",
|
||||
colors: '#7e7e7e'
|
||||
}
|
||||
}
|
||||
fontSize: '11px',
|
||||
colors: '#7e7e7e',
|
||||
},
|
||||
},
|
||||
},
|
||||
yaxis: {
|
||||
min: 0,
|
||||
max: 100,
|
||||
labels: {
|
||||
formatter: function (val) {
|
||||
return val + '%'
|
||||
}
|
||||
}
|
||||
return val + '%';
|
||||
},
|
||||
},
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
@@ -51,13 +52,14 @@ const BarChart = ({data}) => {
|
||||
},
|
||||
},
|
||||
};
|
||||
const series = [{
|
||||
name: 'درصد پیشرفت',
|
||||
data: usableArray
|
||||
}]
|
||||
return (
|
||||
<Chart chartId="LoanProgressBar" type="bar" specialOption={specialOption} series={series}/>
|
||||
)
|
||||
const series = [
|
||||
{
|
||||
name: 'درصد پیشرفت',
|
||||
data: usableArray,
|
||||
},
|
||||
];
|
||||
|
||||
return <Chart chartId="LoanProgressBar" type="bar" specialOption={specialOption} series={series}/>;
|
||||
};
|
||||
|
||||
export default BarChart;
|
||||
@@ -1,55 +1,44 @@
|
||||
import {Grid, Paper} from "@mui/material";
|
||||
import {Box, CircularProgress, Grid, Paper, Typography} from "@mui/material";
|
||||
import BarChart from "./BarChart";
|
||||
import Filter from "../Filter";
|
||||
import {useTranslations} from "next-intl";
|
||||
|
||||
const fakeData = [
|
||||
{name: "آذربایجان شرقی", data: 0},
|
||||
{name: "آذربایجان غربی", data: 33},
|
||||
{name: "اردبیل", data: 90},
|
||||
{name: "اصفهان", data: 30},
|
||||
{name: "البرز", data: 70},
|
||||
{name: "ایلام", data: 32},
|
||||
{name: "بوشهر", data: 12},
|
||||
{name: "تهران", data: 44},
|
||||
{name: "چهارمحال و بختیاری", data: 95},
|
||||
{name: "خراسان جنوبی", data: 30},
|
||||
{name: "خراسان رضوی", data: 70},
|
||||
{name: "خراسان شمالی", data: 10},
|
||||
{name: "خوزستان", data: 28},
|
||||
{name: "زنجان", data: 85},
|
||||
{name: "سمنان", data: 30},
|
||||
{name: "سیستان و بلوچستان", data: 70},
|
||||
{name: "فارس", data: 10},
|
||||
{name: "قزوین", data: 12},
|
||||
{name: "قم", data: 40},
|
||||
{name: "کردستان", data: 85},
|
||||
{name: "کرمان", data: 30},
|
||||
{name: "کرمانشاه", data: 67},
|
||||
{name: "کهگیلویه و بویراحمد", data: 100},
|
||||
{name: "گلستان", data: 97},
|
||||
{name: "گیلان", data: 5},
|
||||
{name: "لرستان", data: 27},
|
||||
{name: "مازندران", data: 31},
|
||||
{name: "مرکزی", data: 37},
|
||||
{name: "هرمزگان", data: 46},
|
||||
{name: "همدان", data: 52},
|
||||
{name: "یزد", data: 60}
|
||||
];
|
||||
import useChart from "@/lib/app/hooks/useChart";
|
||||
import {GET_PROVINCE_PROGRESS} from "@/core/data/apiRoutes";
|
||||
|
||||
const LoanProgress = () => {
|
||||
const t = useTranslations();
|
||||
const {errorReportList, isLoadingReportList, reportList} = useChart(GET_PROVINCE_PROGRESS);
|
||||
|
||||
console.log(reportList)
|
||||
return (
|
||||
<Paper elevation={2} sx={{width: "95%", mx: "auto", my: 2, pb: 2, background: "#f7f7f7e6"}}>
|
||||
<Filter title={t("reports.loan_progress")}
|
||||
filterItem={[
|
||||
{type: "province", type_fa: "استان", multiple: true},
|
||||
{type: "year", type_fa: "سال", multiple: false}
|
||||
]}
|
||||
/>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12} sx={{height: "400px"}}>
|
||||
<BarChart data={fakeData}/>
|
||||
<Grid container>
|
||||
<Grid item xs={12} sx={{aspectRatio: {xs: "1/1", sm: "1/1", md: "1/0.4", xl: "1/0.3"}}}>
|
||||
{1 === 1 ? (
|
||||
<Box sx={{
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
justifyContent: "center"
|
||||
}}>
|
||||
<CircularProgress sx={{mb: 1, color: "#c2c2c2"}}/>
|
||||
<Typography variant="h6"
|
||||
sx={{color: "#c2c2c2", letterSpacing: "0.2rem"}}
|
||||
>
|
||||
درحال دریافت اطلاعات
|
||||
</Typography>
|
||||
</Box>
|
||||
) : errorReportList ? (
|
||||
<Typography variant="caption">درحال دریافت اطلاعات</Typography>
|
||||
) : (
|
||||
<BarChart data={reportList}/>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Paper>
|
||||
|
||||
@@ -197,3 +197,7 @@ export const DELETE_ROLE_MANAGEMENT =
|
||||
export const GET_PERMISSIONS_LIST =
|
||||
BASE_URL + "/dashboard/permissions/list"
|
||||
//role management
|
||||
|
||||
// reports
|
||||
export const GET_PROVINCE_PROGRESS = BASE_URL + "/dashboard/reports/navgan/province_progress"
|
||||
// reports
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export const calculateGradientColor = (percentage) => {
|
||||
let colorStops = [
|
||||
{percent: 0, color: [199, 18, 5]}, // 0%: #3D0C11
|
||||
{percent: 33, color: [240, 59, 47]}, // 33%: #D80032
|
||||
{percent: 0, color: [173, 3, 23]}, // 0%: #3D0C11
|
||||
{percent: 33, color: [245, 81, 81]}, // 33%: #D80032
|
||||
{percent: 34, color: [237, 204, 101]}, // 34%: #F2F7A1
|
||||
{percent: 66, color: [240, 184, 7]}, // 66%: #E9B824
|
||||
{percent: 67, color: [167, 211, 151]}, // 67%: #B0D9B1
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import useRequest from "@/lib/app/hooks/useRequest";
|
||||
import useSWR from "swr";
|
||||
|
||||
const useChart = (chart_url) => {
|
||||
const requestServer = useRequest({auth: true, notification: false})
|
||||
|
||||
//swr config
|
||||
const fetcher = (...args) => {
|
||||
return requestServer(args, 'get').then(({data}) => {
|
||||
return data.data;
|
||||
}).catch(() => {
|
||||
})
|
||||
};
|
||||
|
||||
const {data, isLoading} = useSWR(chart_url, fetcher, {
|
||||
revalidateIfStale: false,
|
||||
revalidateOnFocus: false,
|
||||
revalidateOnReconnect: false
|
||||
});
|
||||
|
||||
return {
|
||||
reportList: data,
|
||||
isLoadingReportList: isLoading,
|
||||
errorReportList: !data
|
||||
}
|
||||
};
|
||||
|
||||
export default useChart;
|
||||
Reference in New Issue
Block a user