Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
20
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

Organization

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

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
20
Help us understand the problem. What are the problem?