- Published on
Web データ可視化ライブラリ 2026 — D3・Plot・Visx・Recharts・ECharts・Vega-Lite を一気に比較する(深掘りガイド)
- Authors

- Name
- Youngju Kim
- @fjvbn20031
プロローグ — チャートライブラリはなぜこんなに多いのか
初めて Web でチャートを描こうとした人が一度は投げる質問がある。「結局どれを使えばいいの?」 答えはいつも同じだ。「何を描きたいの?」
突き放しに聞こえるが、これが本当の答えだ。2026 年のチャートエコシステムは一次元で整理できない。少なくとも四つの軸がある。
- 抽象レベル — ピクセルまで触りたいのか、JSON 一塊で済ませたいのか。
- フレームワーク親和性 — React か Vue/Svelte か、それともバニラか。
- データ規模 — 1,000 点か、100 万か、1 億か。
- インタラクションの深さ — 静的インフォグラフィックか、ライブダッシュボードか、分析 UI か。
この四つの軸のどこに立つかで、同じ「棒グラフ」が D3 だと 80 行、Plot だと 3 行、Recharts だと 12 行になる。行数が少ないのが偉いわけではない。自由度が少ないのだ。
2026 年 5 月時点、風景を一行ずつ。
- D3.js v7 — あらゆる抽象の土台。npm 週次ダウンロードは約 800 万。直接書く頻度は減ったが、使うすべての道具が D3 の上に立っている。
- Observable Plot 0.7 — D3 メンテナーたちが作った「グラマー・オブ・グラフィックス」層。ggplot2 の精神を JavaScript に持ち込んだ。
- Visx 3.x — Airbnb の React + D3 プリミティブ。活発さは落ち着いたが生きており、コンポーネント志向の React 開発者には今も最適。
- Recharts 2.15 — React 親和の既定値。小規模ダッシュボードの最速ルート。
- Apache ECharts 6 — 2025 年後半に v6 メジャーが出た。Canvas/SVG デュアルレンダラー、巨大なチャートカタログ、中国・日本のエンタープライズ標準。
- Vega-Lite 5.20 — JSON 一塊 = チャート。分析レポート自動生成と相性がよい。
- Plotly.js 2.35 — 科学・金融用インタラクティブチャート。3D・地図まで。
- Chart.js 4.5 — Canvas ベース、最軽量に始めるルート。
- AntV G2 / G6 5 — Alibaba のチャート(G2)とグラフ/ネットワーク(G6)ファミリー。
- Nivo 0.99 — React + D3 で「既定値が一番きれい」なチャート。商用サイトに合う。
- Deck.gl 9 / regl 2 — WebGL/WebGPU で数百万点を描く GPU 加速可視化。
本稿はこの風景を 抽象のはしご として整理する — 最下層(D3)から最上層(Vega-Lite・Superset/Metabase)まで。そして同じチャートを 4 ライブラリで書き、何をいつ選ぶか の決定表を残す。
1 章 · 抽象のはしご — D3 から Plot、Plot からラッパーへ
チャートライブラリを選ぶときまず見るべきは 抽象レベル だ。同じ問題(データをピクセルにする)をどの層で解くのか。
[ 最上 ]
Superset / Metabase (SQL -> チャート、クリックで終わり)
Vega-Lite (JSON スペック) (宣言型グラマー)
Recharts / Nivo / Chart.js (コンポーネント既定値)
Observable Plot (グラマー + JS API)
Visx / AntV G2 (D3 上のコンポーネント・言語抽象)
D3.js (スケール、軸、シェイプ、セレクション)
Canvas 2D / SVG (ブラウザの原始 API)
WebGL / WebGPU (GPU)
[ 最下 ]
このはしごでは 上に行くほど早く始められるが、自由度は狭くなる。下に行くほどすべてのピクセルを握れるが、書く行数は増える。
実用ルール 3 つ:
- 作りたいチャートがライブラリのギャラリーに似た形なら、上の一段か二段から始める。 Recharts / Nivo / ECharts / Plot で 80% のダッシュボードは終わる。
- ギャラリーに無ければ一段下りる。 「軸が二つで、上に矢印が浮いて、クリックでサイドパネル」のたぐいは Plot か Visx で書く。
- それでもダメなら D3 まで下りる。 Sankey / Force / Geo のような非標準形、または「50 万点でも 60fps」のような極端な性能。
人に見せるチャート(ブログ図版・研究レポート)は Plot で 80%、D3 で 20%。製品内のダッシュボードは Recharts / ECharts で 80%、Visx / D3 で 20%。
2 章 · D3.js — すべての抽象の母
D3 はチャートライブラリではない。正確には データ → DOM のマッピングライブラリ で、チャートはその応用の一つに過ぎない。
三つの中核抽象を覚えれば D3 は一気に掴める。
スケール(Scale)
データドメイン(例: 0〜1,000,000)をピクセル範囲(例: 0〜600)に変換する。種類:
scaleLinear、scaleLog、scaleSqrt、scaleTime— 連続scaleBand、scalePoint、scaleOrdinal— 離散scaleSequential、scaleQuantize— 色
import * as d3 from 'd3'
const x = d3.scaleBand()
.domain(data.map(d => d.month))
.range([60, 740])
.padding(0.2)
const y = d3.scaleLinear()
.domain([0, d3.max(data, d => d.revenue)])
.range([460, 20])
セレクション(Selection)とジョイン(Join)
DOM 要素をデータに結ぶ。d3.select、selectAll、.data()、.join()。
const svg = d3.select('#chart').append('svg')
.attr('width', 800).attr('height', 480)
svg.selectAll('rect.bar')
.data(data)
.join('rect')
.attr('class', 'bar')
.attr('x', d => x(d.month))
.attr('y', d => y(d.revenue))
.attr('width', x.bandwidth())
.attr('height', d => 460 - y(d.revenue))
.attr('fill', '#4f46e5')
これが D3 コードの「心臓」。データが変わると .join() 一行が enter / update / exit を処理する。
シェイプジェネレーター(Shape generator)
線・面・アークの path 文字列を作る。d3.line、d3.area、d3.arc、d3.pie。モジュール単位で import する(ツリーシェイキング)。
2026 年に D3 を直接書く場面
正直、減っている。上の段が良くなりすぎた。それでも D3 に直接触る瞬間:
- 非標準形 — Sankey、Chord、Sunburst、Voronoi、Force-directed、Hexbin。
- インタラクションがチャートの本質 — ズーム・ドラッグ・ラバーバンド・ブラシが半分以上を占める。
- 性能を直接扱う必要 — Canvas に直接描く、仮想スクロール、requestAnimationFrame の振り付け。
- チャートライブラリを作る — Visx・Plot・Recharts はすべて内部で D3 モジュールを使う。
D3 の罠を一つ。v6/7 から ES モジュール分離になっている。 d3-scale、d3-shape、d3-array だけ import すればバンドルは 50KB 台に落ちる。import * as d3 from 'd3' は便利だが 250KB 近い。
3 章 · Observable Plot — D3 の上のグラマー層
D3 メンテナーたちが作った 高水準 API。一行要約: 「ggplot2 を JavaScript に。」
ggplot2 を知らなければ「グラマー・オブ・グラフィックス」とは何か、から。チャートを レイヤー・マーク・スケール・エンコーディング に分解して組み合わせる。棒も、点も、線もすべて「マーク」という同じ抽象だ。
D3 の 25 行が:
import * as Plot from '@observablehq/plot'
const chart = Plot.plot({
marginLeft: 60,
y: { grid: true, label: 'Revenue (USD)' },
x: { label: 'Month' },
marks: [
Plot.barY(data, { x: 'month', y: 'revenue', fill: '#4f46e5' }),
Plot.ruleY([0])
]
})
document.getElementById('chart').append(chart)
5 行になる。そしてその 5 行は D3 の上にそのまま敷かれているので、必要なら下に降りられる。グリッド・スケール・軸・凡例が合理的な既定値で点いており、Plot.plot 一発でインタラクション・面積・ヒートマップ・ボックスプロット・地図まで揃う。
2026 年の Plot の位置
- バージョン 0.7(2025 年後半)。1.0 前だが本番で十分安定。
- Observable Framework(静的サイト → データページ)と組み合わさり、データジャーナリズムや社内ダッシュボードでほぼ標準。
- React / Vue / Svelte どこでも動く(返り値が DOM ノードなので
appendChildでよい)。 - インタラクションは
Plot.crosshair・Plot.tooltip・Plot.pointerなどインタラクションマークで処理。
Plot が合わない場面
- ピクセル単位で違う描き方が必要なカスタム形。
- 一つのチャート内のインタラクションが極端に複雑(ドラッグ + 多選択 + サイドパネル同期)。
- 100 万点超 — Canvas モード(
Plot.dot+render: Plot.renderCanvasオプション)もあるが本体は SVG ベース。
一言: ブログ図版・研究レポート・データジャーナリズムなら、ほぼ Plot で終わる。
4 章 · Visx — Airbnb の React + D3 プリミティブ
Visx は D3 モジュールを React コンポーネントに包み直したもの だ。チャートライブラリではなく、チャートを作るためのツールキット。
@visx/scale— D3 スケールを React 親和に。@visx/shape— Bar、Line、Area、Pie などの path コンポーネント。@visx/axis、@visx/grid、@visx/legend。@visx/tooltip— ポジショニング付きツールチップフック。@visx/responsive—ParentSizeでコンテナ幅追従。
強みは明快。
- 純粋 React — 仮想 DOM の中で最後まで生きる。
useEffectの脱出口なし。 - ツリーシェイキング — 必要なものだけ import。
- TypeScript — 型が正確。
import { scaleBand, scaleLinear } from '@visx/scale'
import { Bar } from '@visx/shape'
import { Group } from '@visx/group'
import { AxisBottom, AxisLeft } from '@visx/axis'
function RevenueChart({ data, width = 800, height = 480 }) {
const xScale = scaleBand({
domain: data.map(d => d.month),
range: [60, width - 20],
padding: 0.2,
})
const yScale = scaleLinear({
domain: [0, Math.max(...data.map(d => d.revenue))],
range: [height - 30, 20],
})
return (
<svg width={width} height={height}>
<Group>
{data.map(d => (
<Bar
key={d.month}
x={xScale(d.month)}
y={yScale(d.revenue)}
width={xScale.bandwidth()}
height={(height - 30) - yScale(d.revenue)}
fill="#4f46e5"
/>
))}
</Group>
<AxisLeft scale={yScale} left={60} />
<AxisBottom scale={xScale} top={height - 30} />
</svg>
)
}
2026 年の Visx の位置
正直に言うと、活発さは鈍化している。メジャーリリースは間遠で、Issue の捌きも遅くなった。それでも:
- メンテは生きている(2025 年後半にもパッチが出た)。
- React で D3 プリミティブが必要な人にとっては依然第一候補。
- Airbnb 内部で使われているので消えはしない。
一言: 「Recharts / Nivo は窮屈で、生 D3 までは降りたくない」のドンピシャの位置。
5 章 · Recharts — React 親和の既定値の王
Recharts は 「速く始めて十分遠くまで行く」 の代名詞。2026 年 5 月時点で v2.15。v3 ベータはあるが本番標準は 2.15。
同じ棒グラフ:
import { BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts'
function RevenueChart({ data }) {
return (
<ResponsiveContainer width="100%" height={480}>
<BarChart data={data}>
<XAxis dataKey="month" />
<YAxis />
<Tooltip />
<Bar dataKey="revenue" fill="#4f46e5" />
</BarChart>
</ResponsiveContainer>
)
}
12 行。レスポンシブ・ツールチップ・軸・グリッドがすべて既定で点く。80% の SaaS ダッシュボードはここで終わる。
Recharts が本当に強い場所
- React コンポーネントとしてきれいに合成される — 状態が React に入って出ていく。
- コンポジション —
Bar+Line+Areaを一つのチャートに混ぜるのが自然。 - レスポンシブ —
ResponsiveContainer一行。 - TypeScript 型が合理的。
Recharts の弱点
- SVG ベース — 5,000 個を超えると粘り、1 万個を超えると重い。
- 高度なインタラクションは上限がある — ズーム・ブラシ・多選択を深く突くと Plot / Visx へ。
- 見た目が普通 — デザイントーンはデザイナーの手が要る。
一言: 社内ダッシュボード・BI ウィジェット・ブログチャートなら Recharts から始めよ。詰まったら一段下りる。
6 章 · Apache ECharts 6 — エンタープライズの猛獣
2025 年 11 月に出た ECharts 6 は単なるチャートライブラリではなく 可視化プラットフォーム に近い。Apache 財団の正式プロジェクト。
特徴を素早く:
- Canvas + SVG デュアルレンダラー — 同じオプションオブジェクトで両方描ける。大データは Canvas、印刷/ベクトルは SVG。
- 巨大なチャートカタログ — Bar/Line/Scatter は標準、Sankey・Tree・Treemap・Sunburst・Funnel・Gauge・Radar・Parallel・BoxPlot・Heatmap・Calendar・Graph・Map (GeoJSON)・3D (
echarts-gl) まで。 - 宣言的オプション — JSON 一塊でチャートが終わる(Vega-Lite と近い精神)。
- レスポンシブ —
resize一行。 - WebGL バックエンド —
echarts-glで 100 万点散布図・3D 地図。
同じ棒グラフ:
import * as echarts from 'echarts/core'
import { BarChart } from 'echarts/charts'
import { GridComponent, TooltipComponent } from 'echarts/components'
import { CanvasRenderer } from 'echarts/renderers'
echarts.use([BarChart, GridComponent, TooltipComponent, CanvasRenderer])
const chart = echarts.init(document.getElementById('chart'))
chart.setOption({
xAxis: { type: 'category', data: data.map(d => d.month) },
yAxis: { type: 'value' },
tooltip: { trigger: 'axis' },
series: [{ type: 'bar', data: data.map(d => d.revenue), itemStyle: { color: '#4f46e5' } }],
})
ECharts が強い理由
- チャート種別 — Bar/Line だけなら Recharts のほうがよい。Sunburst・Sankey・Radar・Map・Calendar Heatmap が一つのライブラリに揃うのは ECharts がほぼ唯一。
- 大データ処理 — Canvas 標準 + プログレッシブレンダリングで 50 万点散布図が自然に回る。
- テーマシステム — JSON テーマでトーンを一発切り替え。
- i18n — 最初から多言語前提。
ECharts の弱点
- バンドルサイズ — フルビルドは 1MB を超える。モジュール分離 import が必須。
- React 親和性 — init / dispose を手動で管理する必要。
echarts-for-reactのようなラッパーはある。 - API 表面が巨大 — オプションオブジェクトが深い。一行差で結果が大きく振れる。
一言: 「チャート種別が暴走する BI」または「データ量が多くインタラクションも豊富なダッシュボード」なら ECharts。
7 章 · Vega-Lite — JSON 一塊がチャートになる
ワシントン大学発の 宣言型グラマー。JSON 一つでチャートを定義する。
import { default as vegaEmbed } from 'vega-embed'
vegaEmbed('#chart', {
$schema: 'https://vega.github.io/schema/vega-lite/v5.json',
data: { values: data },
mark: { type: 'bar', color: '#4f46e5' },
encoding: {
x: { field: 'month', type: 'ordinal' },
y: { field: 'revenue', type: 'quantitative' },
},
})
これで終わり。そしてこの JSON スペックは バージョン管理可能で、人間が読み書きしやすく、自動生成もしやすい。
輝く場所
- 分析レポートの自動生成 — LLM がデータを見て JSON を吐けばそれがチャート。Vega-Lite は意外にも LLM 時代と相性がよい。
- データジャーナリズム — チャートの「スペック」をコードと分離して管理。
- Jupyter / Altair 連携 — Python の Altair が同じスペックを吐く。ノートで描いたチャートをそのまま Web へ。
弱点
- インタラクションの深さ — 基本の selection 文法はあるが「チャートのクリックで外部 React 状態が変わる」式の統合には手間。
- バンドル — Vega + Vega-Lite + vega-embed は軽くない。
一言: チャートの「データ/規格」を体系的に扱いたいなら Vega-Lite。
8 章 · その他 — Plotly、Chart.js、AntV、Nivo
一行ずつ素早く。
- Plotly.js 2.35 — 科学・金融インタラクティブチャートの定番。3D・Geo・Financial (OHLC、Candlestick) が強い。バンドルが重いのが弱点(MathJax を抜いても 700KB+)。
plotly.js-basic-distの部分 import が答え。 - Chart.js 4.5 — Canvas ベース。軽量で親切だがチャート種別は少なめ。小規模プロジェクトの最初のライブラリには無難。
- AntV G2 5 / G6 5 — Alibaba のチャート G2 とグラフ/ネットワーク G6。グラフ可視化は G6 が D3-Force より楽。中国・日本圏で強い。
- Nivo 0.99 — React + D3 で作られた 既定値が一番きれい なチャート。商用サイト・ランディングページに合う。短所はバンドルが大きく、カスタマイズの深さは Recharts / Visx より狭い。
9 章 · 同じ棒グラフを 4 ライブラリで — 一目で
月別売上([{month: 'Jan', revenue: 12400}, ...])を棒で描く。同じデータ、4 つのアプローチ。
D3(低水準)
import * as d3 from 'd3'
const width = 800, height = 480, margin = { top: 20, right: 20, bottom: 30, left: 60 }
const svg = d3.select('#chart').append('svg').attr('width', width).attr('height', height)
const x = d3.scaleBand().domain(data.map(d => d.month))
.range([margin.left, width - margin.right]).padding(0.2)
const y = d3.scaleLinear().domain([0, d3.max(data, d => d.revenue)]).nice()
.range([height - margin.bottom, margin.top])
svg.append('g').attr('transform', `translate(0,${height - margin.bottom})`).call(d3.axisBottom(x))
svg.append('g').attr('transform', `translate(${margin.left},0)`).call(d3.axisLeft(y))
svg.selectAll('rect.bar').data(data).join('rect')
.attr('class', 'bar')
.attr('x', d => x(d.month))
.attr('y', d => y(d.revenue))
.attr('width', x.bandwidth())
.attr('height', d => y(0) - y(d.revenue))
.attr('fill', '#4f46e5')
自由度 100。行数 25。インタラクションは別途追加。
Observable Plot(グラマー)
import * as Plot from '@observablehq/plot'
const chart = Plot.plot({
marginLeft: 60,
y: { grid: true, label: 'Revenue (USD)' },
marks: [
Plot.barY(data, { x: 'month', y: 'revenue', fill: '#4f46e5', tip: true }),
Plot.ruleY([0]),
],
})
document.getElementById('chart').append(chart)
自由度 70。行数 8。ツールチップはオプション一つ。
Recharts(React コンポーネント)
import { BarChart, Bar, XAxis, YAxis, Tooltip, CartesianGrid, ResponsiveContainer } from 'recharts'
function RevenueChart({ data }) {
return (
<ResponsiveContainer width="100%" height={480}>
<BarChart data={data} margin={{ top: 20, right: 20, bottom: 30, left: 60 }}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="month" />
<YAxis />
<Tooltip />
<Bar dataKey="revenue" fill="#4f46e5" />
</BarChart>
</ResponsiveContainer>
)
}
自由度 60。行数 12。React コンポジション親和。
ECharts(宣言型オプション)
import * as echarts from 'echarts'
const chart = echarts.init(document.getElementById('chart'))
chart.setOption({
grid: { left: 60, right: 20, top: 20, bottom: 30 },
xAxis: { type: 'category', data: data.map(d => d.month) },
yAxis: { type: 'value', name: 'Revenue (USD)' },
tooltip: { trigger: 'axis' },
series: [{ type: 'bar', data: data.map(d => d.revenue), itemStyle: { color: '#4f46e5' } }],
})
window.addEventListener('resize', () => chart.resize())
自由度 80。行数 11。オプションオブジェクト一塊。
行数はどれも似ているが、何が違うのか
行数だけ見ると差は小さい。本当の差は:
- D3 — データが変わったとき、マウスオーバーしたとき、ズームしたとき、すべての挙動を手で書く。
- Plot — チャート単位。インタラクションはオプション。外部状態との統合は弱い。
- Recharts — React 状態にすべてが流れる。
state.monthが変われば即再描画。 - ECharts —
chart.setOption()で丸ごと差し替え。React の中ではuseEffectで同期を自前で。
チャートが アプリの一構成要素 なら Recharts / Visx、データ → 絵 が本質 なら Plot / ECharts / D3。
10 章 · 大規模データ — Canvas、WebGL、Deck.gl、regl
ここからは別ゲームだ。点 1 万までは SVG。10 万からは Canvas。100 万からは WebGL。
なぜ SVG は遅くなるか
SVG では各点が DOM ノード。点 10 万 = DOM 10 万。ブラウザのレイアウト・ペイントコストはノード数に線形でかかる。5 千〜1 万ノード付近でインタラクションが粘り、10 万ではページそのものが重い。
Canvas 2D — 第一段階
Canvas は一つのノード(canvas 要素)内にピクセルを描く。点が 100 万あっても DOM は一つ。難点は ヒットテスト(マウスがどの点に乗ったか)を手で書くこと。
ライブラリ別 Canvas モード:
- D3 —
canvas.getContext('2d')で直接描画。D3 スケール・シェイプはそのまま使える。 - Plot —
Plot.dot(..., { render: Plot.renderCanvas })のような Canvas マーク。 - Chart.js / ECharts — 標準が Canvas。
- Recharts / Visx — 標準は SVG。Canvas モードは無いか限定的。
WebGL — 第二段階
GPU で点を描く。100 万点も軽い。
- regl 2.x — WebGL を関数型に薄く包んだ層。D3 / Plot と一緒に使うと「スケールは JS、描画は GPU」がきれい。
- Deck.gl 9 — Uber の GPU 可視化フレームワーク。地図(Mapbox GL / MapLibre / Google Maps)の上に 1 億点、3D ビル、ヒートマップ、トレイル。データ可視化 + 地図が一番自然な場所。
- PixiJS / Three.js + インスタンシング — 一般可視化ではないが、100 万点散布図に使う例はある。
WebGPU — 次の段階
2026 年 1 月に WebGPU が主要ブラウザでベースラインになった。可視化ライブラリはゆっくり追従中。
- Deck.gl は 9.x で WebGPU レンダラーを実験提供。
- regl-gpu が一部プロジェクトで使われている。
- 本格採用は 2026 年末〜2027 年。
100 万点散布図、何で描くか
選択フロー:
- 地図の上なら Deck.gl — 迷わない。
- 地図でなく純粋な散布図なら regl + D3 スケール — 100〜300 行で済む。
- 早く始めたく、定型パターンなら ECharts 6 + プログレッシブレンダリング — オプション一行。
- 既に Three.js を使っているなら InstancedMesh。
11 章 · 決定フレームワーク — 何をいつ使うか
表一つに集約。
| シナリオ | 第一候補 | 第二候補 | メモ |
|---|---|---|---|
| React 社内ダッシュボード(5,000 点未満) | Recharts | Nivo | コンポジション・レスポンシブが自然 |
| Vue / Svelte / バニラのダッシュボード | ECharts | Plot | フレームワーク中立 |
| ブログ図版・研究レポート | Plot | ECharts | 5 行で終わり、印刷もきれい |
| 分析・探索 UI(インタラクション深い) | Visx | 生 D3 | React コンポジション + 自由度 |
| BI ウィジェット、チャート種別が暴走 | ECharts 6 | Plotly | Sankey / Sunburst / Calendar |
| 非標準形(Sankey、Force、Chord) | 生 D3 | AntV G6 | ギャラリーに無い |
| 地図上の点 / ヒートマップ | Deck.gl | Mapbox GL | GPU + 地図 |
| 100 万点散布図 | regl + D3 | ECharts (Canvas) | DOM 一つ、GPU |
| 科学 / 金融(3D、OHLC) | Plotly | ECharts | ドメイン特化 |
| JSON スペックで自動生成 | Vega-Lite | Plot | LLM 親和 |
| グラフ / ネットワーク | AntV G6 | D3-Force | G6 のアルゴリズムカタログ |
| デモ / ポートフォリオ | Nivo | Plot | 見映え優先 |
| 体系的なデータセルフサービス | Superset / Metabase | Lightdash | クリック = チャート |
12 章 · アンチパターン — 現場でよく見る失敗
よく見る間違い 5 つ。
- 5,000 点ライブ散布図を Recharts (SVG) で — Canvas / ECharts に替えれば即座に生き返る。
- Plotly フルビルドを一枚のチャートのために import —
plotly.js-basic-distか ECharts に逃げる。 - D3 で棒グラフを 80 行書く — Plot / Recharts なら 5〜12 行で終わる。
- ECharts を React で init / dispose を忘れる — メモリリーク。
useEffectのクリーンアップ関数が必須。 - 複数のチャートライブラリを 1 ページに混ぜる — バンドル爆発、デザイントーン不一致。一つ選んで最後まで行く。
13 章 · BI 消費者側 — Superset、Metabase、Lightdash
最後の一枝。チャートを自分で書かない 道。
- Apache Superset — チャート種別 60+、ECharts ベース、無料でセルフホスト。短所は運用が重い。
- Metabase — 一番親切なセルフサービス BI。非技術ユーザーがクエリなしでチャートを作る。オープンコア + クラウド。
- Lightdash — dbt の上に乗る BI。メトリクス定義を dbt に置き、その可視化層が乗る。データエンジニアリング親和。
- Grafana — 時系列・観測性に特化。可視化ライブラリでもある(公開パネル)。
データチームがチャートをコードで書く時代は徐々に終わりつつある。開発者が書くチャートは減り、BI ツールが描くチャートは増えている。 それが 2026 年の大きな絵だ。
エピローグ — はしごのどこに立つか
Web データ可視化は はしご だ。上に行くほど速いが狭く、下に行くほど遅いが自由。2026 年の風景から残す一行。
- 上 80% — Recharts(React)、ECharts(汎用)、Plot(ブログ・レポート)でほぼ全部。
- 中 15% — インタラクションが深くなれば Visx、チャートが非標準なら D3。
- 下 5% — 100 万点・地図上の可視化は Deck.gl / regl / WebGL / WebGPU。
この比率はライブラリ人気とほぼ比例する。そして真ん中に、D3 は見えないところですべての下に敷かれている。 ライブラリを一つ選ぶたびに、そのライブラリが D3 モジュールをどう使っているか覗いてみるのが、次のチャートライブラリを選ぶときの目になる。
12 項目チェックリスト
- チャートは React コンポーネントとして自然に合成されるか?
- データが 5,000 点を超えたら SVG から Canvas / WebGL へ移したか?
- ECharts / Plotly のような巨大ライブラリはモジュール分離 import を使ったか?
- 同じデータにチャートライブラリが 2 つ以上混ざっていないか?
- レスポンシブは ResizeObserver(またはライブラリ既定)で捕まえたか?
- 色パレットは色覚親和(viridis / cividis など)か?
- 0 始まりでない y 軸はユーザーに明示されているか?
- ツールチップ / フォーカスはキーボードでも到達可能か?
- 元データは CSV / JSON でダウンロード可能か?
- 印刷 / PDF で崩れない SVG モードを用意したか?
- チャートライブラリのツリーシェイキングはバンドルアナライザーで確認したか?
- 多言語(ラベル・日付・数値フォーマット)は最初から入れたか?
次回予告
候補: 「D3 + WebGL で 100 万点散布図を 60fps」、「Vega-Lite で LLM にチャートを直接描かせる」、「Observable Framework で静的データページのワークフロー」。
「チャートはデータの最後の一言。それをはしごのどこから叫ぶかが、記事全体の声色を決める。」
— Web データ可視化ライブラリ 2026、終わり。
参考 / References
- D3.js — https://d3js.org/
- Observable Plot — https://observablehq.com/plot/
- Observable Framework — https://observablehq.com/framework/
- Visx (Airbnb) — https://airbnb.io/visx/
- Recharts — https://recharts.org/
- Apache ECharts — https://echarts.apache.org/
- Vega-Lite — https://vega.github.io/vega-lite/
- Plotly.js — https://plotly.com/javascript/
- Chart.js — https://www.chartjs.org/
- AntV G2 — https://g2.antv.antgroup.com/
- AntV G6 — https://g6.antv.antgroup.com/
- Nivo — https://nivo.rocks/
- Deck.gl — https://deck.gl/
- regl — https://github.com/regl-project/regl
- Apache Superset — https://superset.apache.org/
- Metabase — https://www.metabase.com/
- Lightdash — https://www.lightdash.com/
- Grafana — https://grafana.com/
- A Layered Grammar of Graphics (Hadley Wickham) — https://vita.had.co.nz/papers/layered-grammar.html