Claude Media
Claude CodeにEChartsのoption設計を任せる — 大量データの固まりを間引きで解く

Claude CodeにEChartsのoption設計を任せる — 大量データの固まりを間引きで解く

EChartsが数十万点で固まるとき、sampling・large・progressive・datasetのどれを足すかをClaude Codeに設計させ、テストで固定する手順です。

EChartsのグラフが数十万点のデータで固まるとき、直す場所はoptionの中にあります。Claude Codeにグラフのoption全体を見せ、間引きの設定を足させ、足した設定をテストで固定すれば、再発しにくくなります。この記事では、その順番と、どの設定をどの系列に足すかの判断を書きます。

先に結論を並べます。折れ線は sampling、散布図は large と progressive、データの持ち方は dataset が受け持ちます。この4つは役割が重ならないので、系列の種類ごとに選びます。

固まる原因は「全点を一度に描く」こと

EChartsの progressive の説明には、データ量が数千から1,000万件を超えるまで増えると、すべての図形要素を描くのに時間がかかりすぎる、とあります。ブラウザのUIスレッドが描画で埋まるので、操作が返らなくなります。

ここでClaude Codeに「遅いので速くして」と頼むと、animation を切る、symbolSize を下げるといった見た目の調整に流れがちです。効くのは、描く点の数そのものを減らす設定か、描画を分割する設定です。設計を任せる前に、次の4つの役割を頭に置いておくと、指示が具体的になります。

役割

大量データで効く 4 つの設定

  • sampling

    折れ線のデータ数が画面の画素数よりずっと多いときに、描く点を間引きます。既定ではオフです。

  • large

    散布図などで大規模データ向けの描画最適化を有効にします。個々のデータ項目のスタイルは変えられなくなります。

  • progressive

    1フレーム(約16ms)で描く要素数を区切り、チャンクごとに描画します。

  • dataset

    データを系列から切り離して1か所に置き、複数の系列や部品で再利用します。

samplingは折れ線の「見た目を保つ間引き」

sampling はline系列のオプションです。データ数が画素数よりずっと多いときに性能が上がるとされ、既定では全点を描きます。指定できる値は6つです。

値間引きの方法
'lttb'間引きの方法Largest-Triangle-Three-Bucket。傾向と極値を保つ
'average'間引きの方法区間内の平均値
'min'間引きの方法区間内の最小値
'max'間引きの方法区間内の最大値
'minmax'間引きの方法区間内で絶対値が最大の極値(v5.5.0以降)
'sum'間引きの方法区間内の合計

センサーや株価のように「山と谷の形」を読ませたい折れ線なら、傾向と極値を保つ 'lttb' が第一候補です。件数を集計して見せたい系列(リクエスト数など)では 'sum' が意味を持ちます。平均に潰すと値が変わってしまうためです。

もう1つ、折れ線には showSymbol があります。既定は true で、各点にシンボル(丸印)を描きます。ツールチップのホバー時にも出ます。数十万点で全点にシンボルを描く必要はないので、false にするのが定石です。

largeとprogressiveは散布図の受け持ち

散布図には large(既定 false)と largeThreshold(既定2000)があります。large を有効にすると大規模データ向けの最適化が働き、largeThreshold 以上の件数で描画の最適化が始まります。代償は、個々のデータ項目のスタイルをカスタマイズできなくなる点です。外れ値だけ色を変える、といった指定は効かなくなります。

progressive は1フレームで描く要素数で、既定は400です。progressiveThreshold の既定は3000で、データ量がこれを超えるとprogressive描画が自動で有効になります。progressive: 0 を指定すると、常に無効になります。チャンクの切り方を決める progressiveChunkMode もあり、'sequential' はデータ順、'mod' は剰余で全体から拾うので、描画途中の見え方が良くなります。

つまり progressive は既定で自動オンです。数千点を超えても固まるなら、progressive: 0 が残っていないか、別の原因(折れ線のシンボルや点ごとのスタイル指定)を疑います。

datasetに寄せると、間引きの指示が楽になる

dataset はECharts 4で入った部品で、データを系列の外で一元管理します。二次元配列やオブジェクト配列をそのまま渡せ、系列側は encode でどの列をxとyに使うかを指定します。複数の系列や部品でデータを共有できるので、同じ配列を系列ごとに複製する書き方より、メモリも設定量も減らせます。

