Chart.js の活用(基礎編)

これまで小技ばかり扱ってきましたが、今回は少しコーディングの領域に入ってみたいと思います。第一弾はChart.js の活用(基礎編)です。初めて JavaScript チャートを作成する人におすすめの内容です。Chart.js の詳細に関しては Chart.js 公式サイト (https://www.chartjs.org/) をご確認ください。
Yellowfin では、Chart.js 以外にも D3 や jQuery など様々なライブラリーの活用が可能です。https://qiita.com/celery  でも類似の情報がたくさん扱われているので、是非アクセスしてみてください。

###1. 事前準備
####1-1. ライブラリーの配置
Chart.js を活用するためには、Yellowfin がアクセスできる場所にライブラリーを配置する必要があります。https://www.chartjs.org/ にアクセスして、[Getting started] > [Installation] と進み、js ファイルを取得します。
取得したファイルは、Yellowfin サーバー上の以下のディレクトリに配置します。これで、Yellowfin  がライブラリーを参照できるようになります。
```/appserver/webapps/ROOT/js/chartingLibraries/chartjs/```

####1-2. JavaScript グラフの有効化
JavaScript グラフを作成するためには、いくつか Yellowfin サーバーで事前設定が必要です。必要な設定内容に関しては、以下 Wiki 情報を参考にしてください。
https://wiki.yellowfin.co.jp/pages/viewpage.action?pageId=2293926

###2. グラフの作成
ライブラリーを配置し、JavaScript グラフを有効化したら、早速グラフの作成段階に進みます。以下の手順では、Yellowfin インストール時に規定でインストールされる Ski Team のデータとビューを利用します。

レポートを新規で作成し、Ski Team ビューを選択します。
[グラフ] ステップで、軸に [Camp Region]、集計値に [Camp Rating] をそれぞれ選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/3f92b59e-aa78-b35c-46d3-cedb81a7b7a9.png)

[グラフ] ステップに進み、画面右側 [グラフの選択] から [JavaScriptグラフ] を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/12d64e84-31f7-257b-cdf9-c2f9a3499245.png)

画面に JavaScript の雛形が表示されます。JavaScript グラフを作成する上で必要な関数は ```generateChart``` です。同関数の中に必要な処理を記載することで、グラフの作成が可能です。同関数に引き渡される ```options``` にデータ作成ステップで作成したデータが格納されます。
```options``` にどのようなデータが格納されるかは、後述の手順で確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/8cbdcc18-7e03-a290-86bd-2d93056aa9cf.png)

雛形を全て削除し、以下のコードに置き換えます。chart.js に Yellowfin のデータを受け渡して、レーダーチャートを作成するサンプルコードです。雛形の構造を残したまま、記載内容をシンプルにしています。

```javascript:JavaScript
generateChart = function(options) {
    console.log(JSON.stringify(options));
    options.blockRenderComplete();
    var $chartDrawDiv = $(options.divSelector);
    var processedData = processData(options.dataset.data);
      doDrawing(processedData, $chartDrawDiv, options.renderComplete);
},
processData = function(dataset) {
  var yfdata = {
      labels : [],
      datasets : [
          {
            label : '各地域の点数',
            data : [],
            backgroundColor : ['rgba(135,206,250,0.5)']
          }
        ]
  };
  
  for (var i = 0; i < dataset.camp_region.length; i++) {
      yfdata.labels.push(dataset.camp_region[i].formatted_data);
      yfdata.datasets[0].data.push(dataset.camp_rating[i].raw_data);
      yfdata.datasets[0].backgroundColor.push('rgba(135,206,250,0.5)');
  }
        
  return yfdata;
},
 
doDrawing = function(data, $chartDiv, height, width) {
    require(['js/chartingLibraries/chartjs/Chart.js'], function(chart) {
        var $canvas = $('<canvas height="500" width="500"></canvas>');
      
        $chartDiv.append($canvas);
      
        new Chart($canvas, {
            type: "radar",
            data: data,
            options : {
                responsive : false,
                label: {
                    display: false,
                },
                scale: {
                    ticks: {
                        beginAtZero: true,
                        max: 6,
                        min: 0,
                        stepSize: 1
    }
}
            }
        });
        renderComplete();
    });
}
```
早速どのようなグラフが出来上がるか見てみます。[プレビュー] に移ると、レーダーチャートが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/b0038fc4-64b1-75e7-2642-02388af800b3.png)

###3. コードの内容
####3-1. generateChart
[Javascript] 画面に戻り、コードの中身を確認します。

