この記事でできること
- 複数の公開調査データをD3.jsで横断比較できるバーチャートに整形・表示する手順を理解する
- WordPress(SWELLテーマ)でD3.jsのスクリプトが動かない原因と解決方法を把握する
- 「定義が異なるデータを同一チャートに表示する」設計の判断基準を学ぶ
実際に動作するツールは生成AI企業導入率ダッシュボード(AI Japan Index)で確認できる。
環境・バージョン
- D3.js: v7.9.0(CDN:
https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js) - WordPress: 6.7系
- SWELLテーマ: 2.10系
- ブラウザ確認: Chrome 133 / Safari 17 / Firefox 124
- 動作OS: Windows 11 / macOS Sequoia 15
完成形
9機関の調査結果(17.3%〜64.4%)を1画面に表示し、ユーザーが数値の差の理由を確認できるダッシュボードを作る。
実装するチャート:
- 9調査横断比較バーチャート(大手中心vs全規模を色分け)
- 企業規模別導入率バーチャート
- 国際比較バーチャート(中国95.8%・米国90.6%・ドイツ90.3%・日本55.2%)
- NRI時系列折れ線チャート(2023〜2025年度)
- 導入障壁横棒グラフ
Step 1: データの整形
9調査の数値をそのまま使うのではなく、「定義・対象規模・調査時期」をセットでオブジェクトに持たせる。これをしないと後でUI上で「なぜ数値が違うのか」を表示できなくなる。
// data.js(HTMLにインライン展開)
const surveyData = [
{
org: "JUAS",
date: "2026年2月",
rate: 33.9,
n: 957,
definition: "「導入済み」のみ(試験導入除く)",
scale: "large" // large=大手中心 / mixed=全規模
},
{
org: "NRI",
date: "2025年11月",
rate: 57.7,
n: 517,
definition: "「導入済み」(試験利用含む可能性あり)",
scale: "large"
},
{
org: "日経BP",
date: "2025年9月",
rate: 64.4,
n: 1450,
definition: "IT・ビジネス関心層への調査(最高値)",
scale: "large"
},
{
org: "総務省",
date: "2025年7月",
rate: 55.2,
n: null,
definition: "企業の生成AI「業務で使用中」",
scale: "mixed"
},
{
org: "TSR",
date: "2025年8月",
rate: 25.2,
n: 6645,
definition: "「会社として推進」(個人利用22.3%を除く)",
scale: "mixed"
},
{
org: "TDB",
date: "2024年8月",
rate: 17.3,
n: 4705,
definition: "「活用している」(最も厳格な定義・最小値)",
scale: "mixed"
}
];
Step 2: D3.jsをWordPressで読み込む
<script src="CDN">はWordPressで機能しない。 SWELLテーマが投稿コンテンツ内の外部スクリプトタグを無視するため、動的ロードが必要になる。
// NG: SWELLが無視するパターン
// <script src="https://cdn.jsdelivr.net/npm/d3@7/..."></script>
// OK: JS動的ロード
function loadD3(callback) {
if (typeof d3 !== 'undefined') {
callback();
return;
}
const s = document.createElement('script');
s.src = 'https://cdn.jsdelivr.net/npm/d3@7/dist/d3.min.js';
s.onload = callback;
s.onerror = function() {
const w = document.getElementById('aji-genai-dashboard-wrap');
if (w) { w.innerHTML = '<p>グラフの読み込みに失敗しました</p>'; }
};
document.head.appendChild(s);
}
document.addEventListener('DOMContentLoaded', function() {
loadD3(initAllCharts);
});
Step 3: 横断比較バーチャートの実装
9調査を並べる際、「大手中心(high bias)」と「全規模(realistic)」をユーザーが区別できるよう色分けする。
function renderSurveyChart(data) {
const wrap = document.getElementById('survey-chart');
if (!wrap) return;
const mobile = (window.innerWidth <= 767);
const margin = { top: 16, right: mobile ? 8 : 80, bottom: 50, left: mobile ? 15 : 120 };
const W = wrap.clientWidth || 700;
const H = data.length * (mobile ? 32 : 40) + margin.top + margin.bottom;
const innerW = W - margin.left - margin.right;
const innerH = H - margin.top - margin.bottom;
const svg = d3.select(wrap).append('svg').attr('width', W).attr('height', H);
const g = svg.append('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
const yScale = d3.scaleBand()
.domain(data.map(d => d.org))
.range([0, innerH])
.padding(0.25);
const xScale = d3.scaleLinear().domain([0, 100]).range([0, innerW]);
// バー(大手中心=オレンジ、全規模=グレー)
g.selectAll('.bar')
.data(data)
.enter()
.append('rect')
.attr('y', d => yScale(d.org))
.attr('x', 0)
.attr('height', yScale.bandwidth())
.attr('width', d => xScale(d.rate))
.attr('fill', d => (d.scale === 'large') ? '#ff8906' : '#a7a9be')
.attr('rx', 2);
// PC: 数値ラベル
if (!mobile) {
g.selectAll('.val')
.data(data)
.enter()
.append('text')
.attr('y', d => yScale(d.org) + yScale.bandwidth() / 2 + 4)
.attr('x', d => xScale(d.rate) + 5)
.attr('fill', '#e0e0e0')
.attr('font-size', '12px')
.text(d => d.rate + '%');
g.append('g').call(d3.axisLeft(yScale).tickSize(0)).select('.domain').remove();
g.selectAll('.tick text').attr('fill', '#e0e0e0');
}
// X軸(スマホは3本に間引く)
const xAxisG = g.append('g')
.attr('transform', 'translate(0,' + innerH + ')')
.call(d3.axisBottom(xScale).tickFormat(d => d + '%'));
xAxisG.select('.domain').remove();
xAxisG.selectAll('text').attr('fill', '#a7a9be');
if (mobile) {
const ticks = xAxisG.selectAll('.tick');
const n = ticks.size();
const keep = [0, Math.floor((n - 1) / 2), n - 1];
ticks.each(function(d, i) {
if (keep.indexOf(i) === -1) { d3.select(this).style('display', 'none'); }
});
}
// スマホ: タッチで定義をパネル表示
if (mobile) {
const panel = document.getElementById('mobile-panel');
g.selectAll('.bar')
.on('touchstart', function(e, d) {
e.preventDefault();
e.stopPropagation();
if (panel) {
panel.innerHTML = '<strong>' + d.org + ' ' + d.date + '</strong>: ' +
d.rate + '% — ' + d.definition + '(n=' + (d.n || '非公開') + ')';
panel.style.display = 'block';
}
});
}
}
Step 4: && 問題を解消してWordPressでデバッグする
WordPressの投稿コンテンツ内のJSスクリプトが動かない原因の多くは && 変換問題だ。
// NG: WordPressが && に変換して構文エラー
function checkData(arr) {
if (arr !== null && arr.length > 0) {
render(arr);
}
}
// OK: ネストifで回避
function checkData(arr) {
if (arr !== null) {
if (arr.length > 0) {
render(arr);
}
}
}
デバッグ手順:
- WP管理画面でHTMLブロックのソースを「テキスト表示」で確認する
-
&&が&&に変換されていないかチェックする - 変換されていたら全ての
&&をネストifまたは三項演算子に修正する -
<!-- wp:html -->ブロックで保存し直す
Step 5: スマホ対応と下部パネル
スマホではY軸の日本語ラベルが必ず見切れるため、ラベルを非表示にしてタッチで下部パネルに切り替える。
<!-- 下部固定パネル(HTML構造) -->
<div id="mobile-panel"
style="display:none; position:fixed; bottom:0; left:0; width:100%;
background:#1a1a2e; border-top:2px solid #ff8906;
padding:12px 16px; z-index:10000;
max-height:40vh; overflow-y:auto;">
<button onclick="document.getElementById('mobile-panel').style.display='none'"
style="float:right; background:transparent; border:none; color:#ff8906; font-size:18px;">×</button>
<div id="mobile-panel-content"></div>
</div>
つまずきポイントまとめ
-
<script src="CDN">がWordPressで無視される → JS動的ロードに変更 -
&&演算子が&&に変換されてJS構文エラー → ネストifまたは三項演算子 - Chart.jsのcanvasがSWELLで描画されない → D3.jsのSVG描画に変更
- scaleBandのドメインと
.attr('y')のアクセサが不一致でバーがずれる → 同じ値で統一 - スマホで日本語バー名(組織名8〜10文字)がX軸に重なる → モバイル時に3本に間引く
- 異なる定義の数値を同一チャートに並べると「精度の差」と誤解される →
scaleフィールドで色分け + 定義ポップアップ -
d3.eventがv7で廃止 →function(event, d)として第一引数で受け取る
まとめ(今回学んだこと)
- WordPressでD3.jsを動かす3つの必須ルール: 動的ロード・&&禁止・wp:htmlブロック
- 複数定義の調査データは「定義フィールド」を設けて色分けし、タッチ/ホバーで定義を表示する
- スマホ対応はY軸非表示 + 下部固定パネルのセットで設計する
- 推定値はレンジ(min〜max)で表示する方が「単一点」より誤解が少ない
関連ツールはAI Japan Indexで全て無料公開している。
