JavaScript Chart(d3-cloud)をYellowfin内のデータで表現する方法

##タグクラウド型のJSChart(d3-cloud)の概要
Metricsの大きさによってDimensionのfontsizeが変わるタグクラウドのような表現を可能にするJSChartです。
https://github.com/jasondavies/d3-cloud

![d3-cloud.png](https://qiita-image-store.s3.amazonaws.com/0/223443/9cbce90c-ed26-266c-d6d1-1ad256d7114b.png)



#Yellowfin7.3〜でできること

グラフ描画の部分にJavascriptを使ってプリセットされていないグラフを描画することができます。
これにより、Javascriptのinteractiveな操作やその他ライブラリを使った斬新な表現が可能になりました。
今回はd3-cloudで実現されるタグクラウドをYellowfinの中で表現できるように組み込みます。

###JavascriptChartを使うための事前設定1
管理者メニューの管理→システム構成からsystem→セキュリティ
Javascriptグラフを有効化、場合によってはクライアント組織自体にも権限付与する。

<img width="506" alt="事前設定.png" src="https://qiita-image-store.s3.amazonaws.com/0/223443/9049714b-1478-af2a-8abe-b7608afe5b8f.png">


###JavascriptChartを使うための事前設定2
管理コンソールのロールを開き、適切なロールに権限を付与する。

<img width="453" alt="事前設定2-1.png" src="https://qiita-image-store.s3.amazonaws.com/0/223443/31ee6bb9-9ee2-de63-5485-3132bf1c5810.png">


##ライブラリの保管場所について(準備)
<インストールフォルダ>/appserver/webapps/ROOT/js/chartingLibraries/
ROOTフォルダがjavasciptチャートを書く上でのルートフォルダにもなります。
ここに以下のファイルを配置
https://github.com/jasondavies/d3-cloud/blob/master/build/d3.layout.cloud.js

<img width="776" alt="ライブラリの保管場所.png" src="https://qiita-image-store.s3.amazonaws.com/0/223443/9ff2841f-7ef4-daac-005c-603551f4fd43.png">
この図上はcloud.jsに名前を変更しています。
また、この関数の引数でJSをObjectとして扱うことができます。

##タグクラウド型のJSChart(d3-cloud)の反映手順
###1.まずレポートの新規作成を行います
ここでは初期データとして投入されているデータのSki Teamのビューを使用します

###2.Camp NameとInvoiced Amountをカラムに追加します

<img width="370" alt="手順2.png" src="https://qiita-image-store.s3.amazonaws.com/0/223443/9f7f8cc9-9e7a-0102-a523-bfaf1387b631.png">


###3.グラフメニューに進み、JSChartを選択します

<img width="446" alt="手順3.png" src="https://qiita-image-store.s3.amazonaws.com/0/223443/7381c8e1-ec5e-e759-4a29-73d84f24e9bb.png">

###4.自動でJavascriptタブが出現し、初期値のスクリプトが入った状態になるので、下記のyellowfinTagCloud.jsの中身を全て初期値のスクリプトと入れ替えます

```js:yellowfinTagCloud.js
// Javascript Panel
// generateChart is a required function which will be called to generate your JS chart
generateChart = function (options) {
    // Use require to load the javascript libraries you need
    require(['js/chartingLibraries/d3_3.5.17/d3_3.5.17.min', 'js/chartingLibraries/cloud'], function (d3, cloud) {
        debugger; // This will trigger a breakpoint in your browser debugger so you can debug your javascript

        var $chartDrawDiv = $(options.divSelector);
        $chartDrawDiv.html(
            '<svg1></svg1>'
        );

        var data = options.dataset.data;



        //change data.camp_name to properly column name
        var nameColumn = data.camp_name;
        //change data.invoiced to properly column name
        var countColumn = data.invoiced_amount;


        var countMax = d3.max(countColumn, function (d) { return parseInt(d.raw_data) });
        var sizeScale = d3.scale.linear().domain([0, countMax]).range([10, 100])
        var fill = d3.scale.category20();
        var neodata = { name_Column: [], count_Column: [] };
        var data_names = [];
        var data_counts = [];

        //for excepting formatted data
        var nC = nameColumn;
        nC.forEach(function (key) {
            data_names.push(key.raw_data);
        });

        var cC = countColumn;
        cC.forEach(function (key) {
            data_counts.push(parseInt(key.raw_data));
        });
        neodata.name_Column = data_names;


        var words = neodata.name_Column.map(function (d) {
            return {
                text: d
            };
        });

        for (var i = 0; i < data_counts.length; i++) {
            words[i].size = sizeScale(data_counts[i]);
        }
        var random = d3.random.irwinHall(2)
        var layout = cloud()
            .size([600, 600])
            .words(words)
            .padding(1)
            //    .rotate(function() { return ~~(Math.random() * 2) * 90; })
            .rotate(function () { return Math.round(1 - random()) * 60; })// set the angle
            .font("Impact")
            .fontSize(function (d) { return d.size; })
            .on("end", draw);

        layout.start();

        function draw(words) {
            d3.select("svg1").append("svg")
                .attr("width", layout.size()[0])
                .attr("height", layout.size()[1])
                .append("g")
                .attr("transform", "translate(" + layout.size()[0] / 2 + "," + layout.size()[1] / 2 + ")")
                .selectAll("text")
                .data(words)
                .enter().append("text")
                .style("font-size", function (d) { return d.size + "px"; })
                .style("font-family", "Impact")
                .style("fill", function (d, i) { return fill(i); })
                .attr("text-anchor", "middle")
                .attr("transform", function (d) {
                    return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
                })
                .text(function (d) { return d.text; });
        }
    });
};

```

###5.プレビュータブを開くと、メトリクスの大きさに応じたタグクラウドができます

<img width="325" alt="手順6.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/223443/fa08e0be-a80f-c6d9-78a2-f7e22f5bcefa.jpeg">

##yellowfinTagCloud.js設定など

別のレポートの場合、18、20行目あたりの2つのカラム名を設定するディメンション・メトリクスに変更 (camp_name・invoiced_amountの部分)

Size:キャンパスサイズを設定
Padding:文字間隔を設定
Rotate:角度を設定
Font:フォントを設定
詳細はhttps://github.com/jasondavies/d3-cloud

もっと詳しい開発のための[Tipsはこちら](https://qiita.com/celery/items/d68e1e480e7455e1ecf4)