关于 recharts-patterns
介绍使用 Recharts 3.x 构建图表的技能指南,该库基于 React 和 D3。内容涵盖常见图表类型、无障碍设计、实时更新、性能优化和实现注意事项。
主要功能
- 01创建折线、柱形、饼形和面积图
- 02构建自定义提示框
- 03应用无障碍设计模式
- 04处理实时数据更新
- 05提升渲染性能
适用场景
- 01按时间展示收入与支出
- 02比较销售额或类别总量
- 03以图表呈现实时指标
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ yonatangross/ orchestkit --skill recharts-patterns安装后在 Claude Code 中输入/recharts-patterns确认已加载。
附带文件references/chart-types.md
详细介绍
Recharts 模式
使用 Recharts 3.x 的数据可视化模式——这是一个基于 React 和 D3 构建的可组合图表库。
核心图表类型
折线图
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
const data = [
{ date: '2024-01', revenue: 4000, expenses: 2400 },
{ date: '2024-02', revenue: 3000, expenses: 1398 },
];
function RevenueChart() {
return (
<ResponsiveContainer width="100%" height={400}>
<LineChart data={data} margin={{ top: 5, right: 30, left: 20, bottom: 5 }}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="date" />
<YAxis />
<Tooltip />
<Legend />
<Line type="monotone" dataKey="revenue" stroke="#8884d8" strokeWidth={2} />
<Line type="monotone" dataKey="expenses" stroke="#82ca9d" strokeDasharray="5 5" />
</LineChart>
</ResponsiveContainer>
);
}
柱状图
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
function SalesChart({ data }: { data: SalesData[] }) {
return (
<ResponsiveContainer width="100%" height={300}>
<BarChart data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Bar dataKey="sales" fill="#8884d8" radius={[4, 4, 0, 0]} />
<Bar dataKey="target" fill="#82ca9d" radius={[4, 4, 0, 0]} />
</BarChart>
</ResponsiveContainer>
);
}
饼图/环形图
import { PieChart, Pie, Cell, ResponsiveContainer, Tooltip, Legend } from 'recharts';
const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042'];
function DeviceChart({ data }: { data: { name: string; value: number }[] }) {
return (
<ResponsiveContainer width="100%" height={300}>
<PieChart>
<Pie
data={data}
cx="50%"
cy="50%"
innerRadius={60}
outerRadius={100}
paddingAngle={2}
dataKey="value"
label={({ name, percent }) => `${name} ${(percent * 100).toFixed(0)}%`}
>
{data.map((entry, index) => (
<Cell key={entry.name} fill={COLORS[index % COLORS.length]} />
))}
</Pie>
<Tooltip />
<Legend />
</PieChart>
</ResponsiveContainer>
);
}
渐变面积图
function TrafficChart({ data }: { data: TrafficData[] }) {
return (
<ResponsiveContainer width="100%" height={300}>
<AreaChart data={data}>
<defs>
<linearGradient id="colorUv" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#8884d8" stopOpacity={0.8} />
<stop offset="95%" stopColor="#8884d8" stopOpacity={0} />
</linearGradient>
</defs>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="time" />
<YAxis />
<Tooltip />
<Area type="monotone" dataKey="visitors" stroke="#8884d8" fill="url(#colorUv)" />
</AreaChart>
</ResponsiveContainer>
);
}
自定义提示框
import { TooltipProps } from 'recharts';
function CustomTooltip({ active, payload, label }: TooltipProps<number, string>) {
if (!active || !payload?.length) return null;
return (
<div className="bg-white p-3 shadow-lg rounded-lg border">
<p className="font-medium text-gray-900">{label}</p>
{payload.map((entry) => (
<p key={entry.name} style={{ color: entry.color }}>
{entry.name}: {entry.value?.toLocaleString()}
</p>
))}
</div>
);
}
// Usage: <Tooltip content={<CustomTooltip />} />
无障碍访问
function AccessibleChart({ data }: { data: ChartData[] }) {
return (
<figure role="img" aria-label="Monthly revenue trend from January to December">
<ResponsiveContainer width="100%" height={400}>
<LineChart data={data}>
<XAxis dataKey="month" />
<YAxis tickFormatter={(value) => `$${value.toLocaleString()}`} />
<Tooltip />
<Line type="monotone" dataKey="revenue" stroke="#8884d8" name="Monthly Revenue" />
</LineChart>
</ResponsiveContainer>
<figcaption className="sr-only">Line chart showing monthly revenue</figcaption>
</figure>
);
}
实时更新
function RealTimeChart() {
const { data } = useQuery({
queryKey: ['metrics'],
queryFn: fetchMetrics,
refetchInterval: 5000,
});
if (!data) return <ChartSkeleton />;
return (
<ResponsiveContainer width="100%" height={300}>
<LineChart data={data}>
<Line type="monotone" dataKey="value" stroke="#8884d8" isAnimationActive={false} dot={false} />
<XAxis dataKey="timestamp" />
<YAxis domain={['auto', 'auto']} />
<Tooltip />
</LineChart>
</ResponsiveContainer>
);
}
性能提示
// Limit data points for smooth rendering
const MAX_POINTS = 500;
const chartData = data.slice(-MAX_POINTS);
// Use dot={false} for many data points
<Line dataKey="value" dot={false} />
// Memoize expensive calculations
const processedData = useMemo(() => processChartData(rawData), [rawData]);
// Disable animation for real-time
<Line isAnimationActive={false} />
反模式(禁止)
// NEVER: ResponsiveContainer without parent dimensions
<div> {/* No height! */}
<ResponsiveContainer width="100%" height="100%"> {/* Won't work */}
</ResponsiveContainer>
</div>
// NEVER: Fixed dimensions on ResponsiveContainer
// NEVER: Animations on real-time charts (causes jank)
// NEVER: Inline data definition in render (new array every render)
// NEVER: Too many data points without limiting (performance issue)
关键决策
| 决策 | 建议 |
|---|---|
| 容器 | 始终使用 ResponsiveContainer |
| 动画 | 对实时数据禁用 |
| 提示框 | 使用自定义提示框,打造品牌化用户体验 |
| 数据更新 | 时间序列使用滑动窗口 |
相关技能
dashboard-patterns- 包含图表的仪表板布局tanstack-query-advanced- 图表数据获取a11y-testing- 测试图表的无障碍访问
评论
支持 Markdown