マリメッコチャート第２弾 ちょっとだけ特殊な使い方：Yellowfin と FusionCharts の連携 

## 1. はじめに
[前回記事]( https://qiita.com/ExtremeCarvFJ/items/7f7fcc7b443e71a6d10d)で、FusionCharts と連携してマリメッコチャートを作成する方法をお伝えしました。マリメッコチャートと言えば、100% 積み上げの見た目が通常ですが、今回はちょっとだけ特殊な使い方を紹介したいと思います。

## 2. データの準備
[一般財団法人 自動車工業会]( https://www.jama.or.jp/)が公開している、[2020 年の二輪車仕向地別輸出台数]( https://www.jama.or.jp/statistics/facts/two_wheeled/index.html)を再集計したものを[こちら]( https://github.com/ChasingHH/ShareFiles/blob/Share/bike_export.csv)に共有しました。自分でも以下の手順でチャートを作成してみたい方は、是非ご活用ください。直接データベースに取り込む以外にも、[Yellowfin トランスフォーメーションフロー]( https://wiki.yellowfin.co.jp/pages/viewpage.action?pageId=2293853)を活用することも可能です。

## 3. ビューの作成
以下の情報を参考に[ビュー](https://wiki.yellowfin.co.jp/pages/viewpage.action?pageId=2294284)を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/b8aa64bd-d6b9-6418-0ab5-680d83520a00.png)

## 3. グラフの作成
準備が整ったら、グラフの作成に手順を進めます。新規でレポートを作成し、以下の手順に従ってグラフを作成します。

#### 3-1. [データ] ステップ
ビューに設定した軸と集計値を全てテーブルに配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/76bd242f-cfe6-b37b-4c21-f22d34ebe656.png)

#### 3-2. [グラフ] ステップ
[グラフ] ステップに進み、画面右側 [グラフの選択] から [JavaScriptグラフ] を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/4e51396e-62ea-9289-c6f4-dcd97ea82743.png)

##### JavaScriptタブ
雛形を全て削除し、以下のコードに置き換えます。コードの処理の内容は後ほど説明します。
```javascript:JS
generateChart = function(options) {
    var $chartDrawDiv = $(options.divSelector);
    var processedDataLabel = processDataLabel(options.dataset.data);
    var processedDataValue1 = processDataValue1(options.dataset.data);
    var processedDataValue2 = processDataValue2(options.dataset.data);
    var processedDataValue3 = processDataValue3(options.dataset.data);
    doDrawing(processedDataLabel, processedDataValue1, processedDataValue2, processedDataValue3, $chartDrawDiv);
},

processDataLabel = function(dataset) {
    var ds_label = [];
    var prev_label = "first";
    for (i=0;i<dataset.area.length;i++){
        if(dataset.area[i].raw_data !== prev_label){
            ds_label.push({
                label: dataset.area[i].raw_data,
            });
        }
        prev_label = dataset.area[i].raw_data;
    }
    return ds_label;
},

processDataValue1 = function(dataset) {
    var ds_value1 = [];
    for (j=0;j<dataset.size.length;j++){
        if(dataset.size[j].raw_data == "251cc以上"){
            ds_value1.push({
                value: dataset.num[j].raw_data,
            });
        }
    }
    return ds_value1;
},

processDataValue2 = function(dataset) {
    var ds_value2 = [];
    for (k=0;k<dataset.num.length;k++){
        if(dataset.size[k].raw_data == "126-250cc"){
            ds_value2.push({
                value: dataset.num[k].raw_data,
            });
        }
    }
    return ds_value2;
},

processDataValue3 = function(dataset) {
    var ds_value3 = [];
    for (l=0;l<dataset.num.length;l++){
        if(dataset.size[l].raw_data == "125cc以下"){
            ds_value3.push({
                value: dataset.num[l].raw_data,
            });
        }
    }
    return ds_value3;
},

doDrawing = function(ds_label, ds_value1, ds_value2, ds_value3, $chartDrawDiv) {
    console.log(JSON.stringify(ds_label));
    console.log(JSON.stringify(ds_value1));
    console.log(JSON.stringify(ds_value2));
    console.log(JSON.stringify(ds_value3));
    require(['js/chartingLibraries/fusioncharts-suite-xt/js/fusioncharts.js'], function(){
        const dataSource = {
            chart: {
                caption: "二輪車主な輸出先地域の比較(単位:台)",
                stack100percent: "0",
                showxaxispercentvalues: "0",
                showvalues: "1",
                yAxisMaxValue:"150000",
                numDivLines:"0",
                canvasBgColor:"#f0f0f0"
            },
            categories:[{category: ds_label}],
            dataset:[
                {
                    seriesname: "251cc以上",
                    color:"#406c93",
                    ratio:"100",
                    valueFontColor :"#ffffff",
                    data: ds_value1
                },
                {
                    seriesname: "126-250cc",
                    color:"#92b7c0",
                    ratio:"100",
                    valueFontColor :"#000000",
                    data: ds_value2
                },
                {
                    seriesname: "125cc以下",
                    color:"#d1e3e1",
                    ratio:"100",
                    valueFontColor :"#000000",
                    data: ds_value3
                }
            ]
        };
        FusionCharts.ready(function() {
            var myChart = new FusionCharts({
                type: "marimekko",
                renderAt: $chartDrawDiv[0],
                width: 700,
                height: 500,
                dataFormat: "json",
                dataSource
            }).render();
        });
    });
};
```
##### プレビュー
[プレビュー] に移り、どのようなチャートが作成されるか確認します。横軸に地域、縦軸に台数を配置し、地域とエンジンサイズから輸出状況を一目で把握することができます。が、100% 積み上げではないです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/35aa34e5-5cbd-50ec-a031-2fbea0e9046f.png)

