0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ベン図 ‐ Yellowfin と amCharts の連携

Posted at

はじめに

YellowfinamCharts JavaScript ライブラリの活用第2弾として、今回はベン図を作成したいと思います。ちなみに、第一弾はこちら

事前準備

1-1. ビューの作成まで

以前の記事 を参考に、『1-2. ビューの作成』 までの作業を実施します。
今回ビューが参照するテーブルのデータは以下です。犬好きか、猫好きか、あるいは両方好きかのアンケート結果とお考え下さい。

name dog cat
ゆい はい いいえ
たろう いいえ はい
みなみ はい いいえ
しょうのすけ はい いいえ
ななえ いいえ はい
ステファン はい はい

上記テーブルの内容を、参照コードを使って以下のように修正します。dog 列の「はい」を「犬」に、cat 列の「はい」を「猫」に置き換えているだけです。

name dog cat
ゆい いいえ
たろう いいえ
みなみ いいえ
しょうのすけ いいえ
ななえ いいえ
ステファン

2. グラフの作成

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

2-1. [データ] ステップ

dog、cat、name 列をテーブルに配置し、name の個数を count するテーブルを作成します。
Yellowfin の集約に関しては、こちらをご参照ください。
image.png

2-2. [グラフ] ステップ

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

JavaScriptタブ

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

全容
generateChart = function(options) {
   var $chartDrawDiv = $(options.divSelector);
   var processedData = processData(options.dataset.data);
   doDrawing($chartDrawDiv, processedData);
},

processData = function(dataset) {
    var ds = [];
    for (i=0;i<dataset.dog.length;i++){
        if(dataset.dog[i].raw_data == 'はい' && dataset.cat[i].raw_data == 'いいえ'){
            var sets1 = [];
            sets1.push(dataset.dog[i].formatted_data);
            ds.push({
                name: dataset.dog[i].formatted_data,
                value: dataset.name[i].formatted_data,
                sets: sets1,
                sliceSettings: {
                    fill: am5.color(0x6e5a40)
                }
            });
        } else if(dataset.dog[i].raw_data == 'いいえ' && dataset.cat[i].raw_data == 'はい'){
            var sets2 = [];
            sets2.push(dataset.cat[i].formatted_data);
            ds.push({
                name: dataset.cat[i].formatted_data,
                value: dataset.name[i].formatted_data,
                sets: sets2,
                sliceSettings: {
                    fill: am5.color(0xb1d245),
                }
            });
        } else if(dataset.dog[i].raw_data == 'はい' && dataset.cat[i].raw_data == 'はい'){
            var sets3 = [];
            sets3.push(dataset.dog[i].formatted_data);
            sets3.push(dataset.cat[i].formatted_data);
            ds.push({
                name: "両方",
                value: dataset.name[i].formatted_data,
                sets: sets3,
                sliceSettings: {
                    fill: am5.color(0x5aaa95),
                }
            });
        }
    }
    console.log(JSON.stringify(ds));
    return ds;
},

doDrawing = function($chartDrawDiv, ds, obj) {
    require(['https://cdn.amcharts.com/lib/5/index.js','https://cdn.amcharts.com/lib/5/venn.js','https://cdn.amcharts.com/lib/5/themes/Animated.js'], function(){
        var $canvas = $('<div id="chartdiv"></div>');
        $chartDrawDiv.append($canvas);

        am5.ready(function() {
            var root = am5.Root.new("chartdiv");
            
            root.setThemes([
              am5themes_Animated.new(root)
            ]);
            
            var container = root.container.children.push(am5.Container.new(root, {
              width: am5.p100,
              height: am5.p100,
              layout: root.verticalLayout
            }));
            
            var chart = container.children.push(am5venn.Venn.new(root, {
              categoryField: "name",
              valueField: "value",
              intersectionsField: "sets",
              paddingTop: 40,
              paddingBottom: 40,
              paddingLeft: 40,
              paddingRight: 40
            }));
            
            var pattern = am5.CirclePattern.new(root, {
              fill: am5.color(0x000000),
              color: am5.color(0xffffff),
              radius: 10,
              gap: 10,
              checkered: true
            })
            
            chart.slices.template.setAll({ templateField: "sliceSettings" });
            chart.labels.template.set("fill", am5.color(0xffffff));
            chart.labels.template.setup = function(target) {
              target.set("background", am5.RoundedRectangle.new(root, {
                stroke: am5.color(0xffffffff),
                fill: am5.color(0x000000),
                cornerRadiusTL: 5,
                cornerRadiusTR: 5,
                cornerRadiusBL: 5,
                cornerRadiusBR: 5,
                fillOpacity: 1
              }));
            };
            
            chart.data.setAll(ds);

            chart.hoverGraphics.setAll({
              strokeDasharray: [3, 3],
              stroke: am5.color(0xffffff),
              strokeWidth: 2
            });
        });
    });
};

