ウォーターフォールチャートライブラリ比較

3つのアプローチで収益・コストの増減を段階的に表示し、実装方法とスタイルを比較

📊 使用しているサンプルデータ

月次損益のウォーターフォールデータです。売上高から始まり各コスト項目を差し引いて最終利益(純利益)を表示します。 typeで「start」「increase」「decrease」「total」を区別しています。

[
  {
    "name": "売上高",
    "value": 10000,
    "type": "start"
  },
  {
    "name": "売上原価",
    "value": -3800,
    "type": "decrease"
  },
  {
    "name": "粗利益",
    "value": 6200,
    "type": "total"
  },
  {
    "name": "人件費",
    "value": -2100,
    "type": "decrease"
  },
  {
    "name": "広告費",
    "value": -800,
    "type": "decrease"
  },
  {
    "name": "その他経費",
    "value": -400,
    "type": "decrease"
  },
  {
    "name": "営業利益",
    "value": 2900,
    "type": "total"
  },
  {
    "name": "営業外収益",
    "value": 300,
    "type": "increase"
  },
  {
    "name": "営業外費用",
    "value": -200,
    "type": "decrease"
  },
  {
    "name": "純利益",
    "value": 3000,
    "type": "total"
  }
]

1. Recharts(カスタム実装)

Rechartsにはウォーターフォール専用コンポーネントはないが、ComposedChartとBarを組み合わせたカスタム実装で実現可能。 各バーの開始位置をstackIdと透明バーで制御し、増加・減少・合計で色を使い分ける。Reactの宣言的APIで実装コードが読みやすい。

✓ ComposedChartベース✓ 宣言的API✓ カスタマイズ容易
特徴: ComposedChartとstackIdを組み合わせ、透明バーで各バーの開始位置を制御。 Cellコンポーネントでtype別に個別の色を適用する。
tsx
'use client';
import {
  ComposedChart, Bar, XAxis, YAxis, CartesianGrid,
  Tooltip, Cell, ResponsiveContainer,
} from 'recharts';

const rawData = [
  { name: '前期末', value: 5000, type: 'total' },
  { name: '新規顧客', value: 2200, type: 'increase' },
  { name: '解約', value: -800, type: 'decrease' },
  { name: 'アップセル', value: 1500, type: 'increase' },
  { name: 'コスト増', value: -600, type: 'decrease' },
  { name: '今期末', value: 7300, type: 'total' },
];

function buildWaterfallData(data: typeof rawData) {
  let cumulative = 0;
  return data.map((d) => {
    if (d.type === 'total') {
      cumulative = d.value;
      return { ...d, base: 0, barValue: d.value };
    }
    const base = d.value < 0 ? cumulative + d.value : cumulative;
    const barValue = Math.abs(d.value);
    cumulative += d.value;
    return { ...d, base, barValue };
  });
}

const chartData = buildWaterfallData(rawData);

const getColor = (type: string) =>
  type === 'total' ? '#6b7280' : type === 'increase' ? '#10b981' : '#ef4444';

export function RechartsWaterfallChart() {
  return (
    <ResponsiveContainer width="100%" height={300}>
      <ComposedChart data={chartData} margin={{ top: 20, right: 20, bottom: 20, left: 60 }}>
        <CartesianGrid strokeDasharray="3 3" vertical={false} />
        <XAxis dataKey="name" tick={{ fontSize: 11 }} />
        <YAxis />
        <Tooltip formatter={(v, name) => name === 'base' ? null : [v, '金額']} />
        <Bar dataKey="base" stackId="stack" fill="transparent" />
        <Bar dataKey="barValue" stackId="stack" radius={[3, 3, 0, 0]}>
          {chartData.map((entry, i) => (
            <Cell key={i} fill={getColor(entry.type)} />
          ))}
        </Bar>
      </ComposedChart>
    </ResponsiveContainer>
  );
}

🤖 AIプロンプトテンプレート

React + Tailwind CSSで、Rechartsを使ったウォーターフォールチャートを実装してください。

- 使用ライブラリ: recharts の ComposedChart、Bar、Cell、YAxis、ResponsiveContainer
- サンプルデータ: 月次損益10項目(売上高から純利益まで)を用意すること
- 実装方法: stackIdと透明バー(fill="transparent")を組み合わせ、各バーの開始位置を制御すること
- 色分け: Cellコンポーネントでstart・increase・decrease・totalのtypeに応じて個別に色を適用すること
- インタラクティブ: ホバー時にカスタムTooltipコンポーネントで項目名と値を表示すること
- レスポンシブ: ResponsiveContainerで親要素の幅に応じてチャートサイズが変わるよう対応すること

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。

2. Nivo(カスタム実装)

NivoのResponsiveBarにカスタムデータ変換を組み合わせて実装。各バーの基準値をデータ側で計算し、 透明バーをベースとして重ねることでウォーターフォール形式を実現。Nivoの洗練されたデザインシステムを活かしつつ独自の表現が可能。

✓ D3.jsベース✓ 美しいデザイン✓ カスタムレイヤー
特徴: keysに["base", "barValue"]を設定してスタック表示し、baseを透明にすることでウォーターフォール形式を実現。 colors関数でtypeに応じた色分けを行う。
tsx
'use client';
import { ResponsiveBar } from '@nivo/bar';

const nivoData = [
  { name: '前期末', base: 0, barValue: 5000, type: 'total' },
  { name: '新規顧客', base: 5000, barValue: 2200, type: 'increase' },
  { name: '解約', base: 6400, barValue: 800, type: 'decrease' },
  { name: 'アップセル', base: 6400, barValue: 1500, type: 'increase' },
  { name: 'コスト増', base: 7300, barValue: 600, type: 'decrease' },
  { name: '今期末', base: 0, barValue: 7300, type: 'total' },
];

