DataTablesの活用 ‐ 機能的なテーブルの作成

これまでにも何度か JavaScript ライブラリーの活用に関する記事を投稿してきましたが、今回は jQuery のプラグインである DataTables を使って、機能的なテーブルを作成しようと思います。

### 1. 事前準備
#### 1-1. ライブラリーの配置
DataTables を活用するためには、Yellowfin がアクセスできる場所にライブラリーを配置する必要があります。[DataTables](https://datatables.net) にアクセスして、[Download] と進みます。Download ページでは「Step 1. Choose a styling framework」と「Step 2. Select packages」でそれぞれ DataTables を選択し、「Step 3. Pick a download method」でライブラリーの入手方法を選択します。インターネットに接続できる環境であれば CDN を参照しても構いません。以下の手順では、ファイルをダウンロードして、サーバー上に保管する手順で説明します。

ダウンロードしたファイルの中から、datatables.min.css と datatables.min.js を Yellowfin サーバーの以下ディレクトリに配置します。これで、Yellowfin がライブラリーを参照できるようになります。
`(Yellowfin)/appserver/webapps/ROOT/js/chartingLibraries/datatables/`

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

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

レポートを新規で作成し、Ski Team ビューを選択します。

[グラフ] ステップで、軸に [Invoiced Date] と [Athlete Region]、集計値に [Invoiced Amount] と [Invoice Estimate] と [Profit Margin] をそれぞれ選択します。ここで選ぶ項目は特に後続の手順に影響するものではないので、どの項目を選んでいただいても大丈夫です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/5831663d-349f-8bda-2d0c-454c632a7e68.png)

### 3. グラフの作成
[グラフ] ステップに進み、画面右側 [グラフの選択] から [JavaScriptグラフ] を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/f071f314-a290-ec4c-ac3f-2ef0be45d374.png)

##### JavaScript タブ
雛形を全て削除し、以下のコードに置き換えます。コードの処理の内容は後ほど説明します。

```javascript:JS
generateChart = function(options) {
   var $chartDrawDiv = $(options.divSelector);
   var height = options.dataset.chart_information.height;
   var width = options.dataset.chart_information.width;
   var processedData = processData(options.dataset.data);
   doDrawing(processedData, $chartDrawDiv, height, width, options.errorCallback);
},

processData = function(dataset) {
    data=[]
    for (i=0;i<dataset['invoiced_amount'].length;i++){
       data.push([dataset['invoiced_date'][i].formatted_data,
        dataset['athlete_region'][i].formatted_data,
        dataset['invoiced_amount'][i].formatted_data,
        dataset['invoice_estimate'][i].formatted_data,
        dataset['profit_margin'][i].formatted_data])
        
    }
    return data
},

doDrawing = function(data, $chartDiv, height, width, errorFunction) {
   require(['https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js'], function() {
    $chartDiv.append('<table id="skiteam" class="display" width="100%"></table>');
    $("#skiteam").DataTable( {
        data: data,
        columns: [
            { title: "日付" },
            { title: "地域" },
            { title: "実績" },
            { title: "予算" },
            { title: "利益" }
        ],
        order: [[ 0, "asc" ]],
        "bSortClasses": false,
        columnDefs: [
            {
                targets: -1,
                className: 'dt-body-right'
            }
        ],
        language: {
        	"sProcessing":   "処理中...",
        	"sLengthMenu":   "_MENU_ 件表示",
        	"sZeroRecords":  "データはありません。",
        	"sInfo":         " _TOTAL_ 件中 _START_ から _END_ まで表示",
        	"sInfoEmpty":    " 0 件中 0 から 0 まで表示",
        	"sInfoFiltered": "（全 _MAX_ 件より抽出）",
        	"sInfoPostFix":  "",
        	"sSearch":       "検索:",
        	"sUrl":          "",
        	"oPaginate": {
        		"sFirst":    "先頭",
        		"sPrevious": "前",
        		"sNext":     "次",
        		"sLast":     "最終"
        	}
        }
    });
   });
}
```

##### CSSタブ
datatables.min.css の内容を全てコピーして貼り付けます。
なお、css ファイルの中身は改行もインデントも施されていないので、見やすくするためには、コードの整形を行うサイトなどを利用すると便利です。私は下記のサイトを利用しました。
https://lab.syncer.jp/Tool/CSS-PrettyPrint/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/10d1c816-f630-b5e8-ab6c-809191e3bd15.png)

[プレビュー] に移り、どのようなチャートが作成されるか見てみます。検索窓で文字列検索ができたり、表示件数を調整できたりと、それなりに使いやすいテーブルが出来上がりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/055f801b-8c95-0cb6-ab57-fac031aedd89.png)

#### 4. コードの説明
ここでコードの説明に移ります。
##### generateChart
JavaScript グラフの中で最初に呼び出されるのが `generateChart` です。この中で、チャートを描画する div を選択し、高さや幅に関する変数を扱います。また、データ処理を行う `processedData` 関数と 描画を行う `doDrawing` 関数を呼び出します。