## 4. コードの内容
動作概要が分かったところで、コードの中身を見てみましょう。
##### generateChart
```JavaScript:generateChart
generateChart = function(options) {
    var $chartDrawDiv = $(options.divSelector);
    var processedDataLabel = processDataLabel(options.dataset.data);
    var processedDataValue1 = processDataValue1(options.dataset.data);
    var processedDataValue2 = processDataValue2(options.dataset.data);
    var processedDataValue3 = processDataValue3(options.dataset.data);
    doDrawing(processedDataLabel, processedDataValue1, processedDataValue2, processedDataValue3, $chartDrawDiv);
},
```

JavaScript グラフの処理において、最初に呼び出されるのが `generateChart = function(options)` です。
[データ] ステップでテーブルに追加した情報が、options に格納されて、メソッドに受け渡されます。
`var $chartDrawDiv = $(options.divSelector)` でグラフを出力する div を選択します。
`var processedDataLabel = processDataLabel(options.dataset.data);`
`var processedDataValue1 = processDataValue1(options.dataset.data);`
`var processedDataValue2 = processDataValue2(options.dataset.data);`
`var processedDataValue3 = processDataValue3(options.dataset.data);`
`doDrawing(processedDataLabel, processedDataValue1, processedDataValue2, processedDataValue3, $chartDrawDiv);`

上記 6 行で、別の関数を呼び出して、データ処理とグラフ描画処理を行っています。呼び出し先の関数での処理内容は後続の個所で説明をします。

##### processDataLabel
```JavaScript:processDataLabel
processDataLabel = function(dataset) {
    var ds_label = [];
    var prev_label = "first";
    for (i=0;i<dataset.area.length;i++){
        if(dataset.area[i].raw_data !== prev_label){
            ds_label.push({
                label: dataset.area[i].raw_data,
            });
        }
        prev_label = dataset.area[i].raw_data;
    }
    return ds_label;
},
```
Yellowfin のデータセットを JSON の配列に変換して ds_label にオブジェクトとして格納しています。
今回のサンプルデータであれば、以下のような JSON の書式になります。横軸のラベルを決めています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/1454a215-eb81-4194-da7b-11f0c1fc9a0d.png)
ラベルとして取り扱うデータなので、同じものを重複して配列に追加しないように、ベタなコーディングをしています。

上記は [グラフ] ステップでディベロッパーツールのコンソールから確認したものです。コードの中に `console.log(JSON.stringify(ds_label))` を記述しておくと、データオブジェクトの中身をコンソールで確認することができます。今回の場合は、doDrawing の先頭に記述しています。デバッグに便利なので、活用してみてください。

以下の手順では、上記と同じ要領で、マリメッコチャートを描くために必要なデータを各関数の中データセットで取り込んでいく流れになります。

##### processDataValue1
251cc 以上のバイクの輸出台数に関わるデータをオブジェクトに格納します。
```JavaScript: processDataValue1
processDataValue1 = function(dataset) {
    var ds_value1 = [];
    for (j=0;j<dataset.size.length;j++){
        if(dataset.size[j].raw_data == "251cc以上"){
            ds_value1.push({
                value: dataset.num[j].raw_data,
            });
        }
    }
    return ds_value1;
},
```

##### processDataValue2
126-250cc のバイクの輸出台数に関わるデータをオブジェクトに格納します。

```JavaScript: processDataValue2
processDataValue2 = function(dataset) {
    var ds_value2 = [];
    for (k=0;k<dataset.num.length;k++){
        if(dataset.size[k].raw_data == "126-250cc"){
            ds_value2.push({
                value: dataset.num[k].raw_data,
            });
        }
    }
    return ds_value2;
},
```
##### processDataValue3
125cc以下 のバイクの輸出台数に関わるデータをオブジェクトに格納します。
```JavaScript: processDataValue3
processDataValue3 = function(dataset) {
    var ds_value3 = [];
    for (l=0;l<dataset.num.length;l++){
        if(dataset.size[l].raw_data == "125cc以下"){
            ds_value3.push({
                value: dataset.num[l].raw_data,
            });
        }
    }
    return ds_value3;
},
```