```Javascript:1-7行
generateChart = function(options) {
    console.log(JSON.stringify(options));
    options.blockRenderComplete();
    var $chartDrawDiv = $(options.divSelector);
    var processedData = processData(options.dataset.data);
      doDrawing(processedData, $chartDrawDiv, options.renderComplete);
},
```
先述の通り、1行目は必ず ```generateChart = function(options)``` で始まる必要があり、```options``` に [データ] ステップで作成したデータが格納されます。

```console.log(JSON.stringify(options));``` で、```options``` に格納されているデータの内容を、JSON 形式でコンソールにログ出力しています。
具体的にどのようなデータが出力されているかを見てみましょう。[プレビュー] 画面で [F12] ボタンを押下するか、ブラウザ右上の [Google Chrome の設定] > [その他のツール] > [デベロッパー ツール] の順に進み、デベロッパーツールを開きます。
画面下部で [情報] の内容を確認すると、[グラフ] ステップで集計した [Camp Region] 軸と [Camp Rating] 集計値が JSON 形式で出力されていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/06828538-017e-846b-266b-78f9b65c1741.png)

[Javascript] に画面に戻って、再びコードの内容を確認します。
3 行目の ```options.blockRenderComplete();```と 53 行目の ```renderComplete();``` で、レンダリング処理の開始と完了を明示する処理を定義しています。処理順序に依存関係が発生する場合などには定義しておくことをお勧めします。

4-6 行でデータ処理とグラフ描画の処理を行っています。4 行目でチャートを描画する div を選択した後、```processData``` と ```doDrawing``` を呼び出し、それぞれでデータ処理と描画処理を行っています。
呼出し先の関数での処理内容は以下で説明をします。

####3-2. データセット

```javascript:8-27行
processData = function(dataset) {
  var yfdata = {
      labels : [],
      datasets : [
          {
            label : '各地域の点数',
            data : [],
            backgroundColor : ['rgba(135,206,250,0.5)']
          }
        ]
  };
  
  for (var i = 0; i < dataset.camp_region.length; i++) {
      yfdata.labels.push(dataset.camp_region[i].formatted_data);
      yfdata.datasets[0].data.push(dataset.camp_rating[i].raw_data);
      yfdata.datasets[0].backgroundColor.push('rgba(135,206,250,0.5)');
  }
        
  return yfdata;
},
```
```processData``` では、データセットの処理に関わる記述をしています。前半でデータセットの属性を定義し、後半の ```for``` 文の中で、データセットに Yellowfin のデータを push しています。push しているデータの内容は、先の手順で確認したものです。軸 (camp_region) と 集計値 (camp_rating) を行数分取り込みます。

最後に、```return yfdata;``` で処理された結果のデータセットを受け取ります。

####3-3. グラフ描画
```javascript:29-55行
doDrawing = function(data, $chartDiv, height, width) {
    require(['js/chartingLibraries/chartjs/Chart.js'], function(chart) {
        var $canvas = $('<canvas height="500" width="500"></canvas>');
      
        $chartDiv.append($canvas);
      
        new Chart($canvas, {
            type: "radar",
            data: data,
            options : {
                responsive : false,
                label: {
                    display: false,
                },
                scale: {
                    ticks: {
                        beginAtZero: true,
                        max: 6,
                        min: 0,
                        stepSize: 1
    }
}
            }
        });
        renderComplete();
    });
}
```
次に、グラフの描画に関する定義個所です。
冒頭の ```Require``` の中で、Chart.js のライブラリーの場所を指定します。具体的には『1-1. ライブラリーの配置』 手順で Chart.js を保管したディレクトリを相対パスで指定します。
```require(['js/chartingLibraries/chartjs/Chart.js']```
ライブラリーがインターネット上にありアクセス可能な場合は、その URL を指定します。カンマで区切って、複数のライブラリーを指定することも可能です。

以下でグラフのサイズを固定し、代わりにレスポンシブデザインを無効化しています。
```var $canvas = $('<canvas height="500" width="500"></canvas>');```
```$chartDiv.append($canvas);```
```responsive : false,```

```type: "radar",``` はチャートの種類を定義しています。"bar" や "Pie" などに変更すれば、別の見せ方をすることも可能です。チャートによって必要な軸と集計値の数が異なることは十分に考慮してください。

```options :``` でスケールに関する定義などを行っています。他にも様々な定義が可能です。詳細は下記をご参照ください。
https://www.chartjs.org/docs/latest/samples/other-charts/radar.html

いかがだったでしょうか。今回は簡単なグラフ作成を行いましたが、もっと複雑で動きのあるグラフを作成することも可能です。
興味深いグラフを作成したら、またこちらの方に記事を投稿します。
それまで、See you then. Ciao!