前回の記事(で、これクリックできるの?→できました。nebula.jsの自作チャートにQlikの「選択・連想・ドリルダウン」を通してみた)で、自作チャートに Qlik の「選択・連想・ドリルダウン」を通しました。クリックさえ Qlik に返せば、あとは連想エンジンが全部やってくれる。見た目は Web、頭脳は Qlik。
ただ、ここまでのデータはカテゴリ8つ × 12か月のトイデータでした。かわいいデータで動いても、「で、実務では?」と言われたら何も言い返せません。
なので今回は実データを流し込みます。最終的にはこうなります。

1. まずは今までのチャートに、実データをそのまま流し込む
使ったのは、Tableau のサンプルでおなじみの「スーパーストア」の日本版です。1万明細・4年分で、製品・地域・顧客・売上・利益・割引率が入っています。利益が赤字の明細が2割以上あるのが、分析しがいのあるところです。
(Qlik Cloud にアップロードしてロードスクリプトで読むだけですが、CSV が Shift-JIS なので codepage is 932 を付けないと途中で読み込みが止まる、という罠だけ踏みました。)
これを、前編・後編で作ってきた rich-table(1つの拡張で十数パターンに描き分けるやつ)にそのまま流し込みます。

見た目は前編のまま、中身だけ実データになりました。せっかくなので、実データならではの対応をいくつか入れています。
ドリルが2軸になった
製品(カテゴリ → サブカテゴリ → 製品名)と、時間(年 → 四半期 → 月)の2本の階層を持たせました。行をクリックすると製品側、列の見出しをクリックすると時間側が降ります。パンくずも2本です。
仕組みは後編と同じで、次元を2つとも qGrouping: 'H' の階層グループにしただけです。
利益を見るパターンを追加
売上だけでなく利益が入ったので、利益ヒートマップ(赤字は赤、黒字は緑)と、0 を中心に左右に振れる利益のダイバージングバー、割引率 × 利益率の散布図を足しました。どれも「家具」に降りた状態です。



家具の中で「テーブル」だけが真っ赤です。しかも4年連続で赤字で、2019年がいちばん深い(-1,379,183)。これがヒートマップだと一目で分かります。
ここで1つだけ気をつけたのが、率はそのまま足せないことです。利益率や平均割引率をそのままメジャーにすると、ドリルで階層が変わったときに正しく集計し直せません。なのでメジャーは Sum(Profit) や Sum(Sales*Discount) のような「足せる素の値」で持って、率は描画するときに割り算しています。
2. でも、これで毎日仕事をするのはつらい
実データで動いた。赤字も見つかった。……んですが、これを毎朝開いて仕事をするかというと、ちょっと違います。
rich-table は「1つの表を十数通りに描き分ける」ための見せ物です。上から下まで、描いているのは全部同じ数字。見せ方の引き出しとしては楽しいけれど、
- 全体の KPI、推移、地域、顧客を一度に見渡せない
- 見たい数字を探してスクロールし続けることになる
- 「テーブルが赤字」は分かっても、「なぜ?」を別の角度から確かめに行けない
実務で欲しいのは、1画面で全体が見えて、気になったところをクリックして掘れる、普通のダッシュボードです。なので、作り替えました。
3. ダッシュボードに作り替えた
改めて、完成品です。
KPI:まず全体を5つの数字で

売上 2.27億円、利益 2,739万円、利益率 12.1%、平均割引率 8.3%、赤字率 23.2%。
数字の大きさと色だけで「どこを見るべきか」が分かるようにしています。赤字率だけは最初から赤。ここが今回の主役です。
推移:売上と利益を2軸で

売上(左軸)と利益(右軸)の月次推移です。売上と利益は桁が違うので2軸にしています。
サブカテゴリ × 割引率と利益率

左はサブカテゴリ別の売上で、赤字のサブカテゴリだけ赤い棒になっています。右は横軸が割引率、縦軸が利益率の散布図で、円の大きさが売上です。
右下、つまり「割引しているのに利益が出ていない」位置に、赤い円がぽつんと1つあります。さっきの「テーブル」です。
地図とヒートマップ

地域別の売上を日本地図で塗り分けました。都道府県のポリゴンを地域の売上で塗っているだけなので、SVG の path に色を付けているだけです。右はサブカテゴリ × 地域のヒートマップ。
顧客区分と上位顧客

