Railsでレーダーチャート を書いてみる(DBから値を取得)

TECH::CAMPで勉強し始めてから13週間目。

TECH::CAMP生でいる期間も、そろそろ半分が過ぎようとしています。

 

今日は、今作っているアプリで一番こだわりたい部分を実装しましたので

それを記録します。

 

Railsアプリにレーダーチャート を導入する

 

  1. レーダーチャートとは?
  2.  gemをダウンロード
  3. 変数定義しましょ
  4. js書きましょ
  5. 大きさ変えてみましょ

 

レーダーチャート とは?

レーダーチャート とは、こんなやつです。

 

図形でバランスを見るやつです。2つのデータの比較なんかによく使われます。

私は現在食品会社で開発をしているので、

アンケートで取得した味の評価データをレーダーチャート にしてプレゼン資料に使ったりすることもあり、好きなグラフの一つです。(かっこいいしね。名前も見た目も)

 

今回は、

コーヒーの味の評価をユーザーが記事として登録するアプリですので、

味の評価を5段階でDBに登録し、そのデータをjavascript(Chart.js)に渡して

チャートにしていただきましょうというわけです。

 

gemをダウンロード

まず、Chart.jsのダウンロードから。gemファイルに

gem 'chart-js-rails'

と記載し、

$ bundle install します。(サーバー再起動忘れずに)

次に、application.jsのファイルに

//= require jquery
//= require Chart.min

を記載します。

これでjQueryとChart.jsが使えるようになりました。

 

 変数を定義しましょ

今回はDBの特定のカラムに入っている値を、

モデル→コントローラー→javascript→ビュー

といった順に渡してやる必要があります。

そこで、思いました。

カラムの値を変数でそのままjavascriptに渡しても、読んでくれないんじゃ・・・

 

案の定、そうでした。

jbuilderを使うなど色々試したのですが、なかなかいい方法が思い付かず、

今回はちょっと裏技的で不本意でしたが、

gon というgemを使うことにしました。

gem 'gon'

変な名前やな・・・

 

といってナメてごめんなさい。本当に素晴らしいgemです。

例えば今回渡したいデータは、postモデル内の

acidity」カラム・・・酸味

bitterness」カラム・・・苦味

sweetness」カラム・・・甘味

fragrance」カラム・・・香り

richness」カラム・・・コク

以上の5つだとすると、gonを使用して、下記のようにjavascriptに渡せる変数を作成することができます。

def show
@post = Post.find(params[:id])
gon.acidity = @post.acidity
gon.bitterness = @post.bitterness
gon.sweetness = @post.sweetness
gon.fragrance = @post.fragrance
gon.richiness = @post.richiness
end

 

gon.〇〇というのがjavascriptで使える変数名です。

なんと簡単・・

 

js書きましょ

次はjavascriptでの記述です。

先にソースコードを全部載せます。

$(document).on('turbolinks:load', function(){ //ページを読み込んだらjs発火
var acidity = gon.acidity; //gonを使った変数をjsで変数に代入
var bitterness = gon.bitterness;
var sweetness = gon.sweetness;
var fragrance = gon.fragrance;
var richiness = gon.richiness;
 
var ctx = document.getElementsByClassName("myChart"); //html内のcanvasタグ
(クラスがmyChart)
 
new Chart(ctx, {
type: 'radar', //レーダーチャートを指定
data: {
labels: ["酸味", "苦味", "甘味", "香り", "コク"], //5角形の頂点の名前
datasets: [{
label: '味のバランス', //レーダーチャートの表すもの
backgroundColor: "rgba(0,0,80,0.4)", //グラフの色
borderColor: "rgba(0,0,80,1)", //レーダーの線の色
data: [acidity,bitterness,sweetness,fragrance,richiness] //実際に引っ張るデータの変数
}],
},
options: {
scale: {
pointLabels: {
fontColor: "green" //5角形の頂点の名前の色
},
ticks: {
min: 0, //minimun(チャートの中心)
max: 5, //maximum (五角形の頂点)
stepSize: 1 //1目盛りの区切り
}
}
}
});
});
 
 

こんな感じでかくと、

HTMLの<canvas>タグに、立派なレーダーチャート が簡単に書けちゃいます!!

(クラス名をしっかり指定してやってくださいね)

 

data: [ ] というカッコ内に変数を配列で入れているところには、

数字を直接入れることもできますよ。(ネットで見るとそっちの例が多く出る)

 

そしてできたチャートはこんな感じ。

f:id:atsukofu:20200601221627p:plain

ふむふむ、香りと苦味が少なく、酸味とコク、甘みが少ない・・

焙煎が浅いタイプかしら?!

なんてことが可視化されて便利というわけです。

 

大きさ変えましょ

このチャートを作っている<canvas>タグですが、

そのままクラス名を指定して、大きさをCSSで調整しようとすると、

うまくいきませんでした。

調べてみると、どうやら親要素の大きさに依存するようですので、

divタグで囲ってCSSで大きさ指定してやると、うまくいくみたいです。

これを利用して、レスポンシブデザイン対応にしてみました。(初挑戦)

PC版

f:id:atsukofu:20200601222401p:plain

大きなブラウザ画面に対応。

 

iphoneX版

f:id:atsukofu:20200601222527p:plain小さな画面に対応してグラフの大きさを調整。

 

ちなみに星の数もDBから数値を取得しています。

投稿時に「全体評価」を1〜5の数値で選ばせ、postモデルのstarsカラムに登録。

<% post.stars.times do%>
<span class="top-index__post--stars">
<i class="fas fa-star"></i>
</span>
<% end %>

starsカラムの数字の回数、font-awesomeで取ってきたアイコンの表示を繰り返すだけです。

CSSで色をつけると、サマになりますね!!!

うーん、楽しい・・・!!!

 

 

実装したいUIから作りたいものを探すことが多いです。

今回もその一つです。

ただ、デザインの才能はあまりないので、

なんとなく配色がダサいですね〜

その辺りも色々勉強したいです。