レスポンシブ対応

レスポンシブ対応は、画面サイズや親要素の幅に応じてチャートのサイズ・レイアウトを自動調整する設定。ダッシュボードやモバイル対応ページなど、さまざまなビューポートで適切に表示させたい場面で必要になる。

固定幅コンテナへの閉じ込め防止、モバイル・タブレット・デスクトップでのレイアウト切り替え、ウィンドウリサイズ時のスムーズな追従。

主なバリエーション
  • コンテナ幅への自動追従(width: 100%)
  • アスペクト比の維持
  • ブレークポイント別のレイアウト切り替え
  • 凡例・ラベルの表示/非表示の切り替え
  • debounce付きリサイズ対応

ライブラリ横断比較

機能RechartsEChartsPlotly.jsChart.jsNivoApexCharts
コンテナ幅への自動追従
ResponsiveContainer
resize()
autosize
デフォルト
Responsive*
width:'100%'
アスペクト比の維持
aspect prop
手動計算
部分対応
aspectRatio
CSS依存
CSS依存
ラッパーコンポーネント
ResponsiveContainer
×××
Responsive*
×
debounceリサイズ
debounce prop
手動実装
自動
resizeDelay
自動
自動
ブレークポイント別設定×××××
responsive[]

○ = 対応  △ = 部分対応・制限あり  × = 非対応

ライブラリ別コード例

各ライブラリでレスポンシブ対応を実装する際の設定部分を抜粋しています。 動くデモは各比較ページでご確認ください。

Recharts

import { ResponsiveContainer, LineChart, Line, XAxis, YAxis } from 'recharts';

// ResponsiveContainer でラップするだけでコンテナ幅に自動追従
<ResponsiveContainer width="100%" height={400}>
  <LineChart data={data}>
    <XAxis dataKey="month" />
    <YAxis />
    <Line type="monotone" dataKey="value" />
  </LineChart>
</ResponsiveContainer>

// アスペクト比を維持したい場合(height不要)
<ResponsiveContainer width="100%" aspect={16 / 9}>
  <BarChart data={data}>
    {/* ... */}
  </BarChart>
</ResponsiveContainer>

// debounce でリサイズパフォーマンスを最適化
<ResponsiveContainer width="100%" height={400} debounce={50}>
  <LineChart data={data}>
    {/* ... */}
  </LineChart>
</ResponsiveContainer>

ECharts

// ECharts: resize() をウィンドウリサイズ時に呼び出す
import * as echarts from 'echarts';
import { useEffect, useRef } from 'react';

const ChartComponent = () => {
  const chartRef = useRef(null);

  useEffect(() => {
    const chart = echarts.init(chartRef.current);
    chart.setOption(option);

    // リサイズハンドラ(debounce推奨)
    const handleResize = () => chart.resize();
    window.addEventListener('resize', handleResize);

    return () => {
      window.removeEventListener('resize', handleResize);
      chart.dispose();
    };
  }, []);

  return <div ref={chartRef} style={{ width: '100%', height: '400px' }} />;
};

// ResizeObserver で親要素の変化を検知(より精密)
useEffect(() => {
  const observer = new ResizeObserver(() => chart.resize());
  observer.observe(chartRef.current.parentElement);
  return () => observer.disconnect();
}, []);

Plotly.js

// Plotly.js: config.responsive と useResizeHandler で自動リサイズ
import Plot from 'react-plotly.js';

<Plot
  data={data}
  layout={{
    autosize: true,  // コンテナサイズに自動フィット
    height: 400,
    margin: { l: 50, r: 20, t: 30, b: 50 },
  }}
  config={{
    responsive: true,  // ウィンドウリサイズ時に自動リサイズ
  }}
  style={{ width: '100%' }}
  useResizeHandler={true}  // react-plotly.js のリサイズ対応prop
/>

Chart.js

// Chart.js: responsive オプションで自動リサイズ
const options = {
  responsive: true,            // コンテナサイズに追従(デフォルトtrue)
  maintainAspectRatio: false,  // アスペクト比を維持しない(height固定時に使用)
  aspectRatio: 2,              // maintainAspectRatio: true のときの比率(幅/高さ)

  // resizeDelay でリサイズのdebounce(ms)
  resizeDelay: 50,
};

// CSS でコンテナの高さを指定
// <div style={{ position: 'relative', height: '400px', width: '100%' }}>
//   <canvas ref={canvasRef} />
// </div>

Nivo

import { ResponsiveLine } from '@nivo/line';
import { ResponsiveBar } from '@nivo/bar';

// Nivo は Responsive* コンポーネントを使うだけでコンテナに自動追従
// 親要素に height を CSS で設定する必要がある

<div style={{ height: '400px' }}>
  <ResponsiveLine
    data={data}
    // width / height prop は不要(コンテナから自動計算)
    margin={{ top: 10, right: 20, bottom: 50, left: 60 }}
  />
</div>

// Responsive版 vs 固定サイズ版
// ResponsiveLine → 親要素にあわせて自動リサイズ(推奨)
// Line           → width / height を明示指定(固定サイズ)

ApexCharts

// ApexCharts: width: '100%' + responsive でブレークポイント対応
const options = {
  chart: {
    width: '100%',    // コンテナ幅に追従
    height: 400,
  },

  // responsive: ブレークポイント別にオプションをオーバーライド
  responsive: [
    {
      breakpoint: 768,     // 768px 以下
      options: {
        chart: { height: 300 },
        legend: { position: 'bottom' },
        plotOptions: {
          bar: { columnWidth: '80%' },
        },
      },
    },
    {
      breakpoint: 480,     // 480px 以下
      options: {
        chart: { height: 250 },
        legend: { show: false },
      },
    },
  ],
};

まとめ・選び方のヒント

  • 最もシンプルに実装したい → Recharts(ResponsiveContainerでラップするだけ)・Nivo(Responsive*コンポーネントを使うだけ)
  • ブレークポイント別にオプションを切り替えたい → ApexCharts(responsive配列で宣言的に設定可能)
  • 設定なしでデフォルト対応 → Chart.js(responsive: trueがデフォルト)
  • Reactに依存しない実装 → ECharts(ResizeObserverとresize()の組み合わせが汎用的)
  • アスペクト比を固定したい → Recharts(aspect prop)・Chart.js(aspectRatioオプション)