プレビューをすると、以下のようなベン図が表示されました。
image.png

コード

コードの中身を、順を追って説明します。

generateChart
generateChart
generateChart = function(options) {
   var $chartDrawDiv = $(options.divSelector);
   var processedData = processData(options.dataset.data);
   doDrawing($chartDrawDiv, processedData);
},
  • JavaScript グラフの処理において、最初に呼び出されるのが generateChart = function(options) です
  • [データ] ステップでテーブルに追加した情報が options に格納されて、メソッドに受け渡されます
  • processData でデータ処理を行うメソッドを呼び出し、doDrawingで描画するメソッドをそれぞれ呼び出しています。各メソッドで実行する具体的な処理は後述します
processData
processData
processData = function(dataset) {
    var ds = [];
    for (i=0;i<dataset.dog.length;i++){
        if(dataset.dog[i].raw_data == 'はい' && dataset.cat[i].raw_data == 'いいえ'){
            var sets1 = [];
            sets1.push(dataset.dog[i].formatted_data);
            ds.push({
                name: dataset.dog[i].formatted_data,
                value: dataset.name[i].formatted_data,
                sets: sets1,
                sliceSettings: {
                    fill: am5.color(0x6e5a40)
                }
            });
        } else if(dataset.dog[i].raw_data == 'いいえ' && dataset.cat[i].raw_data == 'はい'){
            var sets2 = [];
            sets2.push(dataset.cat[i].formatted_data);
            ds.push({
                name: dataset.cat[i].formatted_data,
                value: dataset.name[i].formatted_data,
                sets: sets2,
                sliceSettings: {
                    fill: am5.color(0xb1d245),
                }
            });
        } else if(dataset.dog[i].raw_data == 'はい' && dataset.cat[i].raw_data == 'はい'){
            var sets3 = [];
            sets3.push(dataset.dog[i].formatted_data);
            sets3.push(dataset.cat[i].formatted_data);
            ds.push({
                name: "両方",
                value: dataset.name[i].formatted_data,
                sets: sets3,
                sliceSettings: {
                    fill: am5.color(0x5aaa95),
                }
            });
        }
    }
    console.log(JSON.stringify(ds));
    return ds;
},

processData メソッドで、下記データが生成されます。

