关于 chart-implementation
为使用 Recharts 和 shadcn/ui 的开发者提供图表实现指导,统一组件布局、主题配置与性能实践。
主要功能
- 01基于 ChartContainer 和 ChartWidget
- 02使用 CSS 变量配置颜色
- 03配置图例与提示标签
- 04对数据和配置进行记忆化
适用场景
- 01在应用中构建统一样式的图表
- 02为图表设置主题、标签和提示框
- 03减少图表数据转换的重复计算
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ motormetrics/ motormetrics --skill chart-implementation安装后在 Claude Code 中输入/chart-implementation确认已加载。
详细介绍
图表实现技能
使用 shadcn/ui 的 ChartContainer,通过 Recharts 实现数据可视化。始终使用 CSS 变量设置颜色(参见 design-language-system 技能)。
核心模式
所有图表都使用 @sgcarstrends/ui/components/chart 中的 ChartContainer,并将其放在 @web/components/charts/widget 中的 ChartWidget 里。绝不直接使用原始 ResponsiveContainer。
"use client";
import {
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@sgcarstrends/ui/components/chart";
import { ChartWidget } from "@web/components/charts/widget";
import { BarChart, Bar, CartesianGrid, XAxis, YAxis } from "recharts";
export function TopMakesChart({ data }: { data: { make: string; count: number }[] }) {
const chartConfig = {
count: { label: "Count", color: "var(--chart-1)" },
};
return (
<ChartWidget title="Top Makes" isEmpty={data.length === 0}>
<ChartContainer config={chartConfig} className="h-[300px] w-full">
<BarChart data={data}>
<CartesianGrid vertical={false} strokeDasharray="3 3" className="stroke-default-200" />
<XAxis dataKey="make" tickLine={false} axisLine={false} className="text-xs" />
<YAxis tickLine={false} axisLine={false} className="text-xs" />
<ChartTooltip content={<ChartTooltipContent />} />
<Bar dataKey="count" fill="var(--chart-1)" radius={[8, 8, 0, 0]} />
</BarChart>
</ChartContainer>
</ChartWidget>
);
}
ChartContainer
ChartContainer 为 Recharts 的 ResponsiveContainer 添加了主题支持。通过容器上的 CSS 类设置尺寸:
// ✅ Correct - height via className
<ChartContainer config={chartConfig} className="h-[300px] w-full">
<BarChart data={data}>...</BarChart>
</ChartContainer>
// ❌ Wrong - raw ResponsiveContainer
<ResponsiveContainer width="100%" height={400}>
<BarChart data={data}>...</BarChart>
</ResponsiveContainer>
宽度/高度 -1 警告
在首次渲染时,ResizeObserver 尚未触发,Recharts 的 ResponsiveContainer 会记录 width(-1) and height(-1) 警告。可在 packages/ui/src/components/chart.tsx 中的 ResponsiveContainer 上设置 initialDimension 来解决:
<RechartsPrimitive.ResponsiveContainer initialDimension={{ width: 0, height: 400 }}>
{children}
</RechartsPrimitive.ResponsiveContainer>
参考:shadcn/ui PR #8486、recharts #6716
ChartWidget
将图表包装在 Card 中,并提供标题、副标题、空状态和入场动画:
<ChartWidget
title="Registration Trends"
subtitle="Monthly breakdown"
isEmpty={data.length === 0}
emptyMessage="No trend data available"
>
<ChartContainer ...>...</ChartContainer>
</ChartWidget>
图表配置
定义图表配置,为主题、图例和工具提示提供标签:
const chartConfig = {
diesel: { label: "Diesel", color: "var(--chart-1)" },
petrol: { label: "Petrol", color: "var(--chart-2)" },
electric: { label: "Electric", color: "var(--chart-3)" },
};
性能
对数据和配置进行记忆化
const chartConfig = useMemo(() => {
return Object.fromEntries(
categories.map((category, index) => [
category,
{ label: category, color: `var(--chart-${index + 1})` },
]),
);
}, [categories]);
最佳实践
- ChartContainer - 始终使用
className="h-[300px] w-full"的ChartContainer(绝不使用原始ResponsiveContainer) - ChartWidget - 使用
ChartWidget包装,以确保卡片布局和空状态保持一致 - CSS 变量 - 使用
var(--chart-N)设置颜色(可用范围:1-6) - 坐标轴样式 - 使用
tickLine={false} axisLine={false} className="text-xs",让坐标轴更简洁 - 网格 - 使用
<CartesianGrid vertical={false} strokeDasharray="3 3" className="stroke-default-200" /> - 工具提示 - 使用 shadcn 的
<ChartTooltip content={<ChartTooltipContent />} /> - 记忆化 - 使用
useMemo处理图表配置和数据转换
参考
- Recharts:使用 Context7 查看最新文档
- Design Language System:颜色请参阅
design-language-system技能 - 图表组件源码:
packages/ui/src/components/chart.tsx - Widget 组件:
apps/web/src/components/charts/widget.tsx
评论
支持 Markdown