Files
revenue-fe/src/pages/pengajuan_kredit/chart/blocks/Chart.tsx
2025-02-01 16:44:51 +07:00

194 lines
4.5 KiB
TypeScript

import ApexChart from 'react-apexcharts';
import { ApexOptions } from 'apexcharts';
import { useEffect, useState } from 'react';
import moment from 'moment';
import { fCurrency } from '@/utils/FormatNumber';
interface series {
name: string;
data: any[];
}
const Chart = ({ title, subtitle, number, type, chartType, chartLegend, chartData = [] }: any) => {
const [series, setSeries] = useState<series[]>([]);
const [categories, setCategories] = useState<string[]>([]);
const [yoyData, setYoyData] = useState<string[]>([]);
let legendOpt = null;
if (chartLegend == 'true') {
legendOpt = true;
} else {
legendOpt = false;
}
const options: ApexOptions = {
annotations: {
xaxis: categories.map((cat, index) => ({
x: cat,
x2: cat,
borderColor: '#00000000',
label: {
text: yoyData[index] || '',
orientation: 'horizontal',
position: 'bottom',
style: {
background: yoyData[index]?.includes('↓') ? '#fee2e2' : '#dcfce7',
color: yoyData[index]?.includes('↓') ? '#991b1b' : '#166534',
fontSize: '12px',
fontWeight: 600,
padding: {
left: 10,
right: 10,
top: 2,
bottom: 2
},
borderRadius: 4
}
}
}))
},
chart: {
type: 'area',
toolbar: {
show: false
}
},
plotOptions: {
bar: {
horizontal: false,
columnWidth: '50%'
}
},
dataLabels: {
enabled: true,
offsetY: -10,
offsetX: chartType === 'bar' ? 1.5 : 0,
formatter: (value: any) => {
if (type == 'sum') {
return fCurrency(value);
} else {
return value;
}
}
},
markers: {
size: 0,
shape: 'circle'
},
xaxis: {
categories: categories,
labels: {
style: {
colors: 'var(--tw-gray-500)',
fontSize: '12px'
}
}
},
yaxis: {
labels: {
style: {
colors: 'var(--tw-gray-500)',
fontSize: '12px'
},
formatter: (value: any) => {
if (type == 'sum') {
return fCurrency(value);
} else {
return value;
}
}
}
},
grid: {
borderColor: 'var(--tw-gray-200)',
strokeDashArray: 5,
padding: {
top: 0,
right: 0,
bottom: 20,
left: 0
}
},
tooltip: {
enabled: true,
shared: true,
intersect: false,
y: {
formatter: (value: any) => {
if (type == 'sum') {
return fCurrency(value);
} else {
return value;
}
}
}
},
stroke: {
show: true,
curve: 'smooth',
lineCap: 'butt',
colors: undefined,
width: 3,
dashArray: 0
},
legend: {
show: legendOpt,
position: 'right',
floating: false
}
};
useEffect(() => {
if (chartData && chartData.length != 0) {
const categories = chartData[0].data.map((item: any) => item.x);
const currentData = chartData[0].data.map((item: any) => item.y);
const yoyData = chartData[1].data.map((item: any) => item.y);
const percentageChange = currentData.map((current: number, index: number) => {
const previous = yoyData[index];
if (!previous || previous === 0) return 0;
return (((current - previous) / previous) * 100).toFixed(2);
});
const yoyLabels = percentageChange.map((value: number) => {
if (value === 0) return '-';
const arrow = value >= 0 ? '↑' : '↓';
return `${arrow}${Math.abs(value)}% YoY`;
});
const series: series[] = [
{
name: chartData[0].name,
data: currentData
},
{
name: chartData[1].name,
data: yoyData
}
];
setSeries(series);
setCategories(categories);
setYoyData(yoyLabels);
}
}, [chartData]);
return (
<div className="card h-full">
<div className="card-header border-0 ps-5 pb-0">
<h3 className="card-title">{title}</h3>
</div>
<div className="card-body flex flex-col gap-4 p-2">
<ApexChart
id="earnings_chart" //
options={options}
series={series}
type={chartType}
legend={chartLegend}
height={350}
/>
</div>
</div>
);
};
export { Chart };