111k

Chart

漂亮的图表。基于 Recharts 构建,可直接复制到你的应用中。

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

推出 Charts。这是一组可以直接复制到应用中的图表组件。 Charts 的设计目标是开箱即用也很好看。它们能与其他组件良好协作,并且可以完全自定义以适配你的项目。 浏览 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 版本发布时,你可以按照官方升级路径来升级图表。 组件属于你自己

更新到 Recharts v3

如果你要将旧版图表代码升级到 Recharts v3:

  • 当你从 CSS 变量中引用图表 token 时,使用 var(--chart-1),而不是 hsl(var(--chart-1))
  • ChartTooltip.defaultIndex 只用于 tooltip 的初始状态。请把持久的激活状态保留在你自己的图表状态中。
  • 当父级 <BarChart> 已经定义了布局时,移除 <Bar> 上的 layout
  • ChartContainer 上保留高度、min-h-*aspect-*,这样 ResponsiveContainer 才能在首次渲染时进行测量。

安装

pnpm dlx shadcn@latest add chart

你的第一个图表

让我们来构建你的第一个图表。我们会创建一个柱状图,并添加网格、坐标轴、tooltip 和图例。

先定义你的数据

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

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 },
]

定义你的图表配置

图表配置用于保存图表的配置。你可以在这里放置人类可读字符串,例如标签、图标和用于主题化的颜色 token。

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

构建你的图表

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

"use client"

import { ChartContainer, type ChartConfig } from "@/components/ui/chart"

添加网格

让我们给图表添加网格。

导入 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 { ChartContainer, type ChartConfig } from "@/components/ui/chart"

添加坐标轴

要给图表添加 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 { ChartContainer, type ChartConfig } from "@/components/ui/chart"

添加 Tooltip

到目前为止,我们只使用了 Recharts 的组件。得益于 chart 组件中的一些自定义,它们开箱即用就很好看。

要添加 tooltip,我们会使用 chart 中的自定义 ChartTooltipChartTooltipContent 组件。

导入 ChartTooltipChartTooltipContent 组件。

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

Add the components to your 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 {

悬停即可查看 tooltip。很简单吧?只用两个组件,我们就有了漂亮的 tooltip。

添加图例

图例也同样处理。我们会使用 chart 中的 ChartLegendChartLegendContent 组件。

导入 ChartLegendChartLegendContent 组件。

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

Add the components to your 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 {

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

图表配置

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

它被刻意设计为与图表数据解耦。

这样你就可以在多个图表之间共享配置和颜色 token。即使你的数据或颜色 token 存放在远端,或者格式不同,它也能独立工作。

import { Monitor } from "lucide-react"
 
import { type ChartConfig } from "@/components/ui/chart"
 
const chartConfig = {
  desktop: {
    label: "Desktop",
    icon: Monitor,
    // A color like 'hsl(220, 98%, 61%)' or 'var(--color-name)'
    color: "#2563eb",
    // OR a theme object with 'light' and 'dark' keys
    theme: {
      light: "#2563eb",
      dark: "#dc2626",
    },
  },
} satisfies ChartConfig

主题化

Charts 原生支持主题化。你可以使用 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: "Desktop",
    color: "var(--chart-1)",
  },
  mobile: {
    label: "Mobile",
    color: "var(--chart-2)",
  },
} satisfies ChartConfig

hex、hsl 或 oklch

你也可以直接在图表配置中定义颜色。使用你偏好的颜色格式即可。

components/example-chart.tsx
const chartConfig = {
  desktop: {
    label: "Desktop",
    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

你可以通过 hideLabelhideIndicator 属性控制这些内容的显示与隐藏,并通过 indicator 属性自定义指示器样式。

使用 labelKeynameKey 可以为提示的标签和名称指定自定义键。

chart 提供了 <ChartTooltip><ChartTooltipContent> 组件。你可以用这两个组件为图表添加自定义提示。

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

属性

使用以下属性来自定义 tooltip。

PropTypeDescription
labelKeystring用于标签的配置键或数据键。
nameKeystring用于名称的配置键或数据键。
indicatordot line or dashedtooltip 的指示器样式。
hideLabelboolean是否隐藏标签。
hideIndicatorboolean是否隐藏指示器。

Colors

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

Custom

要为 tooltip 的标签和名称使用自定义键,请使用 labelKeynameKey 属性。

const chartData = [
  { browser: "chrome", visitors: 187, fill: "var(--color-chrome)" },
  { browser: "safari", visitors: 200, fill: "var(--color-safari)" },
]
 
const chartConfig = {
  visitors: {
    label: "Total Visitors",
  },
  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" />}
/>

这样会将 总访问量 用作标签,并将 ChromeSafari 用作 tooltip 名称。

图例

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

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

Colors

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

Custom

要为图例名称使用自定义键,请使用 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" />} />

这样会将 ChromeSafari 用作图例名称。

无障碍

你可以开启 accessibilityLayer 属性,为图表添加无障碍层。

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

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

RTL

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

"use client"

import {