mcpField
R
recharts-patterns

recharts-patterns

github.com/yonatangross设计与 UI29988 次安装今天更新
代码仓库

关于 recharts-patterns

介绍使用 Recharts 3.x 构建图表的技能指南,该库基于 React 和 D3。内容涵盖常见图表类型、无障碍设计、实时更新、性能优化和实现注意事项。

主要功能

  1. 01创建折线、柱形、饼形和面积图
  2. 02构建自定义提示框
  3. 03应用无障碍设计模式
  4. 04处理实时数据更新
  5. 05提升渲染性能

适用场景

  1. 01按时间展示收入与支出
  2. 02比较销售额或类别总量
  3. 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