data
[{
"name": "猫",
	"value": 2,
	"sets": ["猫"],
	"sliceSettings": {"fill":{"_hex":11653701}
},{
	"name": "犬",
	"value": 3,
	"sets": ["犬"],
	"sliceSettings": {"fill":{"_hex":7232064}
},{
	"name": "両方",
	"value": 1,
	"sets": ["犬","猫"],
	"sliceSettings": {"fill":{"_hex":5941909}
}
}]
  • if で 3 条件に分けて、データセットを作成しています。if 条件の中では、raw_data を使って条件分岐を行っています。raw_data は、参照コードで値を置き替える前の元データを参照するときは、raw_data を指定します
  • sets キーの値は、[] で囲まれた配列の形になっています。つまり、JSON 全体としては、配列の入れ子構造になっています。そのため、予め set1 = で配列の値を作成しておいて、後に親の JSON データの sets の値に指定しています
  • sets1.push や ds.push などの中では、配列に formatted_data を追加しています。formatted_data は参照コードで値を置き替えた後のデータを参照する時に指定します
  • sliceSettings キーの値には、丸の内部を塗りつぶす色を固定値で設定しています。もちろん、データベースから色を定義する 16 進数のデータを取得して、ここに設定しても大丈夫です。sliceSettings で設定できる値一覧はこちらでご確認ください
  • 生成されるデータの中身を確認したい場合は、console.log(JSON.stringify(ds_coffee)) で、データをコンソールに出力しておくと便利です
CSS
css
#chartdiv{
    height: 500px;
    width: 100%;
}
  • CSS タブに上記を記述します。後ほど、定義した id を JavaScript から呼び出します
doDrawing
doDrawing
doDrawing = function($chartDrawDiv, ds, obj) {
    require(['https://cdn.amcharts.com/lib/5/index.js','https://cdn.amcharts.com/lib/5/venn.js','https://cdn.amcharts.com/lib/5/themes/Animated.js'], function(){
        var $canvas = $('<div id="chartdiv"></div>');
        $chartDrawDiv.append($canvas);

        am5.ready(function() {
            var root = am5.Root.new("chartdiv");
            
            root.setThemes([
              am5themes_Animated.new(root)
            ]);
            
            var container = root.container.children.push(am5.Container.new(root, {
              width: am5.p100,
              height: am5.p100,
              layout: root.verticalLayout
            }));
            
            var chart = container.children.push(am5venn.Venn.new(root, {
              categoryField: "name",
              valueField: "value",
              intersectionsField: "sets",
              paddingTop: 40,
              paddingBottom: 40,
              paddingLeft: 40,
              paddingRight: 40
            }));
            
            var pattern = am5.CirclePattern.new(root, {
              fill: am5.color(0x000000),
              color: am5.color(0xffffff),
              radius: 10,
              gap: 10,
              checkered: true
            })
            
            chart.slices.template.setAll({ templateField: "sliceSettings" });
            chart.labels.template.set("fill", am5.color(0xffffff));
            chart.labels.template.setup = function(target) {
              target.set("background", am5.RoundedRectangle.new(root, {
                stroke: am5.color(0xffffffff),
                fill: am5.color(0x000000),
                cornerRadiusTL: 5,
                cornerRadiusTR: 5,
                cornerRadiusBL: 5,
                cornerRadiusBR: 5,
                fillOpacity: 1
              }));
            };
            
            chart.data.setAll(ds);

            chart.hoverGraphics.setAll({
              strokeDasharray: [3, 3],
              stroke: am5.color(0xffffff),
              strokeWidth: 2
            });
        });
    });
};
  • require[] の中で、JavaScriptライブラリの場所を指定します。上記の例では CDN のアドレスを指定していますが、JS ライブラリをダウンロードして利用することも可能です
  • var root = am5.Root.new("chartdiv") で、CSS で定義した id を指定します
    root.setThemes で、デザインのテーマを指定します。今回は動きのある Animated を指定していますが、その他にもこちらのテーマが指定可能です。
  • containerpatternchart.sliceschart.labelschart.hoverGraphics では、チャートの見た目を定義しています。各項目の詳細は、Common elementsVenn diagram をご参照ください
  • chart.data.setAll(ds)の中で、作成したデータセットを、描画用のメソッドに受け渡しています。渡す際のデータ型は、JSON オブジェクトである必要があります

これでベン図の完成です。

最後に

Yellowfin と JS チャートを連携する際、Yellowfin のデータを、いかにしてチャートの仕様に合わせたデータ型に生成するががカギとなります。
今回のような、配列の入れ子になっているデータ型でも、さほど問題なく生成することができました。
Yellowfin の機能を補完することができるように、様々なチャートの作成に挑戦してみようと思います。

では皆様、良いデータ分析を!

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?