127k

图表 Chart

漂亮的图表。使用 Recharts 构建。可复制粘贴到你的应用中。

Bar Chart - Interactive
Showing total visitors for the last 3 months

介绍 Charts(图表)。一组可复制粘贴到您的应用中的图表组件。

图表设计即开即用,外观优美。它们可与其它组件良好协作,并且完全可定制以适应您的项目。

浏览图表库。

组件

底层我们使用了 Recharts。

我们设计 chart 组件时考虑了组合性。您可以使用 Recharts 组件构建图表,仅在需要时引入自定义组件,如 ChartTooltip。

import { Bar, BarChart } from "recharts"
 
import { ChartContainer, ChartTooltipContent } from "@/components/ui/chart"
 
export function MyChart() {
  return (
    <ChartContainer>
      <BarChart data={data}>
        <Bar dataKey="value" />
        <ChartTooltip content={<ChartTooltipContent />} />
      </BarChart>
    </ChartContainer>
  )
}

我们不对 Recharts 进行封装。这意味着您不会被抽象层锁定。当 Recharts 发布新版本时,您可以按照官方升级路径更新图表。

这些组件属于您。

Updating to Recharts v3

If you're updating older chart code to Recharts v3:

  • Use var(--chart-1) instead of hsl(var(--chart-1)) when you reference chart tokens from your CSS variables.
  • Use ChartTooltip.defaultIndex for initial tooltip state only. Keep persistent active shapes in your own chart state.
  • Remove layout from <Bar> when the parent <BarChart> already defines it.
  • Keep a height, min-h-*, or aspect-* on ChartContainer so ResponsiveContainer can measure on first render.

Installation

pnpm dlx shadcn@latest add chart

你的第一个图表

让我们构建你的第一个图表。我们将创建一个柱状图,添加网格、坐标轴、提示和图例。

首先定义数据

以下数据表示每个月的桌面和移动用户数量。

components/example-chart.tsx
const chartData = [
  { month: "January", desktop: 186, mobile: 80 },
  { month: "February", desktop: 305, mobile: 200 },
  { month: "March", desktop: 237, mobile: 120 },
  { month: "April", desktop: 73, mobile: 190 },
  { month: "May", desktop: 209, mobile: 130 },
  { month: "June", desktop: 214, mobile: 140 },
]

定义图表配置

图表配置包含图表的配置项。这里是放置可读标签、图标及主题色令牌的地方。

components/example-chart.tsx
import { type ChartConfig } from "@/components/ui/chart"
 
const chartConfig = {
  desktop: {
    label: "桌面",
    color: "#2563eb",
  },
  mobile: {
    label: "移动",
    color: "#60a5fa",
  },
} satisfies ChartConfig

构建图表

现在你可以使用 Recharts 组件构建你的图表了。

"use client"

import { Bar, BarChart } from "recharts"

添加网格

让我们为图表添加网格。

导入 CartesianGrid 组件。

import { Bar, BarChart, CartesianGrid } from "recharts"

将 CartesianGrid 组件添加到图表中。

<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
  <BarChart accessibilityLayer data={chartData}>
    <CartesianGrid vertical={false} />
    <Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
    <Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
  </BarChart>
</ChartContainer>
"use client"

import { Bar, BarChart, CartesianGrid } from "recharts"

添加坐标轴

为了给图表添加 x 轴,我们使用 XAxis 组件。

导入 XAxis 组件。

import { Bar, BarChart, CartesianGrid, XAxis } from "recharts"

将 XAxis 组件添加到图表中。

<ChartContainer config={chartConfig} className="h-[200px] w-full">
  <BarChart accessibilityLayer data={chartData}>
    <CartesianGrid vertical={false} />
    <XAxis
      dataKey="month"
      tickLine={false}
      tickMargin={10}
      axisLine={false}
      tickFormatter={(value) => value.slice(0, 3)}
    />
    <Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
    <Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
  </BarChart>
</ChartContainer>
"use client"

import { Bar, BarChart, CartesianGrid, XAxis } from "recharts"

添加提示框