もう1つ見ておく点が、dimensionsの type です。'float' か 'int' を指定すると、データは TypedArray に格納され、性能最適化に向くと説明されています。数値列が大半の時系列なら、指定しておく価値があります。

書き換えの前後は次のとおりです。

前と後

系列に直接データを持つ書き方から dataset へ

BEFORE

系列ごとに data を持つ

series: [
  { type: 'line', data: rows },
  { type: 'line', data: rows.map(([t, v]) => [t, v * 0.5]) },
]
AFTER

dataset を 1 つ置いて encode で参照

dataset: {
  source: rows,
  dimensions: [{ name: 'ts' }, { name: 'value', type: 'float' }],
},
series: [
  { type: 'line', encode: { x: 'ts', y: 'value' }, sampling: 'lttb', showSymbol: false },
],

datasetに渡せる形式は、先頭行に次元名を置く二次元配列と、キーが次元名になるオブジェクト配列の2つが代表的です。数十万行を扱うなら、行ごとにキー名を繰り返さない二次元配列のほうが、データの記述が短くなります。APIの応答がオブジェクト配列で来る場合は、描画の直前に二次元配列へ詰め替える層を1つ挟む案を、Claude Codeに比較させる価値があります。

既存のoptionをdataset方式へ書き換えるときは、次のように範囲を限って頼みます。

sensor-chart.ts の series[].data を dataset.source に移して、encode で参照する形に書き換えてください。
見た目が変わらないことを確認できるよう、書き換え前後の option を比較するテストも添えてください。

Claude Codeにoption設計を任せる手順

ここからが本題です。optionを直す作業は、いきなり編集させず、計画を確認してから進めます。Claude Codeには、ファイルを読んで計画を出し、承認するまで編集しないplan modeがあります。起動時に指定する方法と、セッション中にShift+Tabで切り替える方法があります。

claude --permission-mode plan

最初の依頼では、症状と条件を具体的に伝えます。件数、系列の種類、固まる操作、変えてはいけない見た目の4つが揃っていると、Claude Codeが sampling と large のどちらを選ぶべきかを自分で絞れます。

src/charts/sensor-chart.ts の option を見て、50万点で固まる原因を洗ってください。
系列は折れ線 3 本と散布図 1 本です。固まるのは初回表示と dataZoom の操作時です。
見た目の変更は避けたいので、まず設計案だけ出してください。編集はまだしないでください。

Claude Codeが返す案は、そのまま採用せず、次の観点で確認します。

  1. 折れ線に sampling が入っているか。入れるなら値の理由が書かれているか
  2. 全点を描く折れ線で showSymbol が false になっているか
  3. 散布図に large を足す場合、点ごとのスタイル指定が消えても困らないか
  4. データを dataset に寄せる案が、複数系列の重複を減らすか

3番は見落としやすい点です。large は個別スタイルを諦める設定なので、外れ値の強調がある図では、散布図は large を使わず、progressive と件数の絞り込みで対処する案に分かれます。

設計をテストで固定する

間引きの設定は、あとから別の人が sampling を消しても、見た目が壊れないので気づかれません。直した設定が後退しないように、optionの生成関数をテストで押さえます。公式の手順では、テストを依頼し、実行して失敗を直させる流れです。

buildSensorOption の単体テストを追加してください。
・line 系列はすべて sampling が指定され、showSymbol が false であること
・scatter 系列は large が true で、largeThreshold が 2000 以上であること
・dataset の value 列が type: 'float' であること
追加したら実行して、失敗があれば直してください。

期待する形のテストは、たとえば次のようなものです(例として示す形です)。

import { describe, it, expect } from 'vitest';
import { buildSensorOption } from './sensor-chart';
 
describe('buildSensorOption', () => {
  const option = buildSensorOption([[0, 1], [1, 2]]);
  const series = option.series as Array<Record<string, unknown>>;
 
  it('折れ線は間引きとシンボル抑制を持つ', () => {
    for (const s of series.filter((x) => x.type === 'line')) {
      expect(s.sampling).toBeDefined();
      expect(s.showSymbol).toBe(false);
    }
  });
 
  it('散布図は large を有効にしている', () => {
    for (const s of series.filter((x) => x.type === 'scatter')) {
      expect(s.large).toBe(true);
    }
  });
});