##### doDrawing
```JavaScript:doDrawing
doDrawing = function(ds_label, ds_value1, ds_value2, ds_value3, $chartDrawDiv) {
    console.log(JSON.stringify(ds_label));
    console.log(JSON.stringify(ds_value1));
    console.log(JSON.stringify(ds_value2));
    console.log(JSON.stringify(ds_value3));
    require(['js/chartingLibraries/fusioncharts-suite-xt/js/fusioncharts.js'], function(){
        const dataSource = {
            chart: {
                caption: "二輪車主な輸出先地域の比較(単位:台)",
                stack100percent: "0",
                showxaxispercentvalues: "0",
                showvalues: "1",
                yAxisMaxValue:"150000",
                numDivLines:"0",
                canvasBgColor:"#f0f0f0"
            },
            categories:[{category: ds_label}],
            dataset:[
                {
                    seriesname: "251cc以上",
                    color:"#406c93",
                    ratio:"100",
                    valueFontColor :"#ffffff",
                    data: ds_value1
                },
                {
                    seriesname: "126-250cc",
                    color:"#92b7c0",
                    ratio:"100",
                    valueFontColor :"#000000",
                    data: ds_value2
                },
                {
                    seriesname: "125cc以下",
                    color:"#d1e3e1",
                    ratio:"100",
                    valueFontColor :"#000000",
                    data: ds_value3
                }
            ]
        };
        FusionCharts.ready(function() {
            var myChart = new FusionCharts({
                type: "marimekko",
                renderAt: $chartDrawDiv[0],
                width: 700,
                height: 500,
                dataFormat: "json",
                dataSource
            }).render();
        });

    });
};
```
`require[]` の中で、JavaScriptライブラリーを格納したディレクトリーを相対パスで記述します。
`dataSource` `chart` の中で、チャートの見た目を定義しています。
例えば`stack100percent: "0",` は、100% 積み上げにするか否かを決めています。値を 1 (TRUE) に変更すると、以下のような見た目に変更されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/5730039c-71c0-3e29-6770-4b3bf78a028e.png)

`showvalues: "1"` は、チャート上に数値を表示するか否かを決めるものです。1 (TRUE) を設定しているので、チャート上に数値が表示されています。

`categories:[{category: ds_label}],`で、先の手順でデータセットに取り込んだオブジェクトの中身 (横軸のラベル) を FushionCharts に受け渡します。

`dataset:[`の中で、エンジンサイズ毎の輸出台数に関わるデータを FusionCharts に受け渡しています。例えば、`data: ds_value1`で251cc 以上、`data: ds_value2`で 126–250cc といった具合に、先の手順でデータセットに取り込んだオブジェクトの中身を受け渡します。

`FusionCharts.ready` でチャートを描画します。
`type: " marimekko”,` でチャートの種類を指定します。
`renderAt: $chartDrawDiv[0]` でチャートを描画する div を指定します。`$chartDrawDiv` はコードの先頭で宣言した変数です。

結果、以下のようなちょっと変わったマリメッコチャートが出来上がりました。マウスをホバーすると、該当箇所の情報がツールチップで確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/02aab893-bfb7-61e1-ccb9-7bf8291583ce.png)

今回のように、全体から一部データだけを抜き出して比較する時は、100% 積み上げよりも、こちらの見え方の方が良いかもしれませんね。

地域としては欧州に対する輸出量が多く、また大型の二輪車がかなりの割合を占めています。
アジア各地では、小型二輪車が多く販売されているイメージがあります。生産拠点の現地化の波に乗って、小型車は現地で生産・販売される傾向が強まり、付加価値が高く利幅の大きい大型二輪が輸出の中心になっている構図もあるかと思います。
ちなみに、[ホンダは 2020 年に、ベトナムで二輪車生産累計 3,000 万台]( https://www.honda.co.jp/news/2020/c201029a.html)を達成したそうです。

## 5. 最後に
20 年近く前にホーチミンを訪れた際、街中が小型バイクだらけだったことを記憶しています。当時、ベトナムの女性の中では美白がブームで、夏のとてもとても暑い中、小型バイクの後ろに乗る女性たちは、皆さん肌を露出しないように苦労されていたことを思い出しました。
私事ですが、ゴーグルによる冬のパンダ焼けだけはしないように気を付けまくったものの、夏に入った途端にウェットスーツ着用時にやりがちなビーサン焼けしてしまいました (←誰が興味あんねん)。

何はともあれ、皆さん、暑さに負けず、良いデータ分析を! Cheers!!