Ruby
JavaScript
Rails
d3.js

JavaScript初心者が、D3.jsをRailsで簡単に使ってみたい

More than 3 years have passed since last update.

0.前提

種類 内容
OS Mac OS X 10.9.4
Ruby 2.1.1
Rails 4.1.2

今回、自分のサービスを作る際にグラフなど視覚的に見せたいものがあり、これらを全てD3.jsで描画することにしました。
なぜD3.jsなのかという話なのですが、まずimgは嫌だったのでjsなどで書きたいのと、リファレンスや書籍などの豊富さから選択しました。
初心者でもできる簡単なものを参考程度にメモっておきました。

途中書きなので、また時間があるときにグラフの書き方などは追加する。

1.動かすまで

まずは、D3.jsの本体をダウンロードします。

$ wget http://d3js.org/d3.v3.min.js

では、次にRailsにセットアップします。

railsのプロジェクトsampleを作成して起動確認します

$ rails new sample -T
$ rails s -p 3001
$ rails g controller welcome index

d3.jsをrailsにコピーします

$ cp ~(先ほどwgetした場所) sample/vendor/assets/javascripts
sample/app/assets/javascripts/application.js
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require d3.v3.min
//= require_tree .

svgを使って球体を出現させてみましょう

app/views/welcome/index.html.erb
<script type="text/javascript">
  var dataset = [3,6,9,12,15];

  var svg = d3.select("body").append("svg");

  var circle = svg.selectAll("circle").data(dataset).enter().append("circle");
  circle.attr("cx", function(d, i) {
    return (i * 50) + 25;
  }).attr("cy", 25)
  .attr("r", function(d) {
    return d;
  }).attr("fill", "green").attr("stroke", "yellow")
  .attr("stroke-width", function(d) {
    return d / 2;
  });

</script>

bodyをセレクタで探してsvgを追加してます。
circleというのは、球体のことです。こいつにdatasetをあげてます。
あとは、この球体にcx, cy, y要素を追加して、fill, strokeなどで配色などを追加してます。


welcome_controller.rb
def show
  @value1 = "test"
  @value2 = "sample"
  @value3 = "ok"
end

# views側
var dataset = [<%= @value1 %>, <%= @value2 %>, <%= @value3 %>]

作法的に正しいのかまだ調査ができてませんが、controllers側から持って来たデータも先ほどのdatasetに突っ込めば出力はできます。

開発の流れ

railsの場合は、上記の設定でapplication.html.erbには既にD3.jsが読み込まれているので、welcome/index.html.erbなどの新しく作ったcontrollerのviewsのbody部分にscriptタグを追加していく形となります。

2.scale

scale

domainをrangeにマップするものです

何を言っているかよくわからないと思います
要は、domainというのが入力値を表しています。例えば、家計簿でグラフを作る際に、100〜1000円/日の費用がかかったとします。
その際のdomainは100 〜 1000ということになります。
一方rangeというのは出力値を表しています。先の例で言えば、10 〜 100の範囲で見せたいということもあるでしょう。

グラフの見せ方の話ですが、今日800円の費用がかかったとして、それをdomainとして入力すると、rangeはそれを80として出力します。イメージはそんなようなところです。

app/views/welcome/index.html.erb
<script type="text/javascript">
  var w = 500;
  var h = 300;
  var svg = d3.select("body").append("svg").attr("width", w).attr("height", h);
  var scale = d3.scale.linear().domain([100, 1000]).range([10, 100]);
</script>

デベロッパーコンソールで確認してみましょう。

> scale(300)
<- 30
> scale(215)
<- 21.5

入力値に対して、出力値がこれではっきり出たと思います。

メモリ

app/views/welcome/index.html.erb
<script type="text/javascript">

  // 省略

  svg.append("g").call(d3.svg.axis().scale(scale));
</script>

axis()でメモリを出せます。scaleでどのスケールと作用するのか決めます。gは要素の構成に対する一貫性を表していますので、必須ではないです。

続く

X.参考資料

とはいえ、JS初心者なので、書き方などもJSの方からも参考にしました。

書籍

JavaScript: The Good Parts
JavaScriptパターン

Web

Bootstrap
D3.js API reference