[Rails]C3.js × gonでチャートを表示する

できるだけ簡単に、かつクオリティの高いチャートを表示したい・・・。
そんなあなたにはC3.jsがオススメです。
また、データベースやコントローラーにあるデータを表示したい場合はgem `gon`を使うと便利です。

今回は、C3.jsとgonを使った以下のような棒グラフの描画方法を紹介します。
<img width="901" alt="スクリーンショット 2019-07-19 14.34.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400652/68659104-ed07-d07a-04b1-29e2877474da.png">

## 環境

### バージョン
```terminal
$ ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin18]
$ rails -v
Rails 5.2.3
```

### 導入gem
`gon`を導入します。

```ruby
gem 'gon'
gem 'haml-rails'
```
ビューにはhamlを採用しています。

### ライブラリとgonの読み込み

C3.jsはD3.jsのラッパーライブラリーなのでC3.jsと一緒にD3.jsを読み込みます。
今回はCDNを使って読み込むことにしました。（もちろん、gemとして読み込むこともできます。[RailsでC3.jsを使う](https://qiita.com/komakomako/items/a2b393446eea7396b719)）
また、gonを適用するためにheadタグの中で以下のように追記します。

```ruby:application.html.haml
    # jsファイルよりも前に読み込む
    = Gon::Base.render_data
    %link{ href: "https://cdnjs.cloudflare.com/ajax/libs/c3/0.6.7/c3.css", rel: "stylesheet"}
    %script{src: "https://d3js.org/d3.v4.min.js", type: "text/javascript"}
    %script{src: "https://cdnjs.cloudflare.com/ajax/libs/c3/0.6.7/c3.js", type: "text/javascript"}
```

## ビュー
チャートを挿入したい要素にIDを指定しておきます。

```haml:html.haml
.container
  #bar
  / ここにチャートを挿入
```

## コントローラー
`gon.◯◯`という変数に値を代入することでjsファイルで呼び出すことができます。

```ruby:controller.rb
    gon.x = ["x","07/13","07/14","07/15","07/16","07/17","07/18","07/19"]
    gon.cash = ["現金",2000000,1000000,1000000,1000000,1000000,1000000,1000000]
    gon.crypto = ["仮想通貨",8000000,9000000,10000000,8000000,6000000,4000000,2000000]
```
わかりやすくするため値を直接代入していますが、
コントローラーでDBの情報を取得してjsに変数を渡したいときに利用すると便利です。

## jsファイル
同様に`gon.◯◯`とすることでコントローラで定義した変数を取り出すことができます。

```javascript
window.onload = function() {
// 棒グラフを挿入
  var barGraph = c3.generate({
    bindto: '#bar', // 挿入する要素のIDを指定（デフォルトは#chart）
    data: {
      x : 'x',
      columns: [
        // コントローラーで定義した変数の呼び出し
        gon.x, //x軸のメモリに表示する文字列
        gon.cash, // 値1
        gon.crypto, // 値2
      ],
      groups: [
          // 値1と値2を連結させた棒グラフを表示
          ['現金', '仮想通貨']
      ],
      type: 'bar' // チャートタイプを指定（今回は棒グラフ）
    },
    axis: {
      x: {
        type: 'category' // x軸のメモリ（今回は日付）を読み込むために必要
      },
      y: {
        label: {
          // y軸のラベルを追加
          text: '価格 / 円',
          position: 'outer-middle'
        },
        tick: {
          // 3桁ずつ「,」を挿入
          format: d3.format(",")
        }
      }
    },
    // チャートの余白を指定できる
    padding: {
      top: 10,
      bottom: 0
    }
  });
}
```
指定できるチャートタイプやその他設定は公式リファレンスがわかりやすいです。[C3.js](https://c3js.org/reference.html)

## gonの仕組み
application.html.hamlのheadタグの中で`Gon::Base.render_data`を記述した場所がどう表示されているかを確認してみます。

```html:html
<script>
  //<![CDATA[
  window.gon={};
  gon.x=["x","07/13","07/14","07/15","07/16","07/17","07/18","07/19"];
  gon.cash=["現金",2000000,1000000,1000000,1000000,1000000,1000000,1000000];
  gon.crypto=["仮想通貨",8000000,9000000,10000000,8000000,6000000,4000000,2000000];
  //]]>
</script>
```

`window.gon={}`とすることで`gon`というグローバル変数を定義し、空のオブジェクトを代入して初期化しています。(グローバル変数はwindowオブジェクトのプロパティです)
そして、コントローラーで指定した値を`gon`のプロパティとして代入しています(windowは省略可能)。
これにより、jsファイルで変数を読み込むことが可能になります。

## 参考
[C3.js](https://c3js.org/)
[gon](https://github.com/gazay/gon/blob/master/README.md)
[RailsでC3.jsを使う](https://qiita.com/komakomako/items/a2b393446eea7396b719)