const getColor = (type: string) =>
  type === 'total' ? '#6b7280' : type === 'increase' ? '#10b981' : '#ef4444';

export function NivoWaterfallChart() {
  return (
    <div style={{ height: 300 }}>
      <ResponsiveBar
        data={nivoData}
        keys={['base', 'barValue']}
        indexBy="name"
        margin={{ top: 20, right: 20, bottom: 50, left: 60 }}
        padding={0.3}
        colors={({ id, data }: any) => id === 'base' ? 'transparent' : getColor(data.type)}
        enableLabel={false}
        axisBottom={{ tickRotation: -20 }}
      />
    </div>
  );
}

🤖 AIプロンプトテンプレート

React + Tailwind CSSで、Nivoを使ったウォーターフォールチャートを実装してください。

- 使用ライブラリ: @nivo/bar の ResponsiveBar
- サンプルデータ: 月次損益10項目(売上高から純利益まで)を用意すること
- 実装方法: keysに["base", "barValue"]を設定してスタック表示し、baseを透明にすることでウォーターフォール形式を実現すること
- 色分け: colors関数でtypeに応じた色分けを行い、baseキーは透明にすること
- インタラクティブ: tooltipプロパティにカスタム関数を渡し、ホバー時に項目名と値を表示すること
- レスポンシブ: ResponsiveBarで親要素の幅に応じてチャートサイズが変わるよう対応すること

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。

3. Chart.js(カスタム実装)

Chart.jsのBarチャートは[min, max]形式の浮動バー(Floating Bar)をネイティブサポートしており、ウォーターフォールに最も適した実装が可能。 各バーの開始・終了位置を配列で指定するだけでよく、透明バーのハックが不要。Canvas描画でパフォーマンスも安定。

✓ Canvas描画✓ 浮動バー対応✓ 高パフォーマンス
特徴: [min, max]形式の浮動バーをネイティブサポート。透明バーのスタック技法が不要で、 各バーの開始・終了値を直接配列で指定できる最もシンプルなアプローチ。
tsx
'use client';
import { Bar } from 'react-chartjs-2';
import {
  Chart as ChartJS, CategoryScale, LinearScale,
  BarElement, Title, Tooltip, Legend,
} from 'chart.js';

ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend);

// Chart.js floating bars: [start, end]
const labels = ['前期末', '新規顧客', '解約', 'アップセル', 'コスト増', '今期末'];

const data = {
  labels,
  datasets: [{
    label: '金額',
    data: [
      [0, 5000],
      [5000, 7200],
      [6400, 7200],
      [6400, 7900],
      [7300, 7900],
      [0, 7300],
    ],
    backgroundColor: ['#6b7280', '#10b981', '#ef4444', '#10b981', '#ef4444', '#6b7280'],
    borderSkipped: false,
    borderRadius: 3,
  }],
};

export function ChartJSWaterfallChart() {
  return (
    <Bar data={data as any}
      options={{ responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false } } }}
      height={300} />
  );
}

🤖 AIプロンプトテンプレート

React + Tailwind CSSで、Chart.js(react-chartjs-2)を使ったウォーターフォールチャートを実装してください。

- 使用ライブラリ: react-chartjs-2 の Bar コンポーネント、chart.js の CategoryScale・LinearScale・BarElement
- サンプルデータ: 月次損益10項目(売上高から純利益まで)を用意すること
- 実装方法: datasetsのdataに[min, max]形式の浮動バー(Floating Bar)を使用し、各バーの開始・終了位置を直接指定すること
- 色分け: backgroundColorに配列でtypeごとの色を指定すること
- インタラクティブ: tooltip.callbacks.labelで項目名と元の値を表示すること
- レスポンシブ: responsive: true、maintainAspectRatio: falseで親要素に合わせたサイズにすること

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。

ライブラリ比較

アプローチレンダリング実装方法浮動バー対応おすすめ用途
Recharts カスタムSVG透明バー重ね△ 疑似的に実現Reactアプリ全般
Nivo カスタムSVGデータ変換+重ね△ 疑似的に実現デザイン重視のダッシュボード
Chart.js カスタムCanvas浮動バーネイティブシンプルで確実な実装

選択のポイント

  • Recharts: 既存のRechartsプロジェクトに追加しやすく、ComposedChartの知識があれば実装可能。コードの可読性が高い。
  • Nivo: デザイン性を重視したい場合に選択。カスタムレイヤーを活用することでNivoのデザインシステムに統一できる。
  • Chart.js: 浮動バーをネイティブサポートしているため、3つの中で最もシンプルにウォーターフォールを実装できる。実装の確実性が高い。

典型的な使用例

  • 💰
    損益分析:売上から各コストを差し引いて最終利益に至るまでの流れを可視化
  • 📊
    予算vs実績:予算からの乖離要因を増減で段階的に表現
  • 🏦
    キャッシュフロー:営業・投資・財務活動ごとの現金増減を表示
  • 📈
    KPI変動要因分析:前期比較での増減要因をブリッジチャートで説明

⚠️ 使用時の注意点

  • 合計バー(start・total)と増減バーは色を明確に区別する(例:合計は濃色、増加は青・緑、減少は赤・オレンジ)
  • 項目数が多すぎるとバーが細くなり読みにくくなるため、8〜10項目程度に抑える
  • 各バーに値ラベルを表示することで、グラフだけでは読み取りにくい数値を補完する
  • 負の値(減少)の表現方法をライブラリごとに確認し、意図した表示になるよう注意する