Files
reui-blocks/blocks/chart-card15.tsx
T

175 lines
4.3 KiB
TypeScript

"use client";
import {
Bar,
BarChart,
CartesianGrid,
Cell,
LabelList,
XAxis,
YAxis,
} from "recharts";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import {
type ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart";
import { cn } from "@/lib/utils";
interface ChartCard15Props {
title?: string;
description?: string;
className?: string;
}
const currencyFormatter = new Intl.NumberFormat("fa-IR", {
style: "currency",
currency: "IRR",
minimumFractionDigits: 0,
maximumFractionDigits: 0,
});
const compactCurrencyFormatter = new Intl.NumberFormat("fa-IR", {
style: "currency",
currency: "IRR",
notation: "compact",
minimumFractionDigits: 0,
maximumFractionDigits: 1,
});
const rawData = [
{ name: "شروع", value: 10000 },
{ name: "فروش", value: 5000 },
{ name: "بازپرداخت", value: -1200 },
{ name: "هزینه", value: -3500 },
{ name: "مالیات", value: -800 },
{ name: "پایان", value: 9500 },
];
const chartData = rawData.map((item, index) => {
if (index === 0 || item.name === "پایان") {
return {
name: item.name,
value: item.value,
start: 0,
isTotal: true,
};
}
let runningTotal = rawData[0].value;
for (let i = 1; i < index; i++) {
runningTotal += rawData[i].value;
}
return {
name: item.name,
value: item.value,
start: item.value >= 0 ? runningTotal : runningTotal + item.value,
isTotal: false,
};
});
const chartConfig = {
value: {
label: "مبلغ",
color: "var(--chart-1)",
},
} satisfies ChartConfig;
const ChartCard15 = ({
title = "آبشار درآمد",
description = "تفکیک تغییرات درآمد",
className,
}: ChartCard15Props) => {
return (
<Card
dir="rtl"
lang="fa"
className={cn("w-full max-w-2xl text-start", className)}
>
<CardHeader>
<CardTitle>{title}</CardTitle>
<CardDescription>{description}</CardDescription>
</CardHeader>
<CardContent>
<ChartContainer config={chartConfig} className="h-64 w-full">
<BarChart
data={chartData}
margin={{ top: 20, right: 10, left: 0, bottom: 0 }}
>
<CartesianGrid strokeDasharray="3 3" vertical={false} />
<XAxis
dataKey="name"
axisLine={false}
tickLine={false}
tickMargin={8}
fontSize={11}
/>
<YAxis
axisLine={false}
tickLine={false}
tickMargin={8}
fontSize={10}
width={52}
tickFormatter={(value) =>
compactCurrencyFormatter.format(Number(value))
}
/>
<ChartTooltip
content={
<ChartTooltipContent
formatter={(value) => {
const num = Number(value);
if (num === 0) return null;
const formatted = currencyFormatter.format(Math.abs(num));
return num < 0
? `${formatted} (کاهش)`
: `${formatted} (افزایش)`;
}}
/>
}
cursor={{ fillOpacity: 0.05 }}
/>
<Bar dataKey="start" stackId="a" fill="transparent" />
<Bar dataKey="value" stackId="a" radius={[4, 4, 4, 4]}>
{chartData.map((entry, index) => (
<Cell
key={index}
fill={
entry.isTotal
? "var(--chart-3)"
: entry.value >= 0
? "var(--chart-1)"
: "var(--chart-5)"
}
/>
))}
<LabelList
dataKey="value"
position="top"
fontSize={10}
formatter={(value) => {
const num = Number(value);
if (num === 0) return "";
return compactCurrencyFormatter.format(Math.abs(num));
}}
/>
</Bar>
</BarChart>
</ChartContainer>
</CardContent>
</Card>
);
};
export { ChartCard15 };