YellowfinでHighchartsのワードクラウドを描画する

# はじめに

### 概要
BIツールであるYellowfinは、JavaScriptライブラリを利用することで標準機能以外の様々なグラフや図を表現することが可能です。
今回はHighchartsを利用し、ワードクラウドを描画してみます。

### ワードクラウドとは
各文字列に紐づけられた数値の重みに応じて文字の大小を表現した図です。
例えば、「文章を単語レベルに分解した上で出現頻度を重み付けし、出現頻度が高い単語を大きく表示する」ケース等で利用されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2767545/09e5d0c0-5b43-9d53-a7b7-a0a236e990a5.png" width=450 /> 

https://www.highcharts.com/demo/wordcloud

### バージョン情報
Yellowfin：9.7.0.3
Highcharts：10.2.0

# 事前準備

### 1. YellowfinのJavaScriptグラフ機能を有効化
下記ページの手順を参考に、YellowfinのJavaScriptグラフ機能を有効化します。

https://wiki.yellowfin.co.jp/pages/viewpage.action?pageId=2293926

### 2. ライブラリのインストールと配置
1. npmでHighchartsのパッケージをインストールします。
`npm install --save highcharts`

2. Yellowfinサーバーの下記ディレクトリ配下にインストールしたパッケージを配置します。
`{Yellowfinインストールディレクトリ}/appserver/webapps/ROOT/js/chartingLibraries/highcharts`


:::note info
下記両条件を満たす場合、本手順は省略可能です。
・Yellowfinサーバーがインターネットにアクセス可能
・CDNでライブラリを参照する
:::

# レポートの作成

### 1. ビュー選択
新規レポートの作成時、デフォルトで選択可能なサンプルビューの「Ski Team」を選択します。
<img width="450" alt="ビュー選択.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2767545/c37125b6-3e90-29e4-6b5c-93a7baa1b943.png">

### 2. カラム設定
「Camp Name」および「Cost of Camp」をカラムとして設定します。
<img width="450" alt="カラム選択.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2767545/a6512047-279e-f792-507c-386b95ac81c3.png">

### 3. グラフ画面へ遷移
画面上部メニューの「グラフ」（①）、画面右のJSボタン（②）、「グラフの選択」領域内の「JS」（③）を順に選択し、JavaScriptタブ画面を表示させます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2767545/4626bf5a-67c6-b317-ca9c-5ba14edafd5c.png" width=450 /> 

### 4. グラフの設定
「JavaScript」タブにデフォルトで入力されているテンプレートを全て削除し、下記コードに置き換えます（コードの処理内容の詳細については後述）。
「CSS」タブについては、Highcharts公式のWordCloudサンプルのCSSと同様に設定します。

https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/demo/wordcloud

```javascript:wordcloud_skiTeam.js
//generateChart は必須の関数であり、Javascriptグラフの作成において呼び出しされます
generateChart = function (options) {

    // グラフを描画する部分です
    var $chartDrawDiv = $(options.divSelector);

    // 必要に応じて、RAWデータJSONをグラフに必要な形式に変換します。
    var processedData = processData(options.dataset.data);

    // グラフの実績の描画を $chartDrawDiv に行います。
    doDrawing(processedData, $chartDrawDiv);
    
},

    processData = function (dataset) {

        var processedData = [];
        var arrlength = dataset.cost_of_camp.length;

        for (let i = 0; i < arrlength; i++) {
            // 各カラムの生データを行ごとに連想配列に格納
            var obj = {
                name: dataset.camp_name[i].raw_data,
                weight: dataset.cost_of_camp[i].raw_data
            };
            processedData.push(obj);
        }

        return processedData;
    },

    doDrawing = function (data, $chartDiv) {

        // Tell RequireJS how and where to search for the highcharts package
        require.config({
            packages: [{
                name: 'highcharts',
                main: 'highcharts'
            }],
            paths: {
                'highcharts': 'js/chartingLibraries/highcharts'
            }
        });
        require([
            'highcharts',
            'highcharts/modules/wordcloud',
            'highcharts/modules/exporting',
            'highcharts/modules/export-data',
            'highcharts/modules/accessibility'
            ], function (Highcharts) {
            Highcharts.chart($chartDiv[0].id, {
                accessibility: {
                    screenReaderSection: {
                        beforeChartFormat: '<h5>{chartTitle}</h5>' +
                            '<div>{chartSubtitle}</div>' +
                            '<div>{chartLongdesc}</div>' +
                            '<div>{viewTableButton}</div>'
                    }
                },
                series: [{
                    type: 'wordcloud',
                    data,
                    name: 'Occurrences'
                }],
                title: {
                    text: 'Total Cost by Camp Location'
                },
                subtitle: {
                    text: 'Ski Team Cost'
                },
                tooltip: {
                    headerFormat: '<span style="font-size: 16px"><b>{point.key}</b></span><br>'
                }
            });
        });
    };
```

