data-visualization について
ダッシュボードやレポートのデータ可視化を作る開発者向けのスキルです。チャートの選択、レスポンシブな Recharts の実装、アクセシビリティ対応、読み込み中と空の状態を扱います。
主な機能
- 01データに応じたチャート形式の選択
- 02既存のチャートライブラリとデザイントークンの再利用
- 03レスポンシブな Recharts チャートの作成
- 04スクリーンリーダー向けデータ代替の用意
- 05読み込み中と空の状態への対応
活用シーン
- 01ダッシュボードへの傾向チャートの追加
- 02統計値の横に小さなスパークラインを表示
- 03色だけに頼らないチャートのアクセシビリティ改善
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ kensaurus/ skills --skill data-visualizationインストール後、Claude Code で/data-visualizationを入力して読み込まれたか確認します。
同梱ファイルreferences/d3-and-accessibility.mdreferences/recharts.md
詳細
データ可視化スキル
自由度:混在。 グラフの種類とエンコーディングは[高い自由度]、 既存ライブラリ/トークンの調査とアクセシビリティのフォールバックは[低い自由度 — 正確に実行]です。
推論の進め方
- 確認 — 既存のグラフライブラリ、トークン、データの形状
- 解釈 — コンポーネントを再利用するか、新しいグラフの種類を使うか
- 分類 — 折れ線/棒/面/ドーナツ/スパークライン/テーブルへのフォールバック
- 重要度 — アクセシビリティに配慮されていないグラフや空状態がないグラフは、グラデーションの不足より優先度が高いです
実例
確認:
package.jsonに recharts があり、src/components/chartsはありません。トークンには--primaryが定義されています。 解釈: D3 ではなく、Recharts とトークンを再利用します。 分類:ResponsiveContainerの折れ線グラフと sr-only テーブルを使います。読み込み中はスケルトンを表示します。 検証: リサイズに対応し、スクリーンリーダー用のテーブルがあり、2つ目のグラフライブラリはありません。
報告前のセルフチェック
- 既存ライブラリ —
package.jsonを検索し、2つ目のグラフライブラリを追加していません - アクセシビリティ — sr-only テーブルまたはテキストによる代替情報があります
- 状態 — 読み込み中と空の状態に対応しています
- 適切な担当 — イベントの分類体系は
audit-analytics、空/読み込み中のフレームはaudit-ui-statesです
ダッシュボードやレポート向けに、美しく、アクセシブルで、インタラクティブなデータ可視化を作成します。
プロダクトイベントの網羅性(「適切なイベントを追跡できていますか?」)は、このスキルではなく audit-analytics の対象です。グラフの空/読み込み中のフレームは audit-ui-states の対象です。
まず既存のものを確認する [低い自由度 — 正確に実行]
可視化を作成する前に、必ず次を確認します。
- 既存のグラフライブラリを確認します:
cat package.json | grep -i "recharts\|chart\|d3\|visx\|nivo\|tremor"
rg "LineChart|BarChart|PieChart" --type tsx -l | head -10
- 既存のグラフコンポーネントを確認します:
ls -la src/components/charts/ src/components/dashboard/ 2>/dev/null
rg "ResponsiveContainer|Chart" --type tsx | head -10
- デザイントークンを確認します:
cat tailwind.config.* | grep -A10 "chart\|colors"
理由: 既存のグラフライブラリとスタイルの規約を使用します。
Recharts(React に推奨) [高い自由度]
- すべてのグラフを
ResponsiveContainer width="100%"で囲み、固定のheightを設定します。 - トークンでスタイルを指定します:
hsl(var(--primary))、fill-muted-foreground、stroke-mutedを使い、16進数の色はハードコードしません。 - 軸線と目盛り線を非表示にし(
tickLine={false} axisLine={false})、Y軸の目盛りをフォーマットします($、%)。 - カスタム
Tooltipの内容にはbg-background border rounded-lgを使い、テーマに合わせます。 - グラフの種類:折れ線(時間経過による傾向)、棒(
radius={[4,4,0,0]}を指定し、最新のCellを強調)、面(グラデーションの<defs>塗りつぶし)、ドーナツ(innerRadius/outerRadiusと、合計を示す中央のLabel)。
'use client'
import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts'
export function RevenueChart({ data }: { data: { month: string; revenue: number }[] }) {
return (
<ResponsiveContainer width="100%" height={350}>
<LineChart data={data}>
<XAxis dataKey="month" tickLine={false} axisLine={false} className="text-xs fill-muted-foreground" />
<YAxis tickLine={false} axisLine={false} tickFormatter={(v) => `$${v}`} />
<Tooltip cursor={{ stroke: 'hsl(var(--muted))' }} />
<Line type="monotone" dataKey="revenue" stroke="hsl(var(--primary))" strokeWidth={2} activeDot={{ r: 6 }} />
</LineChart>
</ResponsiveContainer>
)
}
カスタムツールチップ付きの折れ線グラフ、棒グラフ、面グラデーション、ドーナツの各コンポーネント全体:references/recharts.md §折れ線グラフ、§棒グラフ、§面グラフ、§円グラフ/ドーナツグラフ。
スパークライン(ミニグラフ) [高い自由度]
Lineを1つだけ使ったLineChartを作成し、dot={false}、strokeWidth={1.5}を指定します。軸は表示せず、高さは約40にします。- コンポーネント内で
number[]を{ index, value }に変換し、呼び出し元からは通常の配列を渡せるようにします。 - 統計値の横にある
w-20の領域に配置し、独立したカードにはしません。
Sparkline コンポーネントと統計カードでの使用方法:references/recharts.md §スパークライン。
傾向を示す統計カード [高い自由度]
rounded-xl border bg-card p-6を使用します。タイトルはtext-muted-foreground、値はtext-3xl font-semiboldにします。- 傾向を示す矢印と
Math.abs(change)%を表示します。上昇は緑、下降は赤にし、スパークラインにも同じ色を渡します。 sparklineDataは省略可能です。データがある場合のみスパークラインを表示します。
StatCard コンポーネント:references/recharts.md §傾向を示す統計カード。
リアルタイムのデータ更新 [高い自由度]
setData(prev => [...prev, point].slice(-N))でデータを追加し、ウィンドウを一定の範囲(約20ポイント)に保ちます。isAnimationActive={false}と固定のYAxis domainを指定し、ティックごとにグラフが跳ねないようにします。- エフェクトのクリーンアップで、インターバルまたはソケットのサブスクリプションを解除します。
RealtimeChart コンポーネント:references/recharts.md §リアルタイムのデータ更新。
カスタムビジュアライゼーション向けの D3.js [自由度:高]
- Recharts ではマークを表現できない場合に限り D3 を使用し、既存のチャートライブラリと併用しないでください。
refを設定した<svg>にuseEffectから描画します。データ変更時に再描画する前にsvg.selectAll('*').remove()を実行してください。- カテゴリーには
scaleBand、値にはscaleLinear().nice()を使用します。サイズはclientWidth/clientHeightから取得し、余白を設けてください。 - ベースラインから
.transition().duration(750)でアニメーションさせ、色には同じhsl(var(--primary))トークンを使用してください。
D3 の棒グラフコンポーネントの全例:references/d3-and-accessibility.md §D3.js custom bar chart。
アクセシビリティ [自由度:低 — 正確に実行]
- グラフを
<div role="img" aria-label="...">で囲み、グラフの内容と範囲を説明してください。 - SVG グラフに
aria-hidden="true"を設定し、データは<caption>を含むsr-onlyの<table>で提供してください。 - 色だけで情報を表さないでください。ラベル、マーカー、凡例を組み合わせてください。
<div role="img" aria-label="Revenue chart showing monthly data from January to December">
<ResponsiveContainer><LineChart data={data} aria-hidden="true">{/* ... */}</LineChart></ResponsiveContainer>
<table className="sr-only">
<caption>Monthly Revenue Data</caption>
<thead><tr><th>Month</th><th>Revenue</th></tr></thead>
<tbody>{data.map((d) => <tr key={d.month}><td>{d.month}</td><td>${d.revenue}</td></tr>)}</tbody>
</table>
</div>
アクセシビリティブロックの全例:references/d3-and-accessibility.md §Accessibility。
検証 [自由度:低 — 省略しないこと]
ビジュアライゼーションを作成した後、次の項目を確認してください。
- レスポンシブ → あらゆる画面サイズでグラフが適切にリサイズされる
- アクセシビリティ → スクリーンリーダー向けの代替手段が用意されている
- パフォーマンス → 大規模なデータセットには仮想化/サンプリングを使用する
- 読み込み状態 → データの読み込み中にスケルトンを表示する
- 空の状態 → データがない場合に意味のあるメッセージを表示する
- 色のコントラスト → WCAG ガイドラインに準拠する
- ツールチップ → ホバー時に詳細なデータを表示する