【Ruby on Rails】Chartkickの散布図でプロットに名前を表示させる

#1.Chartkickとは？

chart.jsというJavaScriptライブラリをラッピングしてくれるgemです。
折線、円、縦棒、横棒、面、散布図、ジオチャート(地図グラフ)、
タイムライン、複数系列といった多様なグラフを作成することができます。
それぞれのイメージについては[chartkick公式ページ](https://chartkick.com/)(英語)を参照ください。
その中でも本記事では散布図(scatter_chart)の作成とプロットに名前を表示させる方法について説明します。
初投稿のため至らない点が多々あるかと思いますがお付き合いください。

#2.始め方
公式に則ってRails5での始め方について説明します。
※Rails6についても公式に載っています。
・Gemfileにchartkickを追加

```ruby:Gemfile
gem 'chartkick'
```
・bundle installを実行
・application.jsに下記を追加

```ruby:application.js
//= require chartkick
//= require Chart.bundle
```
以上でChartkickを使い始めることができます。

#3.基本的な散布図の作成方法
例として名前と数学・物理の点数を持っているTestモデルがあるとします。

```ruby:tests.rb
class CreateTests < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
      
      t.string :name
      t.integer :math   
      t.integer :physics
      
      t.timestamps
    end
  end
end
```

Testsモデルには下記のようなデータが入っているとして、
数学の点数をX軸、物理の点数をY軸にとったグラフを作成してみます。

|名前(:name) |数学(:math) |物理(:physics) |
|:---:|:---:|:---:|
|A太郎|65|74|
|B太郎|61|84|
|C太郎|92|87|
|D太郎|71|63|
|E太郎|60|61|
|F太郎|59|59|
|G太郎|78|69|

[公式](https://chartkick.com/)を参考にControllerにてpluckメソッドで、mathとphysicsをカラムを取得します。
※Pluckメソッド：指定したカラムをモデルから全て取り出して、二次元配列で返すメソッド(詳しくは他の記事を参考にしてください。)
記述方法、実行結果は下記の様になります。

```ruby:test_controller.rb
@result = Test.pluck(:math, :physics)
"pluckメソッドで取り出した結果は下記の様になります。"
[[65, 74], [61, 84], [92, 87], [71, 63], [60, 61], [59, 59], [78, 69]]
```
それをViewにて下記のように記述します。

```ruby:test.html.erb
<%= scatter_chart @result, xtitle: "数学", ytitle: "物理" %>
```
結果は下図のようになり、
マウスオーバーするとプロットのデータが(数学の点数, 物理の点数)という形式で表示されます。
![chartkick_test.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552271/13de82c1-2885-044c-9f0d-98b4d865e6d1.png)

二つのデータ間の相関関係を調べる目的であればこれで十分です。
しかし、これでは誰がどのプロットなのかを知りたい場合は非常に不便です。
対応方法として下記の様にpluckメソッドの引数へ:nameも渡してあげれば済むと思いますが...

```ruby:test_controller.rb
@result = Test.pluck(:name, :math, :physics)
```
これを実行しても何も表示されなくなります。
![chartkick_test2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552271/ac498880-f2a0-a6d7-9780-5e60129a73ff.png)

名前を表示させるためには単純にpluckメソッドで取り出すだけでなく、適切に整形してあげる必要があります。
これについては次の章で記述します。

#4.取得したデータの整形
この整形方法が本記事の本題です。
3.で記述した様に、pluckメソッドで取得したデータを整形します。
下記の様な形式に落とし込むのが目標です。

```ruby:test_controller.rb
@result = [{:name=>"名前", :data=>[["数学の点数", "物理の点数"]]}...]
```
そのためのコードが下記に様になります。

```ruby:test_controller.rb
data = Test.pluck(:name, :math, :physics)

@result = []
data.each do |da|
 @result.push({name: da[0], data: [[da[1], da[2]]]})
end
```
コードの概要は、
・pluckメソッドで配列データを取得
・グラフへ表示する用の空配列を用意
・pluckメソッドで取得した配列データをeach doで回す
・空配列へnameとdataをキーに持たせてpush
　・dataキーには二次元配列の形式でvalueにx軸(:math)とy軸(:physics)の値を持たせる
となっています。

これを実行すると下図の様になります。
![graph3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552271/6d32142c-f700-e6ad-ee6e-cd63ebf373c4.png)
見事にマウスオーバーすると名前が表示され、誰が数学と物理を何点取ったかを把握できるようになりました。

この様にするとlegend(凡例)が出てくるようになります。
プロットが少ない内は良いですが、数が増えてくると邪魔になるかも知れません。
その場合にはlegendオプションで消すことができます。

```ruby:test.html.erb
<%= scatter_chart @result, xtitle: "数学", ytitle: "物理", legend: false %>
```
![graph4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552271/4fa2f218-4ab9-8f6e-fea0-0f9b2c82bdfa.png)

#5.まとめ
本記事では、Chartkickによる基本的な散布図の作成方法から名前を表示させる方法について説明しました。
二つのデータ間の相関関係を調べる目的であれば、公式に載っているようにpluckメソッドでモデルからx軸とy軸のデータを取り出すだけでグラフを描画できます。
ここに名前など特定できるよなデータを表示したい場合は、[{:name=>名前, :data=>[["x", "y"]]}...]という形式に整形する必要があります。

突然出てきた'name'や'data'については、Multiple Series(複数の系列)の章に存在が確認されます。
ただ、散布図での具体的な記述方法に記載がなく、記事も見当たらず四苦八苦したので記事にしました。
この記事が少しでも皆さんのお役に立てば幸いです。
誤字脱字、より良いコードや表現などありましたらご指摘ください。

以上、最後まで読んでいただきありがとうございました。