### 5. グラフ描画結果
各種設定後、プレビュー画面にてワードクラウドが表示されることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2767545/efc468c5-8c54-7537-d097-b8dbd3fda2d8.png)


### 6. コードの説明

#### generateChart
コメント記載の通り、メインの処理を行う関数です。下記3点の処理を行っています。
①グラフの描画箇所の設定
②データ加工関数の呼び出し
③グラフ描画の実行

```javascript:generateChart 
//generateChart は必須の関数であり、Javascriptグラフの作成において呼び出しされます
generateChart = function (options) {

    // グラフを描画する部分です
    var $chartDrawDiv = $(options.divSelector);

    // 必要に応じて、RAWデータJSONをグラフに必要な形式に変換します。
    var processedData = processData(options.dataset.data);

    // グラフの実績の描画を $chartDrawDiv に行います。
    doDrawing(processedData, $chartDrawDiv);
    
},
```


#### processData
表データを加工する関数です。
サンプルコードに倣い、`name`に項目名、`weight`に数値を格納した連想配列を作成します。

https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/demo/wordcloud
```javascript:processData 
    processData = function (dataset) {

        var processedData = [];
        var arrlength = dataset.cost_of_camp.length;

        for (let i = 0; i < arrlength; i++) {
            // 各カラムの生データを行ごとに連想配列に格納
            var obj = {
                name: dataset.camp_name[i].raw_data,
                weight: dataset.cost_of_camp[i].raw_data
            };
            processedData.push(obj);
        }

        return processedData;
    },
```


#### doDrawing
グラフ描画を行う関数です。
例によってサンプルコードに倣い、`require`で必要なjsファイルを参照し、適切な`tltle`と`subtitle`を設定します。

https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/demo/wordcloud
```javascript:doDrawing 
 doDrawing = function (data, $chartDiv) {

        // Tell RequireJS how and where to search for the highcharts package
        require.config({
            packages: [{
                name: 'highcharts',
                main: 'highcharts'
            }],
            paths: {
                'highcharts': 'js/chartingLibraries/highcharts'
            }
        });
        require([
            'highcharts',
            'highcharts/modules/wordcloud',
            'highcharts/modules/exporting',
            'highcharts/modules/export-data',
            'highcharts/modules/accessibility'
            ], function (Highcharts) {
            Highcharts.chart($chartDiv[0].id, {
                accessibility: {
                    screenReaderSection: {
                        beforeChartFormat: '<h5>{chartTitle}</h5>' +
                            '<div>{chartSubtitle}</div>' +
                            '<div>{chartLongdesc}</div>' +
                            '<div>{viewTableButton}</div>'
                    }
                },
                series: [{
                    type: 'wordcloud',
                    data,
                    name: 'Occurrences'
                }],
                title: {
                    text: 'Total Cost by Camp Location'
                },
                subtitle: {
                    text: 'Ski Team Cost'
                },
                tooltip: {
                    headerFormat: '<span style="font-size: 16px"><b>{point.key}</b></span><br>'
                }
            });
        });
    };
```

## まとめ
今回はワードクラウドを描画しましたが、Highchartsのその他様々な種類のグラフも（グラフごとのサンプルを参考に）ほぼ同様の手順で描画できるかと思います。
また、他のJavaScriptライブラリを使用する場合でも、`require`でのjsファイルの参照の仕方などが参考になれば幸いです。

## 参考記事
https://qiita.com/ExtremeCarvFJ/items/df29cc5870e02d4ef733

https://qiita.com/celery/items/858de1f0eeb579b1f4a0