1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AIエージェントのデータダッシュボードを8種類のD3.jsチャートで作ってみた話

1
Posted at

ai-agent-adoption.jpg

AIエージェントのデータダッシュボードを8種類のD3.jsチャートで作ってみた話

AIエージェントの普及率や市場規模データをまとめたダッシュボードを作った。

エリアチャート、ロリポップ、ステップ、ワッフル、ダンベル、対数棒グラフ…と8種類のチャートをWordPressの1記事内に全部突っ込む作業だった。

「D3.jsは聞いたことある」「WordPressでチャートを出したい」というレベルの方に向けて、失敗したところを中心に書く。

完成したもの: AIエージェント普及率ダッシュボード


この記事でできること

  • D3.jsをWordPressで動かす基本パターンが理解できる
  • 「どんなデータにどんなチャートを使うか」の選び方がわかる
  • SVGとHTML divの使い分けルールが整理できる
  • スマホ対応(タップで詳細表示)の実装パターンがわかる
  • 実際に動作するダッシュボードはAIエージェント普及率ダッシュボードで確認できる

環境・前提

  • ブラウザ: モダンブラウザ(Chrome, Firefox, Edge最新版)
  • D3.js: v7(CDNから動的ロード)
  • WordPress: 6系 + SWELLテーマ
  • JavaScript: Vanilla JS(ES5準拠、const/let 使わない)
  • 外部依存: D3.js以外なし

完成形

8つのチャートを1ページに並べたダッシュボード。PCでは2カラムレイアウト、スマホでは縦積み。全チャートがタップ/ホバーで詳細を表示する。

こちらから実物を確認できる。

作ってみて思ったのは、「8種類のチャートを1つの記事内に入れる」という設計よりも、「WordPressで動かす」ための制約対応に時間がかかったということだ。その話を中心に書く。


手順

Step 1: WordPressでD3.jsを動かす

最初にやることは「D3.jsを動かす」の1点に集中する。

NG例(SWELLでは動かない):

<script src="https://cdn.jsdelivr.net/npm/d3@7"></script>
<script>
  var svg = d3.select('body')...
</script>

SWELLテーマはカスタムHTMLブロック内の外部scriptタグを無視する。エラーも出ない。ただ読み込まれない。

OK例(動的ロードパターン):

function loadD3(callback) {
  if (typeof d3 !== 'undefined') {
    callback();
    return;
  }
  var s = document.createElement('script');
  s.src = 'https://cdn.jsdelivr.net/npm/d3@7';
  s.onload = callback;
  document.head.appendChild(s);
}

loadD3(function() {
  // ここでD3.jsを使う
  initAllCharts();
});

typeof d3 で既にロード済みかを確認してから追加する。同じページに複数チャートブロックがある場合でも、D3.jsを二重ロードしない。

補足: callback ではなく onload で初期化を呼ぶことで、D3.jsが確実に使える状態になってから処理が始まる。

Step 2: && 問題に先回り対応する

つまずきポイント: WordPressは && をHTMLエンティティ(&#038;&#038;)に変換する。JSの構文として壊れてスクリプト全体が動かなくなる。

// NG: WordPressが壊す
if (a > 0 && b > 0) { ... }

// OK: 三項演算子で回避
var result = (a > 0) ? ((b > 0) ? doSomething() : null) : null;

// OK: ネストifで回避
if (a > 0) {
  if (b > 0) {
    doSomething();
  }
}

新しくチャートを書く前に「&& を一切使わない」というルールを頭に入れておくと、後から直す手間が省ける。

Step 3: CSSをスコープで囲む

ポイント: グローバルセレクタ(*{} body{} h1{} 等)はSWELLテーマを壊す。必ずツール固有のクラスでスコープを切る。

/* NG: グローバル */
.chart-container { ... }
h3 { ... }

/* OK: スコープ付き */
.aji-ai-agent-adoption-wrap .chart-container { ... }
.aji-ai-agent-adoption-wrap h3 { ... }

全てのCSSセレクタの先頭に .aji-{ツールID}-wrap を付ける。これだけで「テーマが崩れた」系の問題は99%防げる。

Step 4: SVGとHTML divの担当を決める

チャートを書く前に「何をSVGで描いて、何をHTMLで描くか」を決める。これを後から変えると全面書き直しになる。

チャート本体(バー・線・丸・エリア)  → SVG
軸の線と目盛り数値                   → SVG
バー右横の数値(PCのみ)             → SVG

業界名・目的名等の長い日本語ラベル   → HTML div(必須)
注記・出典テキスト                   → HTML div(必須)
凡例                                 → HTML div(必須)
推定値バッジ                         → HTML div

なぜラベルをHTMLにするか: SVGの <text> は自動改行しない。「テクノロジー・メディア・通信」のような長いラベルがスマホで確実に見切れる。HTML divはCSSのword-wrapで自動改行されるのでスマホでも安全。

Step 5: スマホのタッチイベントを実装する

スマホではマウス追従型のツールチップが使えない。代わりに画面下部に固定パネルを出す方式にする。

// PC: hoverで表示
element.addEventListener('mouseover', function(e) {
  showTooltip(e, data);
});

// スマホ: タップで下部固定パネル
element.addEventListener('touchstart', function(e) {
  e.preventDefault();
  e.stopPropagation(); // これがないとパネルが開いて即閉じる
  showMobilePanel(data);
});

つまずきポイント: e.stopPropagation() を書かないと、タッチイベントがdocumentまで伝わって「パネル外タップ」と誤判定される。開いた瞬間に閉じる謎のバグが起きる。必ず e.preventDefault()e.stopPropagation() をセットで書く。

Step 6: スマホでは数値ラベルを非表示にする

バー横の数値ラベルはPC専用にする。スマホで表示すると他の要素と重なる。

var mobile = window.innerWidth <= 767;

// 数値ラベルはPCのみ
if (!mobile) {
  g.append('text')
    .attr('x', xScale(d.value) + 8)
    .attr('y', barY)
    .attr('fill', '#e0e0e0')
    .attr('font-size', '12px')
    .text(d.value + '%');
}

スマホでは数値ラベルを出さない代わりに、タップで下部パネルに詳細を表示する。「チャートを見てタップで詳細」という動線にする。


つまずきポイントまとめ

  • 外部scriptタグが効かない: SWELLはカスタムHTMLブロック内の外部scriptタグを無視する。動的ロードパターン(createElement('script'))を使う
  • && がJSを壊す: WordPressが && をHTMLエンティティに変換する。三項演算子かネストifに書き換える
  • グローバルCSSがテーマを崩す: .aji-{ツールID}-wrap スコープを全セレクタに付ける
  • ラベルがスマホで見切れる: 長い日本語ラベルはSVG <text> ではなくHTML divで実装する
  • パネルが開いて即閉じる: touchstarte.stopPropagation() を忘れている。e.preventDefault() とセットで必ず書く

まとめ

  • D3.jsをWordPressで動かす際のポイントは「動的ロード・&&回避・CSSスコープ・SVG/HTML分担・スマホタッチ対応」の5点
  • チャートの種類選びより「WordPressで動かす制約対応」に時間がかかる
  • 8種類のチャートを作って分かったのは「データに合ったチャート選び」が表現力の9割を決めるということ
  • 対数スケールを使うときは「なぜ等間隔でないか」の注記を必ずHTML divで出す

完成したダッシュボードと関連ツール一覧は以下から。
AIエージェント普及率ダッシュボード
AI Japan Index — 全ツール一覧

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?