نمودار (Chart)
کامپوننتهای نمودار با استفاده از Recharts v3 برای نمایش دادهها همراه با تولتیپ، راهنما، و پترنهای پیشرفته
نصب (Installation)
npx @quark-lab/rad-ui add chartنمودارهای میلهای (Bar Charts)
نمودار میلهای پیشفرض (Default Bar Chart)
نمودار میلهای ساده با پسزمینه نقطهای و تولتیپ.
نمودار میلهای5.2%
فروردین - اسفند ۱۴۰۴
مشاهده کد
1"use client";
2
3import { TrendingUp } from "lucide-react";
4import { Bar, BarChart, XAxis } from "recharts";
5import {
6 Card, CardContent, CardDescription, CardHeader, CardTitle,
7 Badge, ChartContainer, ChartTooltip, ChartTooltipContent,
8 type ChartConfig,
9} from "@/components/ui";
10
11const chartData = [
12 { month: "فروردین", desktop: 342 },
13 { month: "اردیبهشت", desktop: 876 },
14 { month: "خرداد", desktop: 512 },
15 { month: "تیر", desktop: 629 },
16 { month: "مرداد", desktop: 458 },
17 { month: "شهریور", desktop: 781 },
18];
19
20const chartConfig = {
21 desktop: { label: "دسکتاپ", color: "hsl(var(--chart-1))" },
22} satisfies ChartConfig;
23
24export function DefaultBarChart() {
25 return (
26 <Card>
27 <CardHeader>
28 <CardTitle>
29 نمودار میلهای
30 <Badge variant="outline" className="ms-2">
31 <TrendingUp className="h-4 w-4" />
32 <span>5.2%</span>
33 </Badge>
34 </CardTitle>
35 <CardDescription>فروردین - اسفند ۱۴۰۴</CardDescription>
36 </CardHeader>
37 <CardContent>
38 <ChartContainer config={chartConfig}>
39 <BarChart accessibilityLayer data={chartData}>
40 <XAxis dataKey="month" tickLine={false} tickMargin={10} axisLine={false} />
41 <ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
42 <Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
43 </BarChart>
44 </ChartContainer>
45 </CardContent>
46 </Card>
47 );
48}نمودار میلهای گرادیان (Gradient Bar Chart)
نمودار میلهای با افکت گرادیان برای ظاهر مدرن.
نمودار گرادیان5.2%
فروردین - اسفند ۱۴۰۴
مشاهده کد
1"use client";
2
3import { TrendingUp } from "lucide-react";
4import { Bar, BarChart, XAxis } from "recharts";
5import {
6 Card, CardContent, CardDescription, CardHeader, CardTitle,
7 Badge, ChartContainer, ChartTooltip, ChartTooltipContent,
8 type ChartConfig,
9} from "@/components/ui";
10
11const chartConfig = {
12 desktop: { label: "دسکتاپ", color: "hsl(var(--chart-1))" },
13} satisfies ChartConfig;
14
15const CustomGradientBar = (props) => {
16 const { fill, x, y, width, height, dataKey } = props;
17 return (
18 <>
19 <rect x={x} y={y} width={width} height={height} stroke="none"
20 fill={`url(#gradient-bar-${dataKey})`} />
21 <rect x={x} y={y} width={width} height={2} stroke="none" fill={fill} />
22 <defs>
23 <linearGradient id={`gradient-bar-${dataKey}`} x1="0" y1="0" x2="0" y2="1">
24 <stop offset="0%" stopColor={fill} stopOpacity={0.5} />
25 <stop offset="100%" stopColor={fill} stopOpacity={0} />
26 </linearGradient>
27 </defs>
28 </>
29 );
30};
31
32export function GradientBarChart() {
33 return (
34 <Card>
35 <CardHeader>
36 <CardTitle>
37 نمودار گرادیان
38 <Badge variant="outline" className="ms-2">
39 <TrendingUp className="h-4 w-4" /><span>5.2%</span>
40 </Badge>
41 </CardTitle>
42 <CardDescription>فروردین - اسفند ۱۴۰۴</CardDescription>
43 </CardHeader>
44 <CardContent>
45 <ChartContainer config={chartConfig}>
46 <BarChart accessibilityLayer data={chartData}>
47 <XAxis dataKey="month" tickLine={false} tickMargin={10} axisLine={false} />
48 <ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
49 <Bar shape={<CustomGradientBar />} dataKey="desktop"
50 fill="var(--color-desktop)" />
51 </BarChart>
52 </ChartContainer>
53 </CardContent>
54 </Card>
55 );
56}نمودار مساحتی (Area Chart)
نمودار مساحتی با پترن نقطهای و دو سری داده.
نمودار مساحتی5.2%
نمایش بازدیدکنندگان ۶ ماه اخیر
مشاهده کد
1"use client";
2
3import { TrendingUp } from "lucide-react";
4import { Area, AreaChart, CartesianGrid, XAxis } from "recharts";
5import {
6 Card, CardContent, CardDescription, CardHeader, CardTitle,
7 Badge, ChartContainer, ChartTooltip, ChartTooltipContent,
8 type ChartConfig,
9} from "@/components/ui";
10
11const chartConfig = {
12 desktop: { label: "دسکتاپ", color: "hsl(var(--chart-1))" },
13 mobile: { label: "موبایل", color: "hsl(var(--chart-2))" },
14} satisfies ChartConfig;
15
16export function AreaChartExample() {
17 return (
18 <Card>
19 <CardHeader>
20 <CardTitle>
21 نمودار مساحتی
22 <Badge variant="outline" className="ms-2">
23 <TrendingUp className="h-4 w-4" /><span>5.2%</span>
24 </Badge>
25 </CardTitle>
26 <CardDescription>نمایش بازدیدکنندگان ۶ ماه اخیر</CardDescription>
27 </CardHeader>
28 <CardContent>
29 <ChartContainer config={chartConfig}>
30 <AreaChart accessibilityLayer data={chartData}>
31 <CartesianGrid vertical={false} strokeDasharray="3 3" />
32 <XAxis dataKey="month" tickLine={false} axisLine={false}
33 tickMargin={8} />
34 <ChartTooltip cursor={false} content={<ChartTooltipContent />} />
35 <Area dataKey="mobile" type="natural" fill="var(--color-mobile)"
36 fillOpacity={0.2} stroke="var(--color-mobile)" stackId="a" />
37 <Area dataKey="desktop" type="natural" fill="var(--color-desktop)"
38 fillOpacity={0.2} stroke="var(--color-desktop)" stackId="a" />
39 </AreaChart>
40 </ChartContainer>
41 </CardContent>
42 </Card>
43 );
44}نمودار خطی (Line Chart)
نمودار خطی نقطهچین برای نمایش روند دادهها.
نمودار خطی نقطهچین5.2%
فروردین - شهریور ۱۴۰۴
مشاهده کد
1"use client";
2
3import { TrendingUp } from "lucide-react";
4import { CartesianGrid, Line, LineChart, XAxis } from "recharts";
5import {
6 Card, CardContent, CardDescription, CardHeader, CardTitle,
7 Badge, ChartContainer, ChartTooltip, ChartTooltipContent,
8 type ChartConfig,
9} from "@/components/ui";
10
11const chartData = [
12 { month: "فروردین", desktop: 186 },
13 { month: "اردیبهشت", desktop: 305 },
14 { month: "خرداد", desktop: 237 },
15 { month: "تیر", desktop: 73 },
16 { month: "مرداد", desktop: 209 },
17 { month: "شهریور", desktop: 214 },
18];
19
20const chartConfig = {
21 desktop: { label: "دسکتاپ", color: "hsl(var(--chart-2))" },
22} satisfies ChartConfig;
23
24export function DottedLineChart() {
25 return (
26 <Card>
27 <CardHeader>
28 <CardTitle>
29 نمودار خطی نقطهچین
30 <Badge variant="outline" className="ms-2">
31 <TrendingUp className="h-4 w-4" /><span>5.2%</span>
32 </Badge>
33 </CardTitle>
34 <CardDescription>فروردین - شهریور ۱۴۰۴</CardDescription>
35 </CardHeader>
36 <CardContent>
37 <ChartContainer config={chartConfig}>
38 <LineChart accessibilityLayer data={chartData}
39 margin={{ left: 12, right: 12 }}>
40 <CartesianGrid vertical={false} />
41 <XAxis dataKey="month" tickLine={false} axisLine={false}
42 tickMargin={8} />
43 <ChartTooltip cursor={false} content={<ChartTooltipContent hideLabel />} />
44 <Line dataKey="desktop" type="linear" stroke="var(--color-desktop)"
45 dot={false} strokeDasharray="4 4" />
46 </LineChart>
47 </ChartContainer>
48 </CardContent>
49 </Card>
50 );
51}نمودار دایرهای (Pie Chart)
نمودار دایرهای با گوشههای گرد و برچسب داخلی.
نمودار دایرهای5.2%
فروردین - شهریور ۱۴۰۴
مشاهده کد
1"use client";
2
3import { TrendingUp } from "lucide-react";
4import { LabelList, Pie, PieChart } from "recharts";
5import {
6 Card, CardContent, CardDescription, CardHeader, CardTitle,
7 Badge, ChartContainer, ChartTooltip, ChartTooltipContent,
8 type ChartConfig,
9} from "@/components/ui";
10
11const chartData = [
12 { browser: "chrome", visitors: 275, fill: "var(--color-chrome)" },
13 { browser: "safari", visitors: 200, fill: "var(--color-safari)" },
14 { browser: "firefox", visitors: 187, fill: "var(--color-firefox)" },
15 { browser: "edge", visitors: 173, fill: "var(--color-edge)" },
16 { browser: "other", visitors: 90, fill: "var(--color-other)" },
17];
18
19const chartConfig = {
20 visitors: { label: "بازدیدکننده" },
21 chrome: { label: "کروم", color: "hsl(var(--chart-1))" },
22 safari: { label: "سافاری", color: "hsl(var(--chart-2))" },
23 firefox: { label: "فایرفاکس", color: "hsl(var(--chart-3))" },
24 edge: { label: "اج", color: "hsl(var(--chart-4))" },
25 other: { label: "سایر", color: "hsl(var(--chart-5))" },
26} satisfies ChartConfig;
27
28export function RoundedPieChart() {
29 return (
30 <Card className="flex flex-col">
31 <CardHeader className="items-center pb-0">
32 <CardTitle>
33 نمودار دایرهای
34 <Badge variant="outline" className="ms-2">
35 <TrendingUp className="h-4 w-4" /><span>5.2%</span>
36 </Badge>
37 </CardTitle>
38 <CardDescription>فروردین - شهریور ۱۴۰۴</CardDescription>
39 </CardHeader>
40 <CardContent className="flex-1 pb-0">
41 <ChartContainer config={chartConfig}
42 className="mx-auto aspect-square max-h-[250px]">
43 <PieChart>
44 <ChartTooltip content={<ChartTooltipContent nameKey="visitors" hideLabel />} />
45 <Pie data={chartData} innerRadius={30} dataKey="visitors"
46 cornerRadius={8} paddingAngle={4}>
47 <LabelList dataKey="visitors" stroke="none" fontSize={12}
48 fontWeight={500} fill="currentColor" />
49 </Pie>
50 </PieChart>
51 </ChartContainer>
52 </CardContent>
53 </Card>
54 );
55}نمودار رادار (Radar Chart)
نمودار رادار برای نمایش دادههای چندبعدی.
نمودار رادار5.2%
نمایش بازدیدکنندگان ۶ ماه اخیر
مشاهده کد
1"use client";
2
3import { TrendingUp } from "lucide-react";
4import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from "recharts";
5import {
6 Card, CardContent, CardDescription, CardHeader, CardTitle,
7 Badge, ChartContainer, ChartTooltip, ChartTooltipContent,
8 type ChartConfig,
9} from "@/components/ui";
10
11const chartData = [
12 { month: "فروردین", desktop: 186 },
13 { month: "اردیبهشت", desktop: 305 },
14 { month: "خرداد", desktop: 237 },
15 { month: "تیر", desktop: 273 },
16 { month: "مرداد", desktop: 209 },
17 { month: "شهریور", desktop: 214 },
18];
19
20const chartConfig = {
21 desktop: { label: "دسکتاپ", color: "hsl(var(--chart-1))" },
22} satisfies ChartConfig;
23
24export function StrokeRadarChart() {
25 return (
26 <Card>
27 <CardHeader className="items-center pb-4">
28 <CardTitle>
29 نمودار رادار
30 <Badge variant="outline" className="ms-2">
31 <TrendingUp className="h-4 w-4" /><span>5.2%</span>
32 </Badge>
33 </CardTitle>
34 <CardDescription>نمایش بازدیدکنندگان ۶ ماه اخیر</CardDescription>
35 </CardHeader>
36 <CardContent className="pb-0">
37 <ChartContainer config={chartConfig}
38 className="mx-auto aspect-square max-h-[300px]">
39 <RadarChart data={chartData}>
40 <ChartTooltip cursor={false} content={<ChartTooltipContent />} />
41 <PolarAngleAxis dataKey="month" />
42 <PolarGrid strokeDasharray="3 3" />
43 <Radar stroke="var(--color-desktop)" dataKey="desktop"
44 fill="var(--color-desktop)" fillOpacity={0.1} />
45 </RadarChart>
46 </ChartContainer>
47 </CardContent>
48 </Card>
49 );
50}پشتیبانی RTL (RTL Support)
نمودار با پشتیبانی کامل از جهت راست به چپ.
پشتیبانی RTL
تغییر جهت نمودار بین راستبهچپ و چپبهراست
مشاهده کد
1"use client";
2
3import {
4 ChartContainer, ChartLegend, ChartLegendContent,
5 ChartTooltip, ChartTooltipContent, type ChartConfig,
6 Card, CardContent, CardDescription, CardHeader, CardTitle,
7} from "@/components/ui";
8import { Bar, BarChart, CartesianGrid, XAxis } from "recharts";
9
10export default function ChartRtl() {
11 const dir = "rtl";
12
13 const chartConfig = {
14 desktop: { label: "دسکتاپ", color: "hsl(var(--chart-2))" },
15 mobile: { label: "موبایل", color: "hsl(var(--chart-1))" },
16 } satisfies ChartConfig;
17
18 return (
19 <Card>
20 <CardContent>
21 <div dir={dir}>
22 <ChartContainer config={chartConfig} className="min-h-[300px] w-full">
23 <BarChart accessibilityLayer data={chartData}>
24 <CartesianGrid vertical={false}
25 orientation={dir === "rtl" ? "right" : "left"} />
26 <XAxis dataKey="month" tickLine={false} tickMargin={10}
27 axisLine={false} reversed={dir === "rtl"}
28 />
29 <ChartTooltip content={<ChartTooltipContent />} />
30 <ChartLegend content={<ChartLegendContent />} />
31 <Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
32 <Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
33 </BarChart>
34 </ChartContainer>
35 </div>
36 </CardContent>
37 </Card>
38 );
39}مرجع API (API Reference)
ChartContainer
کانتینر اصلی نمودار که ResponsiveContainer را میپوشاند و متغیرهای CSS برای رنگها را از طریق ChartStyle تزریق میکند.
| پراپ (Prop) | نوع (Type) | پیشفرض (Default) | توضیحات (Description) |
|---|---|---|---|
config | ChartConfig | - | پیکربندی نمودار شامل برچسبها و رنگها |
id | string | auto | شناسه یکتا برای اسکوپ CSS متغیرها |
className | string | - | کلاسهای CSS سفارشی |
ChartTooltipContent
محتوای سفارشی برای تولتیپ نمودار با پشتیبانی از فرمتدهنده سفارشی.
| پراپ (Prop) | نوع (Type) | پیشفرض (Default) | توضیحات (Description) |
|---|---|---|---|
labelKey | string | - | کلید داده برای برچسب |
nameKey | string | - | کلید داده برای نام |
indicator | "dot" | "line" | "dashed" | "dot" | نوع نشانگر |
hideLabel | boolean | false | مخفی کردن برچسب |
hideIndicator | boolean | false | مخفی کردن نشانگر |
formatter | function | - | تابع فرمتدهنده سفارشی برای محتوای تولتیپ |
ChartLegendContent
محتوای سفارشی برای راهنمای نمودار.
| پراپ (Prop) | نوع (Type) | پیشفرض (Default) | توضیحات (Description) |
|---|---|---|---|
nameKey | string | - | کلید داده برای نام |
hideIcon | boolean | false | مخفی کردن آیکون راهنما |
دسترسیپذیری (Accessibility)
لایه دسترسی (Accessibility Layer)
با استفاده از پراپ accessibilityLayer در نمودارهای Recharts، دسترسی با کیبورد و پشتیبانی خواننده صفحه فعال میشود.
پشتیبانی از RTL
برای نمودارهای RTL، از orientation="right" در CartesianGrid و reversed در XAxis استفاده کنید.
بهترین شیوهها (Best Practices)
ارتفاع نمودار
همیشه از min-h-[VALUE] در ChartContainer استفاده کنید تا نمودار به درستی ریسپانسیو شود.
ChartConfig
ChartConfig از داده جدا است و رنگها و برچسبها را تعریف میکند. برای استفاده از رنگهای تم، از hsl(var(--chart-N)) یا var(--color-KEY) استفاده کنید.
ChartStyle و تمها
کامپوننت ChartStyle به صورت خودکار متغیرهای CSS را بر اساس ChartConfig تزریق میکند و از تمهای روشن و تاریک پشتیبانی مینماید.
نحوه استفاده (Usage)
نمونه کامل از نحوه ایمپورت و استفاده از کامپوننت نمودار.
مشاهده کد
1import {
2 ChartContainer,
3 ChartLegend,
4 ChartLegendContent,
5 ChartTooltip,
6 ChartTooltipContent,
7 type ChartConfig,
8} from "@/components/ui/chart";
9import { Bar, BarChart, CartesianGrid, XAxis } from "recharts";
10
11const chartData = [
12 { month: "فروردین", desktop: 186, mobile: 80 },
13 { month: "اردیبهشت", desktop: 305, mobile: 200 },
14 { month: "خرداد", desktop: 237, mobile: 120 },
15 { month: "تیر", desktop: 73, mobile: 190 },
16 { month: "مرداد", desktop: 209, mobile: 130 },
17 { month: "شهریور", desktop: 214, mobile: 140 },
18];
19
20const chartConfig = {
21 desktop: { label: "دسکتاپ", color: "hsl(var(--chart-1))" },
22 mobile: { label: "موبایل", color: "hsl(var(--chart-2))" },
23} satisfies ChartConfig;
24
25export default function MyChart() {
26 return (
27 <ChartContainer config={chartConfig} className="min-h-[300px] w-full">
28 <BarChart accessibilityLayer data={chartData}>
29 <CartesianGrid vertical={false} />
30 <XAxis
31 dataKey="month"
32 tickLine={false}
33 tickMargin={10}
34 axisLine={false}
35 />
36 <ChartTooltip content={<ChartTooltipContent />} />
37 <ChartLegend content={<ChartLegendContent />} />
38 <Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
39 <Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
40 </BarChart>
41 </ChartContainer>
42 );
43}