1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Plotly の活用 ‐ Sunburst チャートによる再帰的データの扱い

Posted at

前回、『Chart.js の活用(基礎編)』と題して、JavaScript ライブラリーの活用に関する記事を投稿しました。今回は Plotly というライブラリーを使った Sunburst チャートの作成例を紹介したいと思います。ファイルシステムや組織階層など、階層の深さが定義できないデータを再帰的 (Recursive) に処理することにも適したチャートです。

###1. 事前準備
####1-1. ライブラリーの配置
Plotly を活用するためには、Yellowfin がアクセスできる場所にライブラリーを配置する必要があります。https://plotly.com/javascript/ にアクセスして、[Getting started] > [Download] と進み、plotly.jsファイルを取得します。
取得したファイルは、Yellowfin サーバー上の以下のディレクトリに配置します。これで、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 Country]、集計値に [Camp Rating] をそれぞれ選択します。
image.png

画面左からサブクエリーを選択し、タイプに [結合]、スタイルに [基本] を選択し、[OK] ボタンを押下します。
image.png

サブクエリー設定画面で、計算フィールドを2つ作成します。

計算フィールド名 備考
Region2 ’’ null値
Rating2 0 半角ゼロ
image.png
image.png

マスタークエリーフィールドとサブクエリーフィールドを以下の通りに設定します。

マスタークエリーフィールド サブクエリーフィールド
Camp Region Region2
Camp Country Camp Region
Camp Rating Rating2
image.png
[保存] ボタンを押下し、サブクエリー設定画面を閉じます。

結果、以下のような表が出来上がりました。後続の作業では、Camp Region 列を親、Camp Country 列を子として扱います。階層が特定できないデータであっても、このデータ構造であれば、際限なく深い階層のデータを管理できます。もちろん、データソース上で最初からこの構造でデータが管理されている場合、今回実施したデータ構造の変換作業は必要ありません。ちなみに、Camp Region (親)が null の行は、最上位の階層であることを示します。
image.png

###3. グラフの作成
[グラフ] ステップに進み、画面右側 [グラフの選択] から [JavaScriptグラフ] を選択します。
image.png

雛形を全て削除し、以下のコードに置き換えます。

