この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
2は多分ある。
ナポリタンの食品サンプルがデスクに増えました。
発端
「Railsでデータベース使って色々やってるんだから、それ使って簡単なグラフとか見れたら面白そうだな…..。Railsでグラフを表示する用のgem、探してみよう」
「今回はchart-js-railsを使ってみることにしよう。有名どころでも使われているみたいだし、このgem自体はjavascriptのライブラリのchart.jsをRailsで使う為に引っ張って来てるだけのものみたいだし」
使用方法
「Gemfileに一行付け足して、bundle installして、使う為には、application.jsに
//= require Chart.min
を書き込む、と。
それだけで、他にコマンドとかを打つ必要は全く無し。
さて、まずは適当に新しいページ作ってchart.jsのサンプルページとか見ながら試してみるか……。
新しくそれ用のコントローラ作ってroute.rbにルーティング付け加えて、それからviewを作成して」
Controller
graph_viewers_controller.rb
class GraphViewersController < ApplicationController
def sample
end
end
View
sample.html.erb
<canvas id="myChart" width="900" height="400"></canvas>
<script>
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [1,2,3,4,5],
datasets: [{
label: "サンプル",
data: [1,2,3,4,5],
backgroundColor: 'rgba(255, 99, 132, 1.0)',
borderColor: 'rgba(255, 50, 132, 1.0)',
fill: false
}]
},
options: {
title: {
display: true,
text: "タイトル"
}
}
});
</script>
「お、出来た。
で、これにデータやラベルを変数として組み込むには、配列部分を弄れば良さそうだな」
Controller
def sample
pivotes = PiVote.pluck(:name, :vote_num)
@labels = pivotes.map(&:first)
@datas = pivotes.map(&:second)
#@labels = ["◯っ◯◯","π","パイナップル", "ニシンパイ", "パイルドライバー"]
#@datas = [9999, 3141, 2, 8, 1000]
end
View
「ラベルとデータ部分をそれぞれ弄って、と」
data: {
//文字列の入った配列やハッシュ等はこうしないと正しく表示されない
labels: <%= @labels.to_json.html_safe %>,
datasets: [{
label: "投票数",
data: <%= @datas %>,
backgroundColor: 'rgba(255, 99, 132, 1.0)',
borderColor: 'rgba(255, 50, 132, 1.0)',
fill: false
}]
},
「おお、でけたでけた。
一つ二つでも弄れば円グラフとか散布図とかも色々作れそうだし、オプション設定も色々あるし、夢が広がるぅ」
実際の使用感覚
まあ、そんな感じで使ってみました。実際にデータが視覚化されると、特徴とかが分かりやすくなりますし、そこからプロジェクト等に対する改善策も見やすくなってくると思います。
このchart-js-railsは実際、chart.jsをRailsで使えるようにしただけのgemみたいなものですが、Javascriptを余り深く知らない自分にとっては、Javascriptの勉強にもなって中々面白い所もあります。
今もそれに関して主に弄っていて、グラフの色分けや、散布図の点をクリックしたらそのデータに関する画面に遷移したりとか、実際色んな事が出来るようになってきて、実際夢が広がるぅ、感じです。
でも、一つ、難点として挙げるのならば、データベースから取ってきた値などを、javascriptにrubyとして組み込んでいくので、コードがとても汚くなりがちです。
散布図を色分けやらしたい、なんて考えた時は、データを与える辺りのコードが以下のようになってしまいました。
datasets: [
<% @labels.each_with_index do |label, i| %>
{
label: "<%= label.html_safe %>",
//色の設定。数に応じて変化。
borderColor: "<%= "##{(16 * i / @labels.length).to_s(16)}f#{(16 * (@labels.length - (i + 1)) / @labels.length).to_s(16)}fff"%>",
backgroundColor: "<%= "##{(16 * i / @labels.length).to_s(16)}5#{(16 * (@labels.length - (i + 1)) / @labels.length).to_s(16)}5ff"%>",
pointRadius: <%= 4 + i %>,
pointStyle: "<%= ['circle', 'triangle', 'rect', 'star', 'cross'][i].html_safe%>",
showLine: false,
data: [
//データの配列。データの一つはx,y座標を格納した配列。
<% @datas_array[i].each do |data| %>
{
x: <%= data[0] %>,
y: <%= data[1] %>
},
<% end %>
]
},
<% end %>
]
まあ、もっと良いやり方はあると思うので、もっと色々試してみようとは思いますが。