revamp template
This commit is contained in:
193
src/pages/pengajuan_kredit/chart/blocks/Chart.tsx
Normal file
193
src/pages/pengajuan_kredit/chart/blocks/Chart.tsx
Normal file
@ -0,0 +1,193 @@
|
||||
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 };
|
||||
Reference in New Issue
Block a user