0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Chart.js】React で “定番グラフ” をサクッと描く

Last updated at Posted at 2025-11-20

シンプル版とガチガチ版の 2 グラフで徹底解説

Recharts や Nivo に続いて、この記事では Chart.js + react-chartjs-2 を使った
ライン/複合チャートを

  • Simple(シンプル版)
  • Advanced(ガチガチ版)

の 2 パターンで紹介します。

「設定オブジェクトを書いてグラフを作る」スタイルが特徴で、
“とりあえず定番グラフを出したい” ときに非常に頼れるライブラリ です。


📂 GitHub リポジトリ

この記事で紹介しているコードは、以下のリポジトリにまとめています。

 構成例(Next.js + TypeScript)の一部:

  • src/data.ts
  • src/components/RechartsExample.tsx
  • src/components/NivoExample.tsx
  • src/components/ChartJsExample.tsx
  • src/components/ApexExample.tsx

🖼 グラフのスクリーンショット

記事内でイメージしやすいように、実際に描画したグラフのスクリーンショットも貼っておきます。

スクリーンショット 2025-11-21 6.37.17.png


Chart.js とは?

Chart.js は、もっとも歴史が長くメジャーな JavaScript グラフライブラリの一つです。

  • Line / Bar / Pie / Radar など 定番チャートが一通りそろっている
  • 設定オブジェクト(data / options)を渡してグラフを描画するシンプルな API
  • プラグインで細かい拡張が可能
  • React からは react-chartjs-2 を通して扱うのが一般的

「React-first な設計ではないが、とにかく実績と情報量が多い」
というのが最大の特徴です。


インストール

npm install chart.js react-chartjs-2

共通データ(src/data.ts)

Recharts 編 / Nivo 編と同じデータを使います。

// src/data.ts
export type ChartDatum = {
  month: string;
  actual: number; // 実績
  target: number; // 目標
};

export const chartData: ChartDatum[] = [
  { month: "Jan", actual: 120, target: 150 },
  { month: "Feb", actual: 210, target: 200 },
  { month: "Mar", actual: 160, target: 220 },
  { month: "Apr", actual: 280, target: 250 },
  { month: "May", actual: 300, target: 260 },
];

ChartJsExample コンポーネントの全体像

ChartJsExample コンポーネントの中で、

  • 上段:Simple Chart.js(最低限で整った折れ線)
  • 下段:Chart.js Advanced(グラデーション + 複合チャート)
    の 2 グラフを縦に並べて表示します。

実装コード(src/components/ChartJsExample.tsx)

// src/components/ChartJsExample.tsx
import {
  Chart as ChartJS,
  LineElement,
  BarElement,
  PointElement,
  LinearScale,
  CategoryScale,
  Tooltip,
  Legend,
} from "chart.js";
import { Line, Bar } from "react-chartjs-2";
import { chartData } from "../data";

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

// 軸ラベル
const labels = chartData.map((d) => d.month);

// 実績・目標データ
const actualValues = chartData.map((d) => d.actual);
const targetValues = chartData.map((d) => d.target);

// グラデーション生成ユーティリティ
function createGradient(ctx: CanvasRenderingContext2D, color: string) {
  const gradient = ctx.createLinearGradient(0, 0, 0, 260);
  gradient.addColorStop(0, color + "88"); // 上側は少し濃く
  gradient.addColorStop(1, color + "00"); // 下に向かって透明に
  return gradient;
}