JavaScript
generateChart = function(options) {
   console.log(JSON.stringify(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={ids:[], labels: [], parents: [], values: []}
   for (i=0;i<dataset['camp_rating'].length;i++){
        data['ids'].push(dataset['camp_country'][i].raw_data);
        data['labels'].push(dataset['camp_country'][i].formatted_data);
        data['parents'].push(dataset['camp_region'][i].formatted_data);
        data['values'].push(dataset['camp_rating'][i].raw_data);
    }
    return data
},

doDrawing = function(data, $chartDiv, height, width, errorFunction) {
    require(['js/chartingLibraries/plotly/plotly-2.8.3.min.js'], function(Plotly) {
    var trace = [{
        ids: data['ids'],
        labels: data['labels'],
        parents: data['parents'],
        values: data['values'],
        outsidetextfont: {size: 20, color: "black"},
        leaf: {opacity: 0.4},
        marker: {line: {width: 5}},
        type: 'sunburst'
    }];
    var layout = {
        margin: {l: 0, r: 0, b: 0, t: 0}
    };
    Plotly.newPlot($chartDiv[0], trace, layout);
   });
}

image.png

コードの内容を説明する前に、作成されるチャートと取り扱うデータの中身を先に確認します。[プレビュー] に移ると、Sunburst と呼ばれるチャートが表示されます。円の中心部を最上位とし、円の周囲に移動するに従って、階層を下ります。例えば、Asia の下に Japan が位置づきます。
image.png

グラフ作成に使われているデータの内容を確認するために、options に格納されるデータの中身を見てみましょう(以下 Chrome の手順)。[プレビュー] 画面で [F12] ボタンを押下するか、ブラウザ右上の [Google Chrome の設定] > [その他のツール] > [デベロッパー ツール] の順に進んで、デベロッパーツールを開きます。
image.png

画面下部で [情報] の内容を確認すると、[グラフ] ステップで集計した [Camp Region] [Camp Country] 軸と [Camp Rating] 集計値が JSON の形で表示されています。後述のコードの説明の中で、データフィールドを特定する個所がありますが、そこで指定するフィールド名は以下の情報と一致させる必要があります。
image.png

###4. コードの説明
作成されるチャートとデータの中身を確認したところで、コードの説明に移ります。

generateChart
generateChart = function(options) {
   console.log(JSON.stringify(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);
},

JavaScript グラフの処理において、最初に呼び出されるのが generateChart = function(options) です。

options の中身をJSON 形式でコンソールに出力する処理をする行が console.log(JSON.stringify(options)); です。先ほどデベロッパーツールを用いて中身を確認した情報は、この行が出力した情報です。

以下の3行で、グラフを出力する div を選択し、グラフの高さと幅に関する変数を扱います。
var $chartDrawDiv = $(options.divSelector);
var height = options.dataset.chart_information.height;
var width = options.dataset.chart_information.width;

以下の2行で、別の関数を呼び出して、データ処理とグラフ描画処理を行っています。呼び出し先の関数での処理内容は後続の個所で説明をします。
var processedData = processData(options.dataset.data);
doDrawing(processedData, $chartDrawDiv, height, width, options.errorCallback);

processData
processData = function(dataset) {
   data={ids:[], labels: [], parents: [], values: []}
   for (i=0;i<dataset['camp_rating'].length;i++){
        data['ids'].push(dataset['camp_country'][i].raw_data);
        data['labels'].push(dataset['camp_country'][i].formatted_data);
        data['parents'].push(dataset['camp_region'][i].formatted_data);
        data['values'].push(dataset['camp_rating'][i].raw_data);
    }
    return data
},

Yellowfin のデータセットを Plotly が扱う形式に変換して、data に格納しています。ids, labels, parents, values 項目はいずれも Plotly が Sunburst チャートを作成するために必須の項目で、for 分の中で Yellowfin のデータセットから、それぞれ camp_country, camp_country, camp_region, camp_rating を受け渡しています。

doDrawing
doDrawing = function(data, $chartDiv, height, width, errorFunction) {
    require(['js/chartingLibraries/plotly/plotly-2.8.3.min.js'], function(Plotly) {
    var trace = [{
        ids: data['ids'],
        labels: data['labels'],
        parents: data['parents'],
        values: data['values'],
        outsidetextfont: {size: 20, color: "black"},
        leaf: {opacity: 0.4},
        marker: {line: {width: 5}},
        type: 'sunburst'
    }];
    var layout = {
        margin: {l: 0, r: 0, b: 0, t: 0}
    };
    Plotly.newPlot($chartDiv[0], trace, layout);
   });
}

require(['js/chartingLibraries/plotly/plotly-2.8.3.min.js'], で、plotly.js ライブラリーの場所を指定します。今回であれば、『ライブラリーの配置』 手順でplotly-2.8.3.min.js を保管したディレクトリを相対パスで指定します。

var trace の中で、Yellowfin から受け取った data の中身を、Plotly の各項目に受け渡しています。Outsidetextfont, leaf, marker などでチャートの属性情報を設定します。他にも多くのオプションがあるので、以下でご確認ください。
https://plotly.com/javascript/reference/sunburst/

Plotly.newPlot($chartDiv[0], trace, layout);で、上記手順で設定した情報を用いて、実際にグラフを描画します。

###4. 最後に
いかがだったでしょう。私を含め、Sunburst チャートの存在を初めて知った人もいるのではないでしょうか。ちなみに、ここまでの手順で取り扱ったデータは、2 階層のデータでした。
一方で、階層の数が定義できないファイルシステムや組織階層などのデータを扱った場合にはどうなるでしょう。下の例は、ダミーの組織階層を使って作成した Sunburst チャートの例です。このように、階層数が読めないデータの処理においても、データ構造を可視化できます。
image.png

同じものを作成してみたい方は、こちら に CSV 形式のダミーデータを共有しているので、Yellowfin に取り込んで試してみてください。
CSV データのインポート https://wiki.yellowfin.co.jp/pages/viewpage.action?pageId=2294195

それではまた、Cheers!

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?