このテストが見ているのはoptionの中身で、描画の速さではありません。速さは実機でしか分かりません。ブラウザの開発者ツールでPerformanceパネルを録画し、スクリーンショットをClaude Codeに貼って読ませる手が使えます。画像は画面へのドラッグ、Ctrl+V での貼り付け、パス指定のいずれかで渡せます。

CLAUDE.mdに書いておくと設計がぶれない

毎回同じ説明をしないために、プロジェクトのCLAUDE.mdに判断基準を置きます。チーム全体で規約として持つ考え方は、Claude Codeチーム導入ガイドにも書いています。

## ECharts の option 規約
- 1,000 点を超える line 系列は sampling を必ず指定し、showSymbol を false にする
- scatter で 2,000 点を超える場合は large を使う。点ごとのスタイルは諦める
- データは dataset に寄せ、数値列の dimensions には type: 'float' を付ける
- option の生成は関数に切り出し、上記をテストで固定する

規約に具体的な数値を入れると、Claude Codeが新しい系列を足すときにも同じ基準で書きます。1,000や2,000は例で、自分のデータの密度に合わせて決めてください。

選び方の早見表

症状最初に足す設定注意点
折れ線が数十万点で重い最初に足す設定sampling と showSymbol: false注意点集計値を見せたい系列に average を使うと値が変わる
散布図が数万点で重い最初に足す設定large注意点個別スタイルが効かなくなる
初回表示の一瞬が固まる最初に足す設定progressive を確認注意点progressive: 0 が残っていないか
系列ごとに同じ配列を複製している最初に足す設定dataset に寄せる注意点encode の列指定を忘れない
大量の点と操作が多い最初に足す設定レンダラーをcanvasに注意点SVGはメモリが少ない反面、大量データはcanvasが有利

最後の行はレンダラーの話です。EChartsは既定でCanvasを使います。大量のデータ点を描く場合や、データを使った複雑な操作が要る場合は、現状Canvasのほうが向くと説明されています。SVGはメモリ消費が少なく、拡大してもぼやけませんが、大量の図形には向きません。逆に、1画面にEChartsのインスタンスを大量に作ってブラウザが落ちる場合や、古いAndroid端末では、SVGのほうが良い結果になることがあると説明されています。点数の問題か、インスタンス数の問題かを、Claude Codeに切り分けさせてから設定を選びます。

よくある落とし穴

落とし穴

間引いたのに ECharts が速くならない

sampling を足しても、showSymbol が true のままだと各点にシンボルを描くので、効果が薄れます。散布図に足した large が効かないときは、データ件数が largeThreshold(既定2000)を超えているかを確認します。

もう1つは、見た目の検証が抜けることです。sampling: 'lttb' は傾向と極値を保つとされますが、保たれるのは間引き後の形です。重要な1点(障害の瞬間のスパイクなど)を必ず見せたい場合は、間引きに任せず、その点だけ別系列で足す案も計画に含めてもらいます。

Chart.jsのような他のライブラリでは、設定名も間引きの考え方も異なります。ここで挙げた設定名はEChartsのものとして読んでください。

まとめ

大量データで固まるEChartsは、描く点を減らす(sampling・large)、描画を分ける(progressive)、データを寄せる(dataset)の4手のうち、系列の種類に合うものを選べば解けます。Claude Codeにはplan modeで設計案を出させ、optionの中身をテストで固定し、速さは開発者ツールの録画で確かめる、という分担が現実的です。グラフの表やデータを読み上げ用に添える作業は、Claudeでグラフの代替テキストと表データを付ける手順が続きの工程になります。データベース側から件数を絞る設計は、Claude Codeでデータベースに接続する方法が参考になります。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. echarts.apache.org/en/option.html
  2. echarts.apache.org/handbook/en/concepts/dataset
  3. echarts.apache.org/handbook/en/best-practices/canvas-vs-svg
  4. code.claude.com/docs/en/common-workflows
この記事を共有:XはてブLinkedIn