126 lines
3.5 KiB
TypeScript
126 lines
3.5 KiB
TypeScript
import { Bar, BarChart, CartesianGrid, XAxis, YAxis, LabelList } from "recharts";
|
|
import React, { useState, useEffect } from "react";
|
|
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardHeader,
|
|
CardTitle,
|
|
} from "~/components/ui/card";
|
|
import {
|
|
type ChartConfig,
|
|
ChartContainer,
|
|
ChartTooltip,
|
|
ChartTooltipContent,
|
|
} from "~/components/ui/chart";
|
|
|
|
export const description = "An interactive bar chart";
|
|
|
|
const chartData = [
|
|
{ category: "کیمیا", ideas: 12, revenue: 850, cost: 320 },
|
|
{ category: "ُفرآروزش", ideas: 19, revenue: 1200, cost: 450 },
|
|
{ category: "خوارزمی", ideas: 15, revenue: 1400, cost: 520 },
|
|
];
|
|
|
|
const chartConfig = {
|
|
ideas: {
|
|
label: "ایدهها",
|
|
color: "#60A5FA", // Blue-400
|
|
},
|
|
revenue: {
|
|
label: "درآمد (میلیون)",
|
|
color: "#4ADE80", // Green-400
|
|
},
|
|
cost: {
|
|
label: "کاهش هزینه (میلیون)",
|
|
color: "#F87171", // Red-400
|
|
},
|
|
} satisfies ChartConfig;
|
|
|
|
export function InteractiveBarChart() {
|
|
const [activeChart, setActiveChart] =
|
|
React.useState<keyof typeof chartConfig>("ideas");
|
|
|
|
const total = React.useMemo(
|
|
() => ({
|
|
ideas: chartData.reduce((acc, curr) => acc + curr.ideas, 0),
|
|
revenue: chartData.reduce((acc, curr) => acc + curr.revenue, 0),
|
|
cost: chartData.reduce((acc, curr) => acc + curr.cost, 0),
|
|
}),
|
|
[],
|
|
);
|
|
|
|
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={chartData}
|
|
margin={{
|
|
left: 12,
|
|
right: 12,
|
|
}}
|
|
barCategoryGap="42%"
|
|
>
|
|
<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) => `${value}%`}
|
|
/>
|
|
<Bar
|
|
dataKey="ideas"
|
|
fill={chartConfig.ideas.color}
|
|
radius={[8, 8, 0, 0]}
|
|
>
|
|
<LabelList
|
|
dataKey="ideas"
|
|
position="top"
|
|
style={{ fill: "#ffffff", fontSize: "12px", fontWeight: "bold" }}
|
|
/>
|
|
</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" }}
|
|
/>
|
|
</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" }}
|
|
/>
|
|
</Bar>
|
|
</BarChart>
|
|
</ChartContainer>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|