diff --git a/resources/js/components/ui/chart.tsx b/resources/js/components/ui/chart.tsx
index c7e0d39..bb6dc22 100644
--- a/resources/js/components/ui/chart.tsx
+++ b/resources/js/components/ui/chart.tsx
@@ -278,9 +278,13 @@ function ChartLegendContent({
payload,
verticalAlign = "bottom",
nameKey,
+ onItemClick,
+ activeName,
}: React.ComponentProps<"div"> & {
hideIcon?: boolean
nameKey?: string
+ onItemClick?: (name: string) => void
+ activeName?: string
} & RechartsPrimitive.DefaultLegendContentProps) {
const { config } = useChart()
@@ -301,13 +305,20 @@ function ChartLegendContent({
.map((item, index) => {
const key = `${nameKey ?? item.dataKey ?? "value"}`
const itemConfig = getPayloadConfigFromPayload(config, item, key)
+ const label = typeof itemConfig?.label === 'string' ? itemConfig.label : ''
+ const isInactive = activeName !== undefined && activeName !== label
return (
svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground"
+ "flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground",
+ onItemClick && "cursor-pointer select-none hover:opacity-80",
+ isInactive && "opacity-40"
)}
+ onClick={() => {
+ if (label) onItemClick?.(label)
+ }}
>
{itemConfig?.icon && !hideIcon ? (
diff --git a/resources/js/pages/admin/analysis/index.tsx b/resources/js/pages/admin/analysis/index.tsx
index b844d59..3d66f7e 100644
--- a/resources/js/pages/admin/analysis/index.tsx
+++ b/resources/js/pages/admin/analysis/index.tsx
@@ -267,6 +267,8 @@ type DashboardPieChartProps = {
function DashboardPieChart({ title, data, dataKey, nameKey }: DashboardPieChartProps) {
const hasData = data.length > 0 && data.some((d) => d.count > 0);
+ const [activeName, setActiveName] = useState(undefined);
+
const pieColors = useMemo(() => generateRandomColors(5), []);
const chartConfig = useMemo(() => {
@@ -287,6 +289,17 @@ function DashboardPieChart({ title, data, dataKey, nameKey }: DashboardPieChartP
}));
}, [data, pieColors]);
+ const handlePieClick = (_: unknown, index: number) => {
+ const name = chartData[index]?.name;
+ if (name) {
+ setActiveName((prev) => (prev === name ? undefined : name));
+ }
+ };
+
+ const handleLegendClick = (name: string) => {
+ setActiveName((prev) => (prev === name ? undefined : name));
+ };
+
return (
@@ -311,9 +324,24 @@ function DashboardPieChart({ title, data, dataKey, nameKey }: DashboardPieChartP
data={chartData}
dataKey={dataKey}
nameKey={nameKey}
- />
+ onClick={handlePieClick}
+ >
+ {chartData.map((item, index) => (
+ |
+ ))}
+
}
+ content={
+
+ }
className="-translate-y-2 flex-wrap gap-2 *:basis-1/4 *:justify-center"
/>
diff --git a/resources/js/pages/dashboard.tsx b/resources/js/pages/dashboard.tsx
index 8744170..1c01871 100644
--- a/resources/js/pages/dashboard.tsx
+++ b/resources/js/pages/dashboard.tsx
@@ -18,7 +18,7 @@ import {
UserCheck,
} from 'lucide-react';
import { useEffect, useMemo, useState } from 'react';
-import { Pie, PieChart } from 'recharts';
+import { Cell, Pie, PieChart } from 'recharts';
import { toast } from 'sonner';
type TodayAttendance = {
@@ -463,6 +463,8 @@ type DashboardPieChartProps = {
function DashboardPieChart({ title, data, dataKey, nameKey }: DashboardPieChartProps) {
const hasData = data.length > 0 && data.some((d) => d.count > 0);
+ const [activeName, setActiveName] = useState(undefined);
+
const pieColors = useMemo(() => generateRandomColors(5), []);
const chartConfig = useMemo(() => {
@@ -483,6 +485,17 @@ function DashboardPieChart({ title, data, dataKey, nameKey }: DashboardPieChartP
}));
}, [data, pieColors]);
+ const handlePieClick = (_: unknown, index: number) => {
+ const name = chartData[index]?.name;
+ if (name) {
+ setActiveName((prev) => (prev === name ? undefined : name));
+ }
+ };
+
+ const handleLegendClick = (name: string) => {
+ setActiveName((prev) => (prev === name ? undefined : name));
+ };
+
return (
@@ -507,9 +520,24 @@ function DashboardPieChart({ title, data, dataKey, nameKey }: DashboardPieChartP
data={chartData}
dataKey={dataKey}
nameKey={nameKey}
- />
+ onClick={handlePieClick}
+ >
+ {chartData.map((item, index) => (
+ |
+ ))}
+
}
+ content={
+
+ }
className="-translate-y-2 flex-wrap gap-2 *:basis-1/4 *:justify-center"
/>