顧客区分の構成比と、売上トップ10の顧客です。上位顧客は売上だけでなく利益と利益率も並べているので、「売上は多いけど利益が薄いお客さん」がすぐ分かります。
そして左側にはリストボックス(顧客区分・地域・カテゴリ・顧客名)、右上には今の選択状態と「すべて解除」ボタン。このあたりは Qlik のシートと同じ使い勝手にしています。
4. 全部クリックできる
ここからが本題です。このダッシュボード、どのチャートをクリックしても全チャートが連動します。
さっきの「テーブル」をクリックしてみます。
KPI がこうなりました。
- 売上 1,392万円
- 利益 -318万円
- 利益率 -22.9%
- 平均割引率 24.7%(全体は 8.3%)
- 赤字率 70.4%
テーブルは、全体の3倍近い割引をしていて、明細の7割が赤字でした。売っても売っても赤字、というやつです。数字自体は rich-table の計器パネルにも出ていましたが、ここでは KPI・推移・地図・散布図が1クリックで一斉に「テーブルだけの世界」に切り替わるので、「割引のしすぎで赤字」という話が画面全体から伝わってきます。
もちろん地図や顧客からも絞れます。
地図で関西地方をクリックして、左のリストで「家具」を足しました。関西 × 家具だと売上 2,110万円、利益率 15.8% と、全体(12.1%)よりむしろ優秀です。それでもサブカテゴリの棒を見ると、テーブルだけは利益率 -12.4% で赤いまま。地域を変えても赤字が消えないので、「特定の地域の問題」ではなく「テーブルという商材の値付けの問題」っぽい、というところまでクリック数回で辿り着けます。
「気になったところをクリックして、別の角度から見る」を、画面遷移なしで繰り返せる。これが Qlik の連想のいちばんおいしいところで、それが自作の見た目のまま使えます。
5. 仕組み:チャートごとにハイパーキューブを1個
rich-table は「1つのハイパーキューブを十数通りに描く」拡張でした。ダッシュボードは逆で、チャートごとにセッションオブジェクト(独立したハイパーキューブ)を作っているだけです。
for (const spec of specs) {
const model = await app.createSessionObject({
qInfo: { qType: 'ss-dash-chart' },
qHyperCubeDef: spec.hc,
});
const draw = async () => spec.render(await model.getLayout(), el);
// クリック → その次元の値を選択(連想で全チャートへ波及)
el.addEventListener('click', (evt) => {
const hit = evt.target.closest('[data-elem]');
if (hit) model.selectHyperCubeValues('/qHyperCubeDef', 0, [Number(hit.dataset.elem)], true);
});
model.on('changed', draw); // 選択が変わるとエンジンが通知してくる
await draw();
}
各チャートは「ハイパーキューブの定義」と「描画関数」のペアで、たとえば散布図の定義はこれだけです。
hc: {
qDimensions: [{ qDef: { qFieldDefs: ['SubCategory'] } }],
qMeasures: [
{ qDef: { qDef: '=Sum(Sales)' } },
{ qDef: { qDef: '=Sum(Profit)/Sum(Sales)' } }, // 利益率
{ qDef: { qDef: '=Sum(Sales*Discount)/Sum(Sales)' } }, // 売上加重の平均割引率
],
},
どこかで選択が起きると、エンジンが影響を受けるオブジェクトに changed を送ってくるので、受け取ったら getLayout() し直して描き直すだけ。チャート同士を繋ぐコードは、今回も1行もありません。
これ、構造としては Qlik のシートとまったく同じです。シートに置いたチャートも、1つ1つがハイパーキューブを持ったオブジェクトです。つまり描画だけを自分で書いた Qlik のシートを作った、と言えます。
ちなみに、stardust の組み込みチャートは1つも使っていません。enigma.js の getLayout と selectHyperCubeValues だけで描いています。見た目を100%自分で決めたかったので。
まとめ:見せ物から道具へ
- 前編・後編のチャートに実データを流し込んでも、連想・ドリルはそのまま動いた
- でも実務で使うなら、1画面で見渡せてクリックで掘れる「ダッシュボード」の形が要る
- ダッシュボードは「チャートごとにハイパーキューブ1個」で作れる。構造は Qlik のシートと同じで、連動のコードは今回も0行
前編で「実務でこそ効く」と大きく出たので、今回でやっと回収できた気がします。
次回予告:やりすぎます
実用的なダッシュボードができたので、次は逆に実用性を無視して遊びます。同じデータ・同じ連想のまま、見た目だけを変えた5種類を作りました。
- 光って脈打つネオン版
- スクロールするとチャートが描き上がっていく、すりガラス版
- 映画のタイトルバックみたいなシネマティック版
- 操作不要でずっと回り続ける、大画面サイネージ版
- スポットライトが1枚ずつ当たって解説してくれる、ガイドツアー版
中身は全部 Qlik です。たぶん、今回よりだいぶうるさいです。


