How to Add shadcn Charts to a Next.js App Without Writing Recharts Boilerplate

TL;DR · AI 摘要
How to Add shadcn Charts to a Next.js App Without Writing Recharts Boilerplate October 2, 2026 / Next.js Ash Charts look...
核心要点
- 主题聚焦:How to Add shadcn Charts to a Next.js App Withou
- 来源:freeCodeCamp.org,建议结合原文判断细节。
- AI 分析暂不可用,本条为保底评分与摘要。
如何在不编写 Recharts 样板代码的情况下将 shadcn 图表添加到 Next.js 应用中
2026 年 10 月 2 日
/
#Next.js
Ash
图表在任务票上看起来像是个小任务。但当你打开 Recharts 文档时,你会想起每个图表都需要多少设置:一个用于标签和颜色的配置对象、坐标轴、提示框、图例、适配深色模式的颜色,以及一个能正确调整大小的容器。我们大多数人都是从上一个项目中复制所有这些代码,然后重命名键。
shadcn/ui 的图表组件减少了部分工作量。它用主题感知的颜色和提示框包装了 Recharts。但你仍然需要手动编写每个图表。
所以我开发了 ChartCN,这是一个免费且开源的 shadcn 图表生成器。你只需粘贴数据、选择图表类型,就能复制一个仅依赖于 shadcn/ui 图表组件和 Recharts 的 TSX 文件。它采用 MIT 许可证,无需注册或安装额外包。
在本教程中,你将学习如何在全新的 Next.js 应用中添加一个收入与支出对比的条形图。我们将逐步解析生成代码的每个部分,然后将图表连接到 Server Component 中加载的数据。该工具帮你节省了输入时间,但第 5 步和第 6 步适用于任何 shadcn/ui 图表,无论你是生成它还是手动编写。
先决条件:你需要熟悉 React 并已安装 Node.js。对 Next.js App Router 有基本了解会有所帮助,但每一步都会详细解释。
目录
- 你将构建的内容
- 步骤 1:创建 Next.js 应用并初始化 shadcn/ui
- 步骤 2:添加 shadcn/ui 图表组件
- 步骤 3:在 ChartCN 中生成图表组件
- 步骤 4:将图表添加到页面
- 步骤 5:理解生成的代码
- 步骤 6:以 prop 形式传递实时数据
- 常见问题及解决方法
- 总结
你将构建的内容
最终你将拥有两个页面:
- / 页面显示一个数据直接写在组件中的分组条形图。这是在屏幕上快速显示图表的最快方式。
- /live 页面显示相同的图表,但数据来自在服务器上运行的异步函数。这是与真实数据库或 API 配合使用的版本。
该图表包含渐变条形、紧凑的坐标轴标签(40K 而非 40000)、图例,以及显示月份总和和各系列占比的提示框。
步骤 1:创建 Next.js 应用并初始化 shadcn/ui
创建新应用并进入目录:
npx create-next-app@latest my-charts-app
cd my-charts-app接受推荐的默认配置。你需要 TypeScript、Tailwind CSS 和 App Router。
接下来初始化 shadcn/ui:
npx shadcn@latest init此命令会执行三个你之后会依赖的操作:
- 创建 components.json 文件,告诉 shadcn/ui CLI 将组件放在哪里。
- 添加 lib/utils.ts 文件,包含 cn() 类合并辅助函数。
- 将主题变量写入 app/globals.css,包括五个图表颜色:--chart-1 到 --chart-5,分别定义了浅色和深色模式的值。
这五个图表变量很重要。每个生成的图表都会使用它们,因此在整个应用中更改图表颜色只需修改一行 CSS。
- ChartTooltip、ChartTooltipContent、ChartLegend 和 ChartLegendContent 是 Recharts 提示框和图例的样式化版本。
在继续之前,请检查已安装的 Recharts 版本:
npm ls rechartsChartCN 生成的代码针对的是 Recharts 3.x 版本。如果你看到的是 2.x 版本,请升级:
npm install recharts@latest要点:shadcn/ui 的图表组件是 Recharts 的薄封装层。它不会替代 Recharts,而是为 Recharts 提供你的主题样式。
第 3 步:在 ChartCN 中生成图表组件
打开 ChartCN 的柱状图页面。数据面板有三个标签页:粘贴数据、上传文件和编辑表格。将以下 CSV 粘贴到「粘贴数据」标签页中:
Month,Revenue,Expenses
Jan,42000,31000
Feb,58000,34000
Mar,51000,29000
Apr,67000,38000
May,72000,41000
Jun,69000,37000ChartCN 会将第一列视为分类轴(柱状图的 x 轴),其余列视为数值序列。JSON、TSV 和 Markdown 表格同样适用,格式会自动检测。
在预览区域上方,设置以下选项:
- 布局:分组
- 提示框:细分
- 代码:内联数据
然后点击预览下方 chart.tsx 面板中的「复制组件」按钮。
第 4 步:将图表添加到页面中
在 components/revenue-chart.tsx 创建新文件,并将复制的代码粘贴进去。
不要保存为 components/ui/chart.tsx。ChartCN 会将输出文件命名为 chart.tsx,但该路径已包含第 2 步中的 shadcn 组件,覆盖会导致应用中所有图表失效。
生成的组件始终导出为 Chart,因此在导入时请使用更清晰的名称。将 app/page.tsx 替换为以下内容:
// app/page.tsx
import { Chart as RevenueChart } from "@/components/revenue-chart"
export default function Home() {
return (
<main className="mx-auto max-w-3xl p-8">
<h1 className="mb-6 text-2xl font-semibold">Revenue vs. expenses</h1>
<RevenueChart />
</main>
)
}运行 npm run dev 并打开 http://localhost:3000。你应该能看到图表。
要点:生成的图表只是项目中的一个组件。无需配置,也不需要维护任何同步的包。
第 5 步:理解生成的代码
现在你拥有这个文件,了解各部分功能很有价值。以下是关键部分(已精简长度):
文件以指令和导入语句开头:
// components/revenue-chart.tsx
"use client"
import { useId } from "react"
import { Bar, BarChart, CartesianGrid, Rectangle, XAxis, YAxis } from "recharts"
import {
type ChartConfig,
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltip,
} from "@/components/ui/chart"Recharts 需要测量 DOM 并处理鼠标事件,因此图表必须是客户端组件。app/page.tsx 可以保持为服务端组件,因为它仅渲染图表。
接下来是数据和配置:
const data = [
{ Month: "Jan", Revenue: 42000, Expenses: 31000 },
{ Month: "Feb", Revenue: 58000, Expenses: 34000 },
// ...
]
const chartConfig = {
Revenue: { label: "Revenue", color: "var(--chart-1)" },
Expenses: { label: "Expenses", color: "var(--chart-2)" },
} satisfies ChartConfigchartConfig 中的键必须与数据中的键匹配。ChartContainer 会读取此配置,并为每个键创建 CSS 变量,作用域限定在该图表:--color-Revenue 和 --color-Expenses。每个变量指向主题颜色,因此图表在暗色模式下会自动切换颜色。
图表本身使用这些变量:
<ChartContainer config={chartConfig} className="aspect-auto h-[350px] w-full">
<BarChart accessibilityLayer data={data} barCategoryGap="30%" barGap={4}>
{/* ...gradient <defs>, grid, axes, tooltip, legend... */}
<Bar
dataKey="Revenue"
fill="var(--color-Revenue)"
shape={(props) => <Rectangle {...props} fill={`url(#${uid}-fill-0)`} />}
radius={[6, 6, 0, 0]}
maxBarSize={36}
/>
</BarChart>
</ChartContainer>有几个细节需要注意:
- 高度由 ChartContainer 上的 h-[350px] 设置。请在此处进行修改。
- 渐变效果通过 shape 属性绘制,而 fill 保持为纯色。这就是为什么图例和提示框的点显示的是干净的纯色而非渐变。
- uid 来自 useId(),因此如果在同一页上渲染两个图表,渐变 ID 会保持唯一。
该文件还包含一个约 70 行的 ChartBreakdownTooltip 组件,用于显示总计和每个系列的百分比。如果您更倾向于使用标准的 shadcn 提示框,请在复制 ChartCN 之前选择 Tooltip: Simple。这样整个文件的行数将从约 120 行减少到约 50 行。
要点:在 shadcn/ui 图表中,颜色从主题变量通过 chartConfig 流入 --color-<key> 变量。一旦理解了这个路径,您就可以手动编辑任何图表。
第 6 步:将实时数据作为 prop 传递
演示中使用硬编码数据是可以接受的。对于真实数据,请返回到 ChartCN,将 Code 切换为 Data as prop,然后再次复制。将此版本保存为 components/revenue-chart-live.tsx。
图表的结构与之前完全相同,仅文件顶部有所变化:数据数组被类型替换,组件接受数据作为 prop:
// components/revenue-chart-live.tsx
export type ChartRow = { Month: string; Revenue: number | null; Expenses: number | null }
export interface ChartProps {
data: ChartRow[]
}
// ...chartConfig 保持不变...
export function Chart({ data }: ChartProps) {
// ...与之前相同的 JSX
}系列数据被定义为 number | null,因为真实数据可能存在缺失值。null 值会渲染为缺失的条形,而不是零值的条形。
现在创建一个在服务器上加载数据的函数:
// lib/get-revenue.ts
import type { ChartRow } from "@/components/revenue-chart-live"
export async function getRevenue(): Promise<ChartRow[]> {
// 请用您的数据库查询或 API 调用替换此代码。
// 例如:const res = await fetch("https://api.example.com/revenue")
return [
{ Month: "Jan", Revenue: 42000, Expenses: 31000 },
{ Month: "Feb", Revenue: 58000, Expenses: 34000 },
{ Month: "Mar", Revenue: 51000, Expenses: 29000 },
{ Month: "Apr", Revenue: 67000, Expenses: 38000 },
{ Month: "May", Revenue: 72000, Expenses: null },
]
}然后从服务器组件页面调用它:
// app/live/page.tsx
import { Chart as RevenueChart } from "@/components/revenue-chart-live"
import { getRevenue } from "@/lib/get-revenue"
export default async function LivePage() {
const data = await getRevenue()
return (
<main className="mx-auto max-w-3xl p-8">
<h1 className="mb-6 text-2xl font-semibold">收入 vs. 支出</h1>
<RevenueChart data={data} />
</main>
)
}打开 http://localhost:3000/live。由于该值为 null,5 月会显示一个收入条形,旁边没有支出条形。
要点:在 Server Component 中加载数据,在 Client Component 中进行渲染。导出的 ChartRow 类型使 TypeScript 检查你的数据是否符合图表预期。
常见问题及解决方法
出现 "Property 'itemSorter' does not exist" 等类型错误。你的项目安装了 Recharts 2。运行 npm install recharts@latest 升级到 Recharts 3。
柱状图是黑色且图例圆点缺失。你的 app/globals.css 没有定义 --chart-1 到 --chart-5。再次运行 npx shadcn@latest init,或从 shadcn/ui 主题文档复制图表变量。
粘贴图表后所有图表停止工作。你可能覆盖保存了 components/ui/chart.tsx 文件。通过 npx shadcn@latest add chart --overwrite 恢复文件,并将图表保存为不同名称。
同一页的两个图表名称相同。所有生成的组件都导出为 Chart。导入时重命名,例如 import { Chart as SignupsChart } from "@/components/signups-chart" 。
总结
- shadcn/ui 图表组件为主题化 Recharts 提供支持。它不会替换 Recharts,ChartCN 的输出需要 Recharts 3。
- 颜色通过 CSS 变量传递。--chart-1 通过 chartConfig 变为 --color-Revenue,因此无需额外代码即可支持暗色模式。
- 将生成的图表保存为独立名称。components/ui/chart.tsx 属于 shadcn/ui。
- 使用 Data 属性传递真实数据。在 Server Component 中加载数据,将类型化行传递给图表。
- null 表示 "无数据"。空白区域渲染为间隙而非零值。
由于 ChartCN 是一个 shadcn 图表生成器而非组件库,因此没有需要安装或更新的 ChartCN 包。你可以浏览它支持的全部 13 个 shadcn 图表,包括折线图、面积图、饼图、雷达图、KPI 卡片、瀑布图和热力图。它们都遵循你在此处使用的粘贴、选择和复制工作流程。
源代码在 GitHub 上,采用 MIT 许可证。如果对你有帮助,给项目加星有助于其他开发者发现它。
合作伙伴推荐课程
(opens in a new tab)
ADVERTISEMENT
- Coursera 上的 SwiftUI 高级 UI 组件与数据可视化课程 Packt - 课程讲师 5周 5 weeks, 3小时/周 中级 证书 查看课程 (opens in a new tab)
- Coursera 上的使用 Swift 和图表构建 iOS 股票交易应用 EDUCBA 3周 3 weeks, 3小时/周 中级 证书 查看课程 (opens in a new tab)
- Udemy 上的完整应用设计课程 - UX、UI 和设计思维 App Brewery Co. 4.4(满分5星) 12,037 人评价 3小时5分钟 初级 证书 查看课程 (opens in a new tab)
- Coursera 上的数据持久化与 Firebase 集成课程 Packt - 课程讲师 3周 3 weeks, 3小时/周 中级 证书 查看课程 (opens in a new tab)
更多 UI 设计课程请访问 Class Central
→
阅读更多文章 .
如果你读到这里,请感谢作者以表达你的支持。说声谢谢
免费学习编程。freeCodeCamp 的开源课程已帮助超过 40,000 人成为开发者。立即开始