こんにちわ、PHPエンジニアのエンジニア婦人(@naho_osada)です。
PHPエンジニアとして9年~の経験があります。
グラフの描画をするときに使われる、d3.jsというライブラリ。
これをもっと簡単に使えるようにしたものがdimple.jsです。
私はd3.jsは使ったことがないのですが、先日dimple.jsを使う機会があったので、備忘録も兼ねて使い方を記録しておきます。
dimple.jsとは
早い話が「d3.jsをもっと手軽に扱えるようにした、グラフ描画のjsライブラリ」です。
dimple.jsの使い方
基本
ダウンロードしてきたファイルを読み込ませます。
<script src="保存先のパス/d3.v4.min.js"></script>
<script src="保存先のパス/dimple.v2.3.0.min.js"></script>
パスは自分の環境に合わせてください。
javascriptを記述します。
var svg = dimple.newSvg("#bar", 800, 550);
var data = [
{"月":"6月", "回数":22},
{"月":"7月", "回数":197},
{"月":"8月", "回数":377},
{"月":"9月", "回数":371},
{"月":"10月", "回数":319},
{"月":"11月", "回数":305},
{"月":"12月", "回数":299},
];
var chart = new dimple.chart(svg, data);
// グラフ描画サイズを指定 左の余白、上の余白、グラフ幅、グラフの高さ
chart.setBounds(50, 50, 600, 400)
// x軸が基準となるのは「月」
chart.addMeasureAxis("x", "回数");
// y軸で表したいものは「月」
var y = chart.addCategoryAxis("y", "月");
// 縦軸yは月降順で表示
y.addOrderRule(["12月","11月","10月","9月","8月", "7月", "6月"]);
// グラフを指定 単一の時はnullを指定する
chart.addSeries(null, dimple.plot.bar);
chart.draw();
これでグラフが描画されます。
単純なもの自体は難しくないですね。
横棒グラフのデモページはこちら ※スマートフォンで閲覧する場合、グラフが綺麗に表示されないことがあります。
dataをjavascript配列で読み込ませ、どういったグラフにするのかオプションで支持を出し、最後にdraw()することでグラフを描画します。
グラフの画像はSVG形式なので、データ範囲にカーソルを合わせると内容が表示されます。
色々なグラフを作ってみた
よく使いそうなグラフを作ってみました。
オプション値を羅列するよりも、実際にあるものをソースのコメントと共に見た方が早いと思うので、ソースを記述します。
尚、以下のソースはGitHubで公開しています。
デモページはこちらから確認できます。 ※スマートフォンで閲覧する場合、グラフが綺麗に表示されないことがあります。
円グラフ
var svg = dimple.newSvg("#circle", 800, 500);
var data = [
{"種類":"コーヒー", "回":3},
{"種類":"緑茶", "回":2},
{"種類":"麦茶", "回":8},
{"種類":"水", "回":2},
{"種類":"牛乳", "回":1},
{"種類":"その他", "回":5},
];
var chart = new dimple.chart(svg, data);
// グラフ描画サイズを指定 左の余白、上の余白、グラフ幅、グラフの高さ
chart.setBounds(50, 50, 500, 400)
// 円グラフに表示するのは「回数」
chart.addMeasureAxis("p", "回");
// 色分けするのは「種類」
chart.addSeries('種類', dimple.plot.pie);
chart.addLegend(500, 20, 90, 300, "left");
chart.draw();
円グラフのデモページはこちら ※スマートフォンで閲覧する場合、グラフが綺麗に表示されないことがあります。
縦棒グラフ(複数)
var svg = dimple.newSvg("#bar-mixed", 800, 550);
var data = [
{"月":"9月", "種類":"収入", "金額":18000},
{"月":"9月", "種類":"支出", "金額":14551},
{"月":"10月", "種類":"収入", "金額":18000},
{"月":"10月", "種類":"支出", "金額":32989},
{"月":"11月", "種類":"収入", "金額":18000},
{"月":"11月", "種類":"支出", "金額":15668},
{"月":"12月", "種類":"収入", "金額":18000},
{"月":"12月", "種類":"支出", "金額":20661},
];
var chart = new dimple.chart(svg, data);
// グラフ描画サイズを指定 左の余白、上の余白、グラフ幅、グラフの高さ
chart.setBounds(50, 50, 600, 400)
// x軸が基準となるのは「月」と「種類(収入と支出を棒グラフにしたい)」
var x = chart.addCategoryAxis("x", ["月", "種類"]);
// y軸の高さで表したいものは「金額」
var y = chart.addMeasureAxis("y", "金額");
// 棒グラフの元データは「収入と支出」なので、「種類」を選択
// 金額ではない
var barAxis = chart.addSeries("種類", dimple.plot.bar);
// 横軸xは月昇順で表示
x.addOrderRule(["9月", "10月", "11月", "12月"]);
// 凡例の並びは収入→支出の順で表示
barAxis.addOrderRule(["収入", "支出"]);
// 凡例を右に表示
chart.addLegend(500, 0, 90, 300, "right");
// 棒の色を指定
// 複数色がある場合でないと反応しない
chart.assignColor("収入", "#5D99FF");
chart.assignColor("支出", "#FF8856");
chart.draw();
複数の縦棒グラフのデモはこちら ※スマートフォンで閲覧する場合、グラフが綺麗に表示されないことがあります。
折れ線グラフ
var svg = dimple.newSvg("#line", 800, 550);
var data = [
{"月":"7月", "ページビュー":374},
{"月":"8月", "ページビュー":1201},
{"月":"9月", "ページビュー":602},
{"月":"10月", "ページビュー":1086},
{"月":"11月", "ページビュー":1099},
{"月":"12月", "ページビュー":1615},
];
var chart = new dimple.chart(svg, data);
// グラフ描画サイズを指定 左の余白、上の余白、グラフ幅、グラフの高さ
chart.setBounds(50, 50, 600, 400)
// x軸が基準となるのは「月」
var x = chart.addCategoryAxis("x", "月");
// y軸の高さで表したいものは「ページビュー」
chart.addMeasureAxis("y", "ページビュー");
// 横軸xは月昇順で表示
x.addOrderRule(["7月","8月","9月","10月", "11月", "12月"]);
// グラフを指定 単一の時はnullを指定する
var s = chart.addSeries(null, dimple.plot.line);
// カーブラインなどのオプションを設定できる
s.interpolation = "cardinal";
chart.draw();
折れ線グラフのデモはこちら ※スマートフォンで閲覧する場合、グラフが綺麗に表示されないことがあります。
折れ線グラフ(複数)
var svg = dimple.newSvg("#line-mixed", 800, 550);
var data = [
{"月":"6月", "種類":"ツイート数", "回数":22},
{"月":"6月", "種類":"プロフィールアクセス数", "回数":18},
{"月":"7月", "種類":"ツイート数", "回数":197},
{"月":"7月", "種類":"プロフィールアクセス数", "回数":888},
{"月":"8月", "種類":"ツイート数", "回数":377},
{"月":"8月", "種類":"プロフィールアクセス数", "回数":3372},
{"月":"9月", "種類":"ツイート数", "回数":371},
{"月":"9月", "種類":"プロフィールアクセス数", "回数":1674},
{"月":"10月", "種類":"ツイート数", "回数":319},
{"月":"10月", "種類":"プロフィールアクセス数", "回数":2000},
{"月":"11月", "種類":"ツイート数", "回数":305},
{"月":"11月", "種類":"プロフィールアクセス数", "回数":1742},
{"月":"12月", "種類":"ツイート数", "回数":299},
{"月":"12月", "種類":"プロフィールアクセス数", "回数":1023},
];
var chart = new dimple.chart(svg, data);
// グラフ描画サイズを指定 左の余白、上の余白、グラフ幅、グラフの高さ
chart.setBounds(50, 50, 600, 400)
// x軸が基準となるのは「月」と「種類(ツイート数とインプレッション数を棒グラフにしたい)」
var x = chart.addCategoryAxis("x", ["月", "種類"]);
// y軸の高さで表したいものは「金額」
var y = chart.addMeasureAxis("y", "回数");
// 棒グラフの元データは「収入と支出」なので、「種類」を選択
// 金額ではない
var barAxis = chart.addSeries("種類", dimple.plot.line);
// 横軸xは月昇順で表示
x.addOrderRule(["6月", "7月", "8月", "9月", "10月", "11月", "12月"]);
// 凡例を右に表示
chart.addLegend(500, 0, 90, 300, "left");
// 棒の色を指定
// 複数色がある場合でないと反応しない?
chart.assignColor("ツイート数", "#005FFF");
chart.assignColor("プロフィールアクセス数", "#00AA00");
chart.draw();
折れ線グラフ(複数)のデモはこちら ※スマートフォンで閲覧する場合、グラフが綺麗に表示されないことがあります。
実際に使うとしたらどういう使い方になる?
ここではjsファイル内に直接データ項目を書いて表示する、というやり方を取っています。
しかし、実際に使うときは「データを動的に取ってきてグラフを生成する」ということが多いのではないでしょうか。
サーバーサイドのPHPやRubyなどでjavascriptの配列データを作って、それを出力してどうこうする…というのが予想されます。
このデータの上手な出力方法、動的にグラフを生成できるかどうか。これがエンジニアの腕の見せ所、だと思います。
サンプルが参考になれば幸いです。
dimple.jsだとできないこと(2019/10/12追記)
dimple.jsを使うと、d3.jsよりは簡単な書き方でグラフの生成ができるますが、反対に「dimple.jsだから、単体で色々対応するのが難しいこと」もあります。
対策は考え方次第でできます。
レスポンシブ対応が難しい
レスポンシブ対応をしたい要望は当たり前のようにありますが、dimple.js単体でレスポンシブ機能を叶えるのはちょっと無理があります。
dimple.jsの本サイトにレスポンシブサンプルがあります。
しかし、グラフの種類によっては細かい調整が必要になることが多く、それならグラフそのものを変えて見やすい幅と高さを指定した方がいい、という結論も出そうです。
たとえば「横棒グラフなどの横幅を広く取りたいグラフ」はPC向けではありますが、スマートフォンのような幅が狭い端末で閲覧するには不向きです。
この場合は「スマートフォンの場合は縦棒グラフで表示する」とプログラムを書き換えた方が望ましいでしょう。
13以上の凡例を持つグラフを生成できない
「13以上の凡例を持つ動的グラフを作る」なんていう状況はあまりないと思いますが…
通常、dimple.jsでは各データの配色を自動で決めてくれます(手動で決めることもできます)。
このデフォルト色ですが、設定されたすべての色を一巡すると、はじめに戻ります。
1番の色と13番の色が同一になります(※確か12色までしか指定がない) 。
これを避けるには、デフォルトカラーの数を超えてしまう場合は手動でカラーリングを設定します。色コード配列を持っておいて、凡例の番号順に色を振っていくイメージです。
その他特殊な要望はd3.js的な書き方になる
グラフにマウスオーバーすると出てくるツールチップの吹き出しを変更したい、特殊なラベルを出したいときなど…実際作ってみると要望は様々出てきます。そういうものです。
こういった場合、結局はd3.jsの書き方になることが発生してきます。
基本的なものはサンプルがありますが、これ以外のことをやろうとしたらd3.jsの書き方をしなければなりません。
以下に一例を記載しておきます。
グラフ内に数値ラベルを出したい
dimple.js本サイトのサンプルにあります。グラフ内に数値を出したいこともあるでしょう。
もし「このラベルの数値を%で出したい」となったらプログラムで計算して書き出すことになります。
凡例名称が長いので収まりきらない
収まらないから改行したい場合、<text>タグを使ってx座標とy座標を指定し、改行先の位置を計算して…ととても大変。
そもそも凡例名称長くするなっていう話でもあります。dimple.jsは長い名称を想定した作りになっていません。
長すぎる場合はツールチップの吹き出しも崩れます。
吹き出しの内容を変えたい
同じく、dimple.js本サイトのサンプルにあります。
上の「凡例名称が長いので収まりきらない」でもあるように、デフォルト状態では崩れてしまうので、その場合は本サイトサンプルのようにする必要があります。