到目前为止我们只使用了 Recharts 组件。得益于 chart 组件中的一些定制,它们开箱即用,外观漂亮。

要添加提示框,我们将使用 chart 包中自定义的 ChartTooltip 和 ChartTooltipContent 组件。

导入 ChartTooltip 和 ChartTooltipContent 组件。

import { ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"

将组件添加到图表中。

<ChartContainer config={chartConfig} className="h-[200px] w-full">
  <BarChart accessibilityLayer data={chartData}>
    <CartesianGrid vertical={false} />
    <XAxis
      dataKey="month"
      tickLine={false}
      tickMargin={10}
      axisLine={false}
      tickFormatter={(value) => value.slice(0, 3)}
    />
    <ChartTooltip content={<ChartTooltipContent />} />
    <Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
    <Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
  </BarChart>
</ChartContainer>
"use client"

import { Bar, BarChart, CartesianGrid, XAxis } from "recharts"

将鼠标悬停以查看提示框。简单吧?只需两个组件,即可拥有漂亮的提示框。

添加图例

图例同理。我们使用 chart 里的 ChartLegend 和 ChartLegendContent 组件。

导入 ChartLegend 和 ChartLegendContent 组件。

import { ChartLegend, ChartLegendContent } from "@/components/ui/chart"

将组件添加到图表中。

<ChartContainer config={chartConfig} className="h-[200px] w-full">
  <BarChart accessibilityLayer data={chartData}>
    <CartesianGrid vertical={false} />
    <XAxis
      dataKey="month"
      tickLine={false}
      tickMargin={10}
      axisLine={false}
      tickFormatter={(value) => value.slice(0, 3)}
    />
    <ChartTooltip content={<ChartTooltipContent />} />
    <ChartLegend content={<ChartLegendContent />} />
    <Bar dataKey="desktop" fill="var(--color-desktop)" radius={4} />
    <Bar dataKey="mobile" fill="var(--color-mobile)" radius={4} />
  </BarChart>
</ChartContainer>
"use client"

import { Bar, BarChart, CartesianGrid, XAxis } from "recharts"

完成!你已经构建了你的第一个图表!接下来呢?

图表配置

图表配置用于定义图表的标签、图标和颜色。

它有意与图表数据分离。

这样可以在多个图表之间共享配置和颜色标记。对于数据或颜色标记存储在远程或不同格式的情况,也可以独立工作。

import { Monitor } from "lucide-react"
 
import { type ChartConfig } from "@/components/ui/chart"
 
const chartConfig = {
  desktop: {
    label: "桌面",
    icon: Monitor,
    // 颜色,如 'hsl(220, 98%, 61%)' 或 'var(--color-name)'
    color: "#2563eb",
    // 或主题对象,含 'light' 和 'dark' 键
    theme: {
      light: "#2563eb",
      dark: "#dc2626",
    },
  },
} satisfies ChartConfig

主题定制

图表内置了主题支持。你可以使用 CSS 变量(推荐)或任何颜色格式的颜色值,如 hex、hsl 或 oklch。

CSS 变量

在 CSS 文件中定义颜色

app/globals.css
@layer base {
  :root {
    --chart-1: oklch(0.646 0.222 41.116);
    --chart-2: oklch(0.6 0.118 184.704);
  }
 
  .dark {
    --chart-1: oklch(0.488 0.243 264.376);
    --chart-2: oklch(0.696 0.17 162.48);
  }
}

在 chartConfig 中添加颜色

components/example-chart.tsx
const chartConfig = {
  desktop: {
    label: "桌面",
    color: "var(--chart-1)",
  },
  mobile: {
    label: "移动",
    color: "var(--chart-2)",
  },
} satisfies ChartConfig

hex、hsl 或 oklch

您也可以直接在图表配置中定义颜色,使用您喜欢的颜色格式。

components/example-chart.tsx
const chartConfig = {
  desktop: {
    label: "桌面",
    color: "#2563eb",
  },
  mobile: {
    label: "Mobile",
    color: "hsl(220, 98%, 61%)",
  },
  tablet: {
    label: "Tablet",
    color: "oklch(0.5 0.2 240)",
  },
  laptop: {
    label: "Laptop",
    color: "var(--chart-2)",
  },
} satisfies ChartConfig

使用颜色

要在图表中使用主题颜色,请用 var(--color-KEY) 格式引用颜色。

组件中

<Bar dataKey="desktop" fill="var(--color-desktop)" />

图表数据中

components/example-chart.tsx
const chartData = [
  { browser: "chrome", visitors: 275, fill: "var(--color-chrome)" },
  { browser: "safari", visitors: 200, fill: "var(--color-safari)" },
]

Tailwind 中

components/example-chart.tsx
<LabelList className="fill-(--color-desktop)" />

提示框

图表提示框包含标签、名称、指示器和值。您可以组合使用这些元素定制提示框。

Label
Page Views
Desktop
186
Mobile
80
Name
Chrome
1,286
Firefox
1,000
Page Views
Desktop
12,486
Indicator
Chrome
1,286

您可以使用 hideLabel、hideIndicator 这类属性打开或关闭标签和指示符,或者用 indicator 属性定制指示符样式。

使用 labelKey 和 nameKey 可定制提示框标签和名称的对应键。

Chart 内置了 <ChartTooltip> 和 <ChartTooltipContent> 组件,可用来为图表添加自定义提示框。

components/example-chart.tsx
import { ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
components/example-chart.tsx
<ChartTooltip content={<ChartTooltipContent />} />

属性

用以下属性来自定义提示框:

属性类型描述
labelKeystring用于标签的配置或数据键。
nameKeystring用于名称的配置或数据键。
indicatordot、line 或 dashed提示框指示符的样式。
hideLabelboolean是否隐藏标签。
hideIndicatorboolean是否隐藏指示符。

颜色

颜色会自动从图表配置中引用。

自定义

使用 labelKey 和 nameKey 属性来指定自定义的提示框标签和名称键。

const chartData = [
  { browser: "chrome", visitors: 187, fill: "var(--color-chrome)" },
  { browser: "safari", visitors: 200, fill: "var(--color-safari)" },
]
 
const chartConfig = {
  visitors: {
    label: "总访客数",
  },
  chrome: {
    label: "Chrome",
    color: "var(--chart-1)",
  },
  safari: {
    label: "Safari",
    color: "var(--chart-2)",
  },
} satisfies ChartConfig
components/example-chart.tsx
<ChartTooltip
  content={<ChartTooltipContent labelKey="visitors" nameKey="browser" />}
/>

这会为标签使用“总访客数”,并为提示框名称使用“Chrome”和“Safari”。

图例

您可以使用自定义的 <ChartLegend> 和 <ChartLegendContent> 组件为图表添加图例。

components/example-chart.tsx
import { ChartLegend, ChartLegendContent } from "@/components/ui/chart"
components/example-chart.tsx
<ChartLegend content={<ChartLegendContent />} />

颜色

颜色会自动从图表配置中引用。

自定义

使用 nameKey 属性来指定自定义的图例名称键。

const chartData = [
  { browser: "chrome", visitors: 187, fill: "var(--color-chrome)" },
  { browser: "safari", visitors: 200, fill: "var(--color-safari)" },
]
 
const chartConfig = {
  chrome: {
    label: "Chrome",
    color: "var(--chart-1)",
  },
  safari: {
    label: "Safari",
    color: "var(--chart-2)",
  },
} satisfies ChartConfig
components/example-chart.tsx
<ChartLegend content={<ChartLegendContent nameKey="browser" />} />

这会将“Chrome”和“Safari”用作图例名称。

无障碍支持

您可以开启 accessibilityLayer 属性为图表添加可访问层。

该属性为图表添加键盘访问和屏幕阅读器支持。

components/example-chart.tsx
<LineChart accessibilityLayer />

RTL

要在 shadcn/ui 中启用 RTL 支持,请参阅 RTL 配置指南。

"use client"

import { Bar, BarChart, CartesianGrid, XAxis } from "recharts"