feat: add bar, donut, and pie charts to dashboard for enhanced data visualization
This commit is contained in:
parent
474c6dc750
commit
0680fb4dc8
@ -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"
|
||||||
|
|||||||
@ -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>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
69
app/pages/dashboard/chart-donut.tsx
Normal file
69
app/pages/dashboard/chart-donut.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
78
app/pages/dashboard/chart-pie.tsx
Normal file
78
app/pages/dashboard/chart-pie.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -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>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user