SCALE — Build Lab
開発パターン · REACT PATTERN

Rechartsグラフパターン

CATEGORY開発パターン TYPEReact Pattern EFFORT90〜240分 DIFFICULTY
PRIMARY CODE
tsx
'use client';
import { LineChart, Line, BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid, Legend } from 'recharts';

// ダーク対応のカスタムツールチップ
function DarkTooltip({ active, payload, label }: any) {
  if (!active || !payload?.length) return null;
  return (
    <div className="bg-zinc-900 border border-zinc-700 rounded-lg p-3 text-xs">
      <p className="text-zinc-400 mb-1">{label}</p>
      {payload.map((p: any, i: number) => (
        <p key={i} style={{ color: p.color }}>{p.name}: {p.value.toLocaleString()}</p>
      ))}
    </div>
  );
}

export function MonthlyLineChart({ data }: { data: { month: string; revenue: number; profit?: number }[] }) {
  return (
    <ResponsiveContainer width="100%" height={300}>
      <LineChart data={data}>
        <CartesianGrid stroke="#27272a" strokeDasharray="3 3" />
        <XAxis dataKey="month" stroke="#71717a" fontSize={11} />
        <YAxis stroke="#71717a" fontSize={11} tickFormatter={(v) => `¥${(v / 1000).toFixed(0)}k`} />
        <Tooltip content={<DarkTooltip />} />
        <Legend />
        <Line type="monotone" dataKey="revenue" stroke="#818cf8" strokeWidth={2} dot={{ r: 3 }} name="売上" />
        {data[0]?.profit !== undefined && (
          <Line type="monotone" dataKey="profit" stroke="#34d399" strokeWidth={2} dot={{ r: 3 }} name="利益" />
        )}
      </LineChart>
    </ResponsiveContainer>
  );
}

export function CategoryBarChart({ data }: { data: { name: string; value: number }[] }) {
  return (
    <ResponsiveContainer width="100%" height={300}>
      <BarChart data={data}>
        <CartesianGrid stroke="#27272a" strokeDasharray="3 3" />
        <XAxis dataKey="name" stroke="#71717a" fontSize={11} />
        <YAxis stroke="#71717a" fontSize={11} />
        <Tooltip content={<DarkTooltip />} />
        <Bar dataKey="value" fill="#a78bfa" radius={[4, 4, 0, 0]} />
      </BarChart>
    </ResponsiveContainer>
  );
}
前提条件
Tailwind CSS v4TypeScript 5
USE CASES
  • ダッシュボード全般

Rechartsグラフパターン

:LiTarget: 用途

Recharts で売上・KPI等のグラフを綺麗に描画するパターン集。

:LiSparkle: 特徴

  • 折れ線
  • ツールチップカスタム
  • ダーク対応

:LiCode: コード(コピペ用)

'use client';
import { LineChart, Line, BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid, Legend } from 'recharts';

// ダーク対応のカスタムツールチップ
function DarkTooltip({ active, payload, label }: any) {
  if (!active || !payload?.length) return null;
  return (
    <div className="bg-zinc-900 border border-zinc-700 rounded-lg p-3 text-xs">
      <p className="text-zinc-400 mb-1">{label}</p>
      {payload.map((p: any, i: number) => (
        <p key={i} style={{ color: p.color }}>{p.name}: {p.value.toLocaleString()}</p>
      ))}
    </div>
  );
}

export function MonthlyLineChart({ data }: { data: { month: string; revenue: number; profit?: number }[] }) {
  return (
    <ResponsiveContainer width="100%" height={300}>
      <LineChart data={data}>
        <CartesianGrid stroke="#27272a" strokeDasharray="3 3" />
        <XAxis dataKey="month" stroke="#71717a" fontSize={11} />
        <YAxis stroke="#71717a" fontSize={11} tickFormatter={(v) => `¥${(v / 1000).toFixed(0)}k`} />
        <Tooltip content={<DarkTooltip />} />
        <Legend />
        <Line type="monotone" dataKey="revenue" stroke="#818cf8" strokeWidth={2} dot={{ r: 3 }} name="売上" />
        {data[0]?.profit !== undefined && (
          <Line type="monotone" dataKey="profit" stroke="#34d399" strokeWidth={2} dot={{ r: 3 }} name="利益" />
        )}
      </LineChart>
    </ResponsiveContainer>
  );
}

export function CategoryBarChart({ data }: { data: { name: string; value: number }[] }) {
  return (
    <ResponsiveContainer width="100%" height={300}>
      <BarChart data={data}>
        <CartesianGrid stroke="#27272a" strokeDasharray="3 3" />
        <XAxis dataKey="name" stroke="#71717a" fontSize={11} />
        <YAxis stroke="#71717a" fontSize={11} />
        <Tooltip content={<DarkTooltip />} />
        <Bar dataKey="value" fill="#a78bfa" radius={[4, 4, 0, 0]} />
      </BarChart>
    </ResponsiveContainer>
  );
}

:LiHandPointer: 使い方

対象プロジェクトに該当ファイルをコピーして、props を流し込むだけ。

:LiAlertCircle: 注意事項

  • 依存パッケージを忘れず追加