export function ChartJsExample() {
  return (
    <div style={{ display: "grid", gap: 24 }}>
      {/* ============================= */}
      {/* Simple Chart.js */}
      {/* ============================= */}
      <section>
        <h2
          style={{
            fontSize: 14,
            fontWeight: 600,
            marginBottom: 8,
            color: "#4b5563",
          }}
        >
          Simple Chart.js(最低限で整った折れ線)
        </h2>
        <p
          style={{
            fontSize: 12,
            color: "#6b7280",
            marginBottom: 12,
          }}
        >
          設定をほぼ書かずに使える、Chart.js のベーシックな折れ線グラフです。
          実績と目標の 2 系列を、最低限のオプションで描画しています。
        </p>

        <div
          style={{
            height: 260,
            padding: 12,
            background: "#ffffff",
            borderRadius: 12,
            boxShadow: "0 8px 24px rgba(15,23,42,0.06)",
          }}
        >
          <Line
            data={{
              labels,
              datasets: [
                {
                  label: "実績",
                  data: actualValues,
                  borderColor: "#3b82f6",
                  backgroundColor: "#3b82f666",
                  tension: 0.4,
                  pointRadius: 4,
                  borderWidth: 2,
                },
                {
                  label: "目標",
                  data: targetValues,
                  borderColor: "#9ca3af",
                  borderDash: [6, 4],
                  tension: 0.4,
                  pointRadius: 0,
                  borderWidth: 2,
                },
              ],
            }}
            options={{
              responsive: true,
              plugins: {
                legend: { position: "top" },
              },
              scales: {
                x: { grid: { display: false } },
                y: { grid: { color: "#e5e7eb" } },
              },
            }}
          />
        </div>
      </section>

      {/* ============================= */}
      {/* Chart.js Advanced */}
      {/* ============================= */}
      <section>
        <h2
          style={{
            fontSize: 14,
            fontWeight: 600,
            marginBottom: 8,
            color: "#4b5563",
          }}
        >
          Chart.js Advanced(グラデーション + 複合チャート)
        </h2>
        <p
          style={{
            fontSize: 12,
            color: "#6b7280",
            marginBottom: 12,
          }}
        >
          グラデーション塗り、カスタム風ツールチップ、棒+折れ線の複合表現など、
          Chart.js の柔軟な “設定力” を詰め込んだ例です。
        </p>

        <div
          style={{
            height: 260,
            padding: 14,
            background:
              "linear-gradient(135deg, rgba(17,24,39,1), rgba(2,6,23,1))",
            borderRadius: 18,
            boxShadow: "0 18px 40px rgba(15,23,42,0.55)",
          }}
        >
          <Bar
            data={(canvas) => {
              const ctx = canvas.getContext("2d")!;
              return {
                labels,
                datasets: [
                  {
                    type: "bar" as const,
                    label: "実績(Bar)",
                    data: actualValues,
                    backgroundColor: createGradient(ctx, "#3b82f6"),
                    borderRadius: 6,
                  },
                  {
                    type: "line" as const,
                    label: "目標(Line)",
                    data: targetValues,
                    borderColor: "#f97316",
                    borderWidth: 3,
                    borderDash: [4, 4],
                    tension: 0.4,
                    pointRadius: 4,
                  },
                ],
              };
            }}
            options={{
              responsive: true,
              plugins: {
                legend: {
                  labels: { color: "#e5e7eb" },
                },
                tooltip: {
                  backgroundColor: "rgba(17,24,39,0.9)",
                  titleColor: "#e5e7eb",
                  bodyColor: "#e5e7eb",
                  borderColor: "rgba(148,163,184,0.3)",
                  borderWidth: 1,
                },
              },
              scales: {
                x: {
                  ticks: { color: "#cbd5e1" },
                  grid: { display: false },
                },
                y: {
                  ticks: { color: "#cbd5e1" },
                  grid: { color: "rgba(148,163,184,0.3)" },
                },
              },
            }}
          />
        </div>
      </section>
    </div>
  );
}

🧩 Simple Chart.js(最低限で整った折れ線)のポイント

  • data と options の 2 つを渡すだけでグラフが描ける
  • datasets に 2 系列(実績 / 目標)を書くだけのシンプル構成
  • borderDash, pointRadius, tension などの基本プロパティである程度見栄えが整う
  • 軸やグリッドも scales.x.grid.display などで簡単に制御

「Chart.js を最小単位で触るとこうなる」 という入門サンプルです。

🧩 Chart.js のメリット・デメリット

React-first ではないものの、長い歴史と実績がある Chart.js。
その “強み” と “気をつけたい点” を整理してまとめます。


✅ メリット(強み)

1. 歴史と実績が圧倒的に豊富

