読者です 読者をやめる 読者になる 読者になる

D3.js + AngularJS な Radian のチュートリアルを進めながらグラフ書いてみた(関数プロットまで)

グラフ書きたいですね。グラフ書きたいんだけどいろいろ書いたりするの面倒だな。 かっこいいのがいいのならHighchartsがいいなーとか色々調べたりしてました。もうちょっと手軽感ほしいなーと思っていたら新しい良さげなものを教えてもらったので、使った感じと合わせて軽く使い方まとめます。

ということでRadianを使ってみました。 RadianはAngularとD3.jsを組み合わせたというごいすーな感じがするグラフ作成用のライブラリです。 D3なのでちゃんとSVGなのがとてもグッド。

チュートリアル

準備

ということでさくっとRadianの公式チュートリアルをさらう。

git clone git@github.com:openbrainsrc/Radian-tutorial.git
cd Radian-tutorial
git checkout -f part-1
node web-server.js

で、チュートリアルセットを持ってきてサーバーをたてる。template.htmlもあるので、今後使っていくのにも便利っぽい。(サーバーは別にnodeじゃなくてもOK。)

http://localhost:8000/index.htmlとかにアクセスすると各exampleへのリンクがあるので、適当にぽちぽちするとどんな感じのグラフができるのかが分かる。

こっからはtutorial.htmlを適宜コピーしながらやってけばOK。

plotについて

ex1

みんなだいすきsin関数

<plot>
  <lines x="[[seq(0,2*PI,101)]]" y="[[sin(x)]]"></lines>
</plot>

f:id:matsu_chara:20131031181837j:plain

plotタグがグラフのラッパーになっているらしい。 plotタグの中に色々書いていくことで、グラフを書いたりサイズを指定したりできるらしい。 linesタグはまだ気にするなとのこと。

ex2

<plot height=300 aspect=2>
  <lines x="[[seq(0,2*PI,101)]]" y="[[sin(x)]]"></lines>
</plot>

height=300 aspect=2によって高さが300になって横が600になる。(aspectは縦に対しての横の長さを決定する)

この時点で特に設定しなくても軸の目盛やら軸名やら書いてあってとてもお手軽。

ex3~

<plot height=300 aspect=2 axis-x="off" axis-y="off">
  <lines x="[[seq(0,2*PI,101)]]" y="[[sin(x)]]"></lines>
</plot>
<plot height=300 aspect=2 axis-x-label="Custom X axis label"
      axis-y-label="Custom Y axis label">
  <lines x="[[seq(0,2*PI,101)]]" y="[[sin(x)]]"></lines>
</plot>

目盛を消したり、ラベルをつけたり。

f:id:matsu_chara:20131031160829j:plain

もちろん日本語も問題ない(ラベルは適当) タイトルつけたり、フォントを変えたり、レンジを変えたりするのも同じ要領で設定可 詳しくはリファレンス参照のこと。

lines is 何

linesは x座標とy座標をRadian expression経由でjavascriptの配列形式として渡すと(x,y)の組としてポリラインを引いていくよ(十分近ければ曲線になるよ)とのこと。 Radian表現は[[]]のように二重角括弧でくくって書くらしい。括弧の中はjavascript+radianの文法が使えるらしい。

<plot height=300 aspect=2>
  <lines x="[[seq(0,2*PI,6)]]" y="[[sin(x)]]"></lines>
  <lines x="[[seq(0,2*PI,101)]]" y="[[cos(x)]]"></lines>
</plot>

とかするとカクカクになるのが分かる。

f:id:matsu_chara:20131031170355j:plain

ちなみに複数の曲線のxが同じ値でいいなら、下のようにすると共有できる。 (angularによって内側のスコープに継承される。なのでx以外のどんな変数や配列も共有可能。)

<plot height=300 aspect=2 x="[[seq(0,2*PI,101)]]">
  <lines y="[[sin(x)]]"></lines>
  <lines y="[[cos(x)]]"></lines>
</plot>

しゃれおつなライン

今もしゃれおつですが、linesにちょっと設定するだけで、さらにしゃれおつにできます。

<plot height=300 aspect=2 x="[[seq(0,2*PI,101)]]">
  <lines y="[[sin(x)]]" stroke="red" stroke-width=5></lines>
  <lines y="[[cos(x)]]" stroke="blue" stroke-width=10
         stroke-opacity=0.5></lines>
</plot>

デフォルトじゃない色がいい場合は stroke="rgb(0,0,255)"stroke="rgba(0,0,255,0.5)"も使えるらしい

ちょっと書いてみた。

<plot height=300 aspect=2 x="[[seq(-2*PI,2*PI,101)]]" range-y="-10,10" legend-switches>
  <lines y="[[(exp(x)-exp(-x))/2]]" stroke="green" stroke-width=1 label="sinh(x)"></lines>
  <lines y="[[(exp(x)+exp(-x))/2]]" stroke="orange" stroke-width=1 label="cosh(x)"></lines>
  <lines y="[[(exp(x)-exp(-x))/(exp(x)+exp(-x))]]" stroke="violet" stroke-width=5 stroke-opacity=0.9 label="tanh(x)"></lines>
</plot>

f:id:matsu_chara:20131031171953j:plain

鬼のように簡単というより直感的に使えました。(計算もベクトル化されてて配列を意識しないでも普通に書けるとか)あとlegend-switchesを使うと凡例が出てくると同時に、凡例をクリックすると、該当の曲線の表示・非表示を切り替えられるようになるっぽいです。

seqとか

radian表現の中ではseqなどradianが用意してくれた関数があります。 seq(-1, 2, 10)だと-1から2まで10分割みたいな意味ですね。 PI等が使えるのはjavascriptのmathライブラリ由来のようです。 通常のjavascriptの関数以外にはd3の関数(min, max, extent, sum, mean, median, quantile, zip)や、 seq, sdev, unique, minBy, maxBy, sumBy, meanBy, sdevBy, normal, lognormal, gamma, invgammaなどがあるらしい。詳しくはこちら

正規分布のみならずガンマ分布もかけるという充実ぶり。

感想

今回はlinesだけでしたがpointsでスキャッター、barで棒グラフもかけるようです。 コンターがまだ無いのが残念ですが、Roadmapで予定されていることがわかるので、いつか対応すると信じてます。 チュートリアルはこの後csvやjsonデータの読み込みをやってくので今度見てみようかなと思います。

Radianの感想としてはやっぱりangularのカスタムhtmlタグの効果が大きいなーと感じました。htmlから出ずにグラフを書けるというところはとても有り難いです。javascriptでも問題ないのですが、ドキュメントとしてグラフを作りたいときはやっぱりhtmlで記述したいという欲求を素晴らしく満たしてくれている気がします。今後流行っていくといいな。