Reviewed-on: https://git.pelekan.org/Saeed0920/inogen/pulls/7 Co-authored-by: saeed0920 <sd.eed1381@gmail.com> Co-committed-by: saeed0920 <sd.eed1381@gmail.com>
128 lines
4.0 KiB
TypeScript
128 lines
4.0 KiB
TypeScript
import {
|
|
Bar,
|
|
BarChart,
|
|
CartesianGrid,
|
|
XAxis,
|
|
YAxis,
|
|
LabelList,
|
|
} from "recharts";
|
|
import { Card, CardContent } from "~/components/ui/card";
|
|
import {
|
|
type ChartConfig,
|
|
ChartContainer,
|
|
} from "~/components/ui/chart";
|
|
import { formatNumber } from "~/lib/utils";
|
|
|
|
export type CompanyChartDatum = {
|
|
category: string; // related_company
|
|
capacity: number; // percentage
|
|
revenue: number; // percentage
|
|
cost: number; // percentage
|
|
};
|
|
|
|
const chartConfig = {
|
|
capacity: {
|
|
label: "افزایش ظرفیت",
|
|
color: "#69C8EA",
|
|
},
|
|
revenue: {
|
|
label: "افزایش درآمد",
|
|
color: "#4ADE80", // Green-400
|
|
},
|
|
cost: {
|
|
label: "کاهش هزینه",
|
|
color: "#F87171", // Red-400
|
|
},
|
|
} satisfies ChartConfig;
|
|
|
|
|
|
export function InteractiveBarChart({
|
|
data,
|
|
}: {
|
|
data: CompanyChartDatum[];
|
|
}) {
|
|
return (
|
|
<Card className="py-0 bg-transparent mt-20 border-none h-full">
|
|
<CardContent className="px-2 sm:p-6 bg-transparent">
|
|
<ChartContainer config={chartConfig} className="aspect-auto h-96 w-full">
|
|
<BarChart
|
|
accessibilityLayer
|
|
data={data}
|
|
margin={{ left: 12, right: 12 }}
|
|
barGap={15}
|
|
barSize={8}
|
|
>
|
|
<CartesianGrid vertical={false} stroke="#475569" />
|
|
<XAxis
|
|
dataKey="category"
|
|
tickLine={false}
|
|
axisLine={false}
|
|
tickMargin={8}
|
|
minTickGap={32}
|
|
tick={{ fill: "#94a3b8", fontSize: 12 }}
|
|
/>
|
|
<YAxis
|
|
domain={[0, 100]}
|
|
tickLine={false}
|
|
axisLine={false}
|
|
tickMargin={8}
|
|
tick={{ fill: "#94a3b8", fontSize: 12 }}
|
|
tickFormatter={(value) => `${formatNumber(Math.round(value))}%`}
|
|
/>
|
|
<Bar dataKey="capacity" fill={chartConfig.capacity.color} radius={[8, 8, 0, 0]}>
|
|
<LabelList
|
|
dataKey="capacity"
|
|
position="top"
|
|
style={{ fill: "#ffffff", fontSize: "12px", fontWeight: "bold" }}
|
|
formatter={(v: number) => `${formatNumber(Math.round(v))}%`}
|
|
/>
|
|
</Bar>
|
|
<Bar dataKey="revenue" fill={chartConfig.revenue.color} radius={[8, 8, 0, 0]}>
|
|
<LabelList
|
|
dataKey="revenue"
|
|
position="top"
|
|
style={{ fill: "#ffffff", fontSize: "12px", fontWeight: "bold" }}
|
|
formatter={(v: number) => `${formatNumber(Math.round(v))}%`}
|
|
/>
|
|
</Bar>
|
|
<Bar dataKey="cost" fill={chartConfig.cost.color} radius={[8, 8, 0, 0]}>
|
|
<LabelList
|
|
dataKey="cost"
|
|
position="top"
|
|
style={{ fill: "#ffffff", fontSize: "12px", fontWeight: "bold" }}
|
|
formatter={(v: number) => `${formatNumber(Math.round(v))}%`}
|
|
/>
|
|
</Bar>
|
|
</BarChart>
|
|
</ChartContainer>
|
|
|
|
{/* Legend below chart */}
|
|
<div className="flex justify-center gap-8 mt-4">
|
|
<div className="flex items-center gap-2">
|
|
<div
|
|
className="w-6 h-2 rounded"
|
|
style={{ backgroundColor: chartConfig.capacity.color }}
|
|
></div>
|
|
<span className="text-sm text-white">{chartConfig.capacity.label}</span>
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<div
|
|
className="w-6 h-2 rounded"
|
|
style={{ backgroundColor: chartConfig.cost.color }}
|
|
></div>
|
|
<span className="text-sm text-white">{chartConfig.cost.label}</span>
|
|
</div>
|
|
<div className="flex items-center gap-2">
|
|
<div
|
|
className="w-6 h-2 rounded"
|
|
style={{ backgroundColor: chartConfig.revenue.color }}
|
|
></div>
|
|
<span className="text-sm text-white">{chartConfig.revenue.label}</span>
|
|
</div>
|
|
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|