```JavaScript:generateChart
generateChart = function(options) {
   var $chartDrawDiv = $(options.divSelector);
   var height = options.dataset.chart_information.height;
   var width = options.dataset.chart_information.width;
   var processedData = processData(options.dataset.data);
   doDrawing(processedData, $chartDrawDiv, height, width, options.errorCallback);
},
```
##### processedData
`processedData` 関数の for 文の中で Yellowfin のデータセットを配列にして data に格納しています。

```JavaScript:processedData
processData = function(dataset) {
    data=[]
    for (i=0;i<dataset['invoiced_amount'].length;i++){
       data.push([dataset['invoiced_date'][i].formatted_data,
        dataset['athlete_region'][i].formatted_data,
        dataset['invoiced_amount'][i].formatted_data,
        dataset['invoice_estimate'][i].formatted_data,
        dataset['profit_margin'][i].formatted_data])
        
    }
    return data
},
```
##### doDrawing
`Require` の中で、datatables.min.js ライブラリーの場所を指定します。今回であれば、『1.1 ライブラリーの配置』 手順で plotly-2.8.3.min.js を保管したディレクトリを相対パスで指定します。インターネットにつながる環境であれば、CDN の URL を指定することも可能です。
`$chartDiv.append('<table id="skiteam" class="display" width="100%"></table>')` でテーブルを描画するための HTML タグを指定し、ここで指定した id を下の行 `$("#skiteam").DataTable` で呼び出し、テーブルに data の中身を展開します。
`columns:` の中で、テーブルヘッダーの名称を指定します。
`order: [[ 0, "asc" ]],` で既定の並びを１列目の昇順としています。ソート列は複数指定も可能です。詳細は[こちら](https://datatables.net/examples/basic_init/table_sorting.html)でご確認ください。
`language:` の中で、画面上の表記を日本語化しています。なお、[インターネット上の JSON ファイル](https://datatables.net/plug-ins/i18n/Japanese)を直接指定することも可能です。
その他にも、様々なオプションの指定が可能です。詳しくは、DataTables のサイトでご確認ください。

```JavaScript:doDrawing
doDrawing = function(data, $chartDiv, height, width, errorFunction) {
   require(['https://cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js'], function() {
    $chartDiv.append('<table id="skiteam" class="display" width="100%"></table>');
    $("#skiteam").DataTable( {
        data: data,
        columns: [
            { title: "日付" },
            { title: "地域" },
            { title: "実績" },
            { title: "予算" },
            { title: "利益" }
        ],
        order: [[ 0, "asc" ]],
        "bSortClasses": false,
        columnDefs: [
            {
                targets: -1,
                className: 'dt-body-right'
            }
        ],
        language: {
        	"sProcessing":   "処理中...",
        	"sLengthMenu":   "_MENU_ 件表示",
        	"sZeroRecords":  "データはありません。",
        	"sInfo":         " _TOTAL_ 件中 _START_ から _END_ まで表示",
        	"sInfoEmpty":    " 0 件中 0 から 0 まで表示",
        	"sInfoFiltered": "（全 _MAX_ 件より抽出）",
        	"sInfoPostFix":  "",
        	"sSearch":       "検索:",
        	"sUrl":          "",
        	"oPaginate": {
        		"sFirst":    "先頭",
        		"sPrevious": "前",
        		"sNext":     "次",
        		"sLast":     "最終"
        	}
        }
    });
   });
}
```

##### CSS の修正
既定の CSS を直接修正することでもデザインの変更は可能ですが、手っ取り早いのはデザイン行を追加して、既定の設定をオーバーライドすることです。CSS タブの最終行に、以下の行を追加します。

```css:CSS
table th, td {
    border: 1px solid #8fbc8f;
}
#skiteam thead tr{
    background-color:   #8fbc8f;
    color:              #ffffff;
}
#skiteam tbody tr.odd{
    background-color: #eeeeee;
}
#skiteam tbody tr.even{
    background-color: #c3f0dd;
}

td:nth-of-type(3) {text-align:right}
td:nth-of-type(4) {text-align:right}
td:nth-of-type(5) {text-align:right}
```
ついでに、JavaScript タブの `$("#skiteam").DataTable({})` の中に `"bSortClasses": false,` を１行追加します。

```javascript:JS
$("#skiteam").DataTable( {
    "bSortClasses": false,
```
背景色や罫線の色を変更し、数値セルを右寄せすることで、以下のようなデザインに変更しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/db33c59b-a504-82ee-d2f0-11969172f2f4.png)


棒グラフや散布図などを使ってデータを可視化することで、分析はとても効率よくなります。
一方で、テーブルチャートが最も多くのデータをまとめて確認することができるため、現場ではテーブルが多用されることも事実です。
是非、DataTable などのライブラリと Yellowfin を併用し、分析に適したテーブルを作成してみてください。

For your awesome data analytical experience with Yellowfin! Cheers!