Chart.js は最も長く使われているグラフライブラリの一つで、

  • 日本語記事が多い
  • プラグインが豊富
  • StackOverflow の回答も大量

という 情報量の多さ が最大の安心材料です。

「困った時は Chart.js」
という言葉が現場でよく出るほど情報が充実しています。


2. 定番グラフが一通りそろう

  • 折れ線
  • 棒グラフ
  • 円グラフ
  • レーダーチャート
  • 気泡・散布図

など、一般的に必要とされるグラフがほぼ全部揃っているため、
ダッシュボードや分析 UI に汎用的に使えます。


3. 設定オブジェクト方式で柔軟にカスタムできる

Chart.js は “設定オブジェクトを書くスタイル” なので、
想像以上に細かい UI まで調整できます。

  • 軸・グリッド・ツールチップの完全カスタム
  • プラグインで動的描画
  • イベントフックで振る舞いを拡張

など、書けば書くほど高度な表現ができるのは Chart.js の魅力です。


4. プラグインによる拡張性が高い

  • 目標ラインを追加する Annotation Plugin
  • ズーム/パンの zoom plugin
  • 背景カスタム plugin

など、公式・非公式の拡張が非常に多いため、
グラフの “限界突破” がしやすいライブラリです。


⚠️ デメリット(弱み)

1. React-first の設計ではない

Chart.js の内部は Imperative(命令的)であり、
React の Virtual DOM と相性が良いとはいえません。

そのため、

  • 再レンダリング時に挙動がわかりづらい
  • コンポーネント化が Recharts や Nivo ほど直感的ではない

という点は注意ポイントです。


2. 設定が複雑になりがち

シンプルな設定なら良いのですが、
凝り始めると options がどんどん肥大化していきます。

例:

scales > x > ticks > color  
scales > y > grid > color  
plugins > tooltip > callbacks > label  

と階層が深くなり、
「どこを触れば目的の見た目になるか?」が分かりにくくなりがち です。

3. リッチなデザインは手間がかかる

Chart.js で “綺麗なグラフ” を作ろうとすると、必ず設定量が増えます。

  • グラデーション塗り
  • 影(shadow)
  • カスタムツールチップ
  • ダークテーマ
  • 軸・グリッド・ラベルの微調整

これらは Chart.js 自体にはショートハンドがなく、
すべて optionsplugins をしっかり書いて作り込む必要があります。


🎯 Chart.js を選ぶべきケース

Chart.js が特に力を発揮するのは、以下のようなプロジェクトです。


📌 実績と安定性を最優先したいケース

  • 長く使われているライブラリが安心
  • プラグインや StackOverflow の情報量が多い方が良い
  • チームに Chart.js の経験者がいる

という状況では Chart.js の安定性 が最も役立ちます。


📌 “定番グラフ” を素早く用意したい場合

折れ線・棒・円・レーダーといった
「よくある UI のグラフ」 を短時間で作りたいなら、Chart.js は最も手軽です。

  • 表示だけならシンプルな設定で OK
  • 細かなデザイン調整も後から追加できる

という柔軟性があります。


📌 プラグインを活かしたい構成

Chart.js には公式・非公式の拡張プラグインが豊富です。

  • chartjs-plugin-zoom(ズーム/パン)
  • chartjs-plugin-annotation(目標ライン・イベント線)
  • カスタム描画プラグイン

など、拡張が前提の UI では Chart.js が最有力候補 になります。


📝 まとめ

Chart.js は、

  • 定番グラフをまず出したい
  • チームで安心して使える実績が欲しい
  • プラグインで将来の拡張性も確保したい

というプロジェクトに最も向いています。

一方で、デザインの表現力という意味では
Recharts・Nivo のような “React 的・テーマ特化” のライブラリに一歩譲ります。

最終的な比較の立ち位置は次の通りです:

ライブラリ 強み
Recharts React 的。複合チャートの構成力が強い
Nivo デザイン/アニメーション表現が最強
Chart.js 定番グラフ・情報量・プラグインで安心感

👉 次回「ApexCharts 編」です。
https://qiita.com/kz2021019/items/07ce194201bf5c90a041

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?