feat: add bar, donut, and pie charts to dashboard for enhanced data visualization

This commit is contained in:
Ardeman 2025-03-13 05:45:03 +08:00
parent 474c6dc750
commit 0680fb4dc8
5 changed files with 157 additions and 118 deletions

View File

@ -16,7 +16,7 @@ type CardReportProperty = {
export const CardReport = (properties: CardReportProperty) => { export const CardReport = (properties: CardReportProperty) => {
const { title, amount, icon: Icon, counter, currency } = properties const { title, amount, icon: Icon, counter, currency } = properties
return ( return (
<div className="rounded-lg bg-white px-4 py-6 shadow-sm"> <div className="rounded-xl bg-white px-4 py-6 shadow-sm">
<div className="flex items-center"> <div className="flex items-center">
<Icon <Icon
className="ml-2 rounded-xl bg-[#2E2F7C] p-2 text-white" className="ml-2 rounded-xl bg-[#2E2F7C] p-2 text-white"

View File

@ -7,12 +7,11 @@ import {
LinearScale, LinearScale,
BarElement, BarElement,
Title, Title,
type ChartOptions,
type ChartEvent, type ChartEvent,
type ActiveElement, type ActiveElement,
} from 'chart.js' } from 'chart.js'
import { useState } from 'react' import { useState } from 'react'
import { Bar, Doughnut, Pie } from 'react-chartjs-2' import { Bar } from 'react-chartjs-2'
ChartJS.register( ChartJS.register(
ArcElement, ArcElement,
CategoryScale, CategoryScale,
@ -25,64 +24,7 @@ ChartJS.register(
type HandleChartClick = (event: ChartEvent, elements: ActiveElement[]) => void type HandleChartClick = (event: ChartEvent, elements: ActiveElement[]) => void
export const UiChartPie = () => { export const ChartBar = () => {
const data = {
labels: [
'Pidana',
'Perdata',
'Perceraian',
'Surat Bisnis',
'Surat Tanah',
'Lainnya',
],
datasets: [
{
data: [33.7, 13, 22.8, 9.3, 9.3, 21.2],
backgroundColor: [
'#FFB300',
'#4CAF50',
'#3F51B5',
'#F44336',
'#2196F3',
'#FF9800',
],
hoverOffset: 4,
},
],
}
const options: ChartOptions<'pie'> = {
maintainAspectRatio: true,
responsive: false,
plugins: {
legend: {
position: 'right',
labels: {
usePointStyle: true,
pointStyle: 'circle',
padding: 20,
},
},
},
layout: {
padding: 0,
},
}
return (
<div className="h-[300px] w-full items-center justify-center rounded-lg bg-white p-5 px-4 py-6 text-center shadow-sm">
<h2 className="text-xl font-bold">Top 5 Artikel</h2>
<Pie
height={225}
width={450}
data={data}
options={options}
/>
</div>
)
}
export const UiChartBar = () => {
const yearlyData = { const yearlyData = {
labels: ['2022', '2023', '2024'], labels: ['2022', '2023', '2024'],
datasets: [ datasets: [
@ -151,7 +93,7 @@ export const UiChartBar = () => {
} }
return ( return (
<div className="rounded-lg bg-white p-6 shadow-sm"> <div className="rounded-xl bg-white p-6 shadow-sm">
<div className="mb-4 flex items-center justify-between"> <div className="mb-4 flex items-center justify-between">
<h2 className="text-xl font-bold"> <h2 className="text-xl font-bold">
{view === 'year' {view === 'year'
@ -177,51 +119,3 @@ export const UiChartBar = () => {
</div> </div>
) )
} }
export const ChartSubscription = () => {
const data = {
labels: ['Selesai', 'Belum Selesai'],
datasets: [
{
data: [70, 30],
backgroundColor: ['#1e3a8a', '#e5e7eb'],
borderWidth: 0,
cutout: '70%',
circumference: 180,
rotation: 270,
},
],
}
const options: ChartOptions<'doughnut'> = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'right',
labels: {
usePointStyle: true,
pointStyle: 'circle',
boxWidth: 10,
},
},
tooltip: {
enabled: false,
},
},
}
return (
<div className="rounded-xl bg-white p-6 shadow-lg">
<h2 className="mb-4 text-[20px]">Subscription Selesai</h2>
<div className="flex items-center justify-between">
<div style={{ height: 'auto', width: '100%' }}>
<Doughnut
data={data}
options={options}
/>
</div>
</div>
</div>
)
}

View File

@ -0,0 +1,69 @@
import {
Chart as ChartJS,
ArcElement,
Tooltip,
Legend,
CategoryScale,
LinearScale,
BarElement,
Title,
type ChartOptions,
} from 'chart.js'
import { Doughnut } from 'react-chartjs-2'
ChartJS.register(
ArcElement,
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend,
)
export const ChartDonut = () => {
const data = {
labels: ['Selesai', 'Belum Selesai'],
datasets: [
{
data: [70, 30],
backgroundColor: ['#1e3a8a', '#e5e7eb'],
borderWidth: 0,
cutout: '70%',
circumference: 180,
rotation: 270,
},
],
}
const options: ChartOptions<'doughnut'> = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'right',
labels: {
usePointStyle: true,
pointStyle: 'circle',
boxWidth: 10,
},
},
tooltip: {
enabled: false,
},
},
}
return (
<div className="rounded-xl bg-white p-6 shadow-sm">
<h2 className="mb-4 text-[20px]">Subscription Selesai</h2>
<div className="flex items-center justify-between">
<div style={{ height: 'auto', width: '100%' }}>
<Doughnut
data={data}
options={options}
/>
</div>
</div>
</div>
)
}

View File

@ -0,0 +1,78 @@
import {
Chart as ChartJS,
ArcElement,
Tooltip,
Legend,
CategoryScale,
LinearScale,
BarElement,
Title,
type ChartOptions,
} from 'chart.js'
import { Pie } from 'react-chartjs-2'
ChartJS.register(
ArcElement,
CategoryScale,
LinearScale,
BarElement,
Title,
Tooltip,
Legend,
)
export const ChartPie = () => {
const data = {
labels: [
'Pidana',
'Perdata',
'Perceraian',
'Surat Bisnis',
'Surat Tanah',
'Lainnya',
],
datasets: [
{
data: [33.7, 13, 22.8, 9.3, 9.3, 21.2],
backgroundColor: [
'#FFB300',
'#4CAF50',
'#3F51B5',
'#F44336',
'#2196F3',
'#FF9800',
],
hoverOffset: 4,
},
],
}
const options: ChartOptions<'pie'> = {
maintainAspectRatio: true,
responsive: false,
plugins: {
legend: {
position: 'right',
labels: {
usePointStyle: true,
pointStyle: 'circle',
padding: 20,
},
},
},
layout: {
padding: 0,
},
}
return (
<div className="h-[300px] w-full items-center justify-center rounded-xl bg-white p-5 text-center shadow-sm">
<h2 className="text-xl font-bold">Top 5 Artikel</h2>
<Pie
height={225}
width={450}
data={data}
options={options}
/>
</div>
)
}

View File

@ -1,10 +1,8 @@
import { CardReport } from '~/components/ui/card-report' import { CardReport } from '~/components/ui/card-report'
import {
ChartSubscription,
UiChartBar,
UiChartPie,
} from '~/components/ui/chart'
import { ChartBar } from './chart-bar'
import { ChartDonut } from './chart-donut'
import { ChartPie } from './chart-pie'
import { HISTORY, REPORT } from './data' import { HISTORY, REPORT } from './data'
export const DashboardPage = () => { export const DashboardPage = () => {
return ( return (
@ -46,16 +44,16 @@ export const DashboardPage = () => {
/> />
))} ))}
<div className="max-h-[300px] sm:col-span-2 sm:col-start-2 sm:row-span-2 sm:row-start-1"> <div className="max-h-[300px] sm:col-span-2 sm:col-start-2 sm:row-span-2 sm:row-start-1">
<UiChartPie /> <ChartPie />
</div> </div>
</div> </div>
<div className="flex flex-wrap gap-5 py-5 sm:flex-nowrap"> <div className="flex flex-wrap gap-5 py-5 sm:flex-nowrap">
<div className="h-full w-full sm:w-[60%]"> <div className="h-full w-full sm:w-[60%]">
<UiChartBar /> <ChartBar />
</div> </div>
<div className="w-ful h-full sm:w-[40%]"> <div className="w-ful h-full sm:w-[40%]">
<ChartSubscription /> <ChartDonut />
</div> </div>
</div> </div>
</div> </div>