はじめに
amCharts という JavaScript ライブラリを活用すると、色々と動きの面白いチャートを作成することができます。
今回はその中から、Directed Tree のチャートを使った例を紹介したいと思います。
事前準備
1-1. ビューの作成まで
以前の記事 を参考に、『1-2. ビューの作成』 までの作業を実施します。
今回使うデータは以下の表です。飲料製品の、各カテゴリとブランドのつながりを示すものとお考え下さい。
category | bland | value |
---|---|---|
コーヒー | コナ | 37 |
コーヒー | モカ | 37 |
コーヒー | ブレンド | 41 |
コーヒー | トラジャ | 43 |
紅茶 | アッサム | 42 |
紅茶 | ウヴァ | 37 |
紅茶 | ジャワ | 38 |
紅茶 | セイロン | 42 |
日本茶 | 緑茶 | 39 |
日本茶 | ほうじ茶 | 42 |
日本茶 | 麦茶 | 39 |
日本茶 | 玄米茶 | 39 |
ソーダ | ファンタ | 40 |
ソーダ | コーラ | 38 |
ソーダ | サイダー | 41 |
ソーダ | 強炭酸 | 41 |
2. グラフの作成
準備が整ったら、グラフの作成に手順を進めます。新規でレポートを作成し、以下の手順に従ってグラフを作成します。
2-1. [データ] ステップ
2-2. [グラフ] ステップ
[グラフ] ステップに進み、画面右側 [グラフの選択] から [JavaScriptグラフ] を選択します。
JavaScriptタブ
雛形を全て削除し、以下のコードに置き換えます。コードの処理の内容は後ほど説明します。
generateChart = function(options) {
var $chartDrawDiv = $(options.divSelector);
var processedCoffee = processCoffee(options.dataset.data);
var processedTea = processTea(options.dataset.data);
var processedJapan = processJapan(options.dataset.data);
var processedSoda = processSoda(options.dataset.data);
doDrawing($chartDrawDiv, processedCoffee, processedTea, processedJapan, processedSoda);
},
processCoffee = function(dataset) {
var ds_coffee = [];
for (i=0;i<dataset.category.length;i++){
if(dataset.category[i].raw_data === "コーヒー"){
ds_coffee.push({
name: dataset.bland[i].raw_data,
value: dataset.value[i].raw_data,
});
}
}
console.log(JSON.stringify(ds_coffee));
return ds_coffee;
},
processTea = function(dataset) {
var ds_tea = [];
for (ii=0;ii<dataset.category.length;ii++){
if(dataset.category[ii].raw_data === "紅茶"){
ds_tea.push({
name: dataset.bland[ii].raw_data,
value: dataset.value[ii].raw_data,
});
}
}
console.log(JSON.stringify(ds_tea));
return ds_tea;
},
processJapan = function(dataset) {
var ds_japan = [];
for (iii=0;iii<dataset.category.length;iii++){
if(dataset.category[iii].raw_data === "日本茶"){
ds_japan.push({
name: dataset.bland[iii].raw_data,
value: dataset.value[iii].raw_data,
});
}
}
console.log(JSON.stringify(ds_japan));
return ds_japan;
},
processSoda = function(dataset) {
var ds_soda = [];
for (iiii=0;iiii<dataset.category.length;iiii++){
if(dataset.category[iiii].raw_data === "ソーダ"){
ds_soda.push({
name: dataset.bland[iiii].raw_data,
value: dataset.value[iiii].raw_data,
});
}
}
console.log(JSON.stringify(ds_soda));
return ds_soda;
},
doDrawing = function($chartDrawDiv, ds_coffee, ds_tea, ds_japan, ds_soda) {
require(['https://cdn.amcharts.com/lib/5/index.js','https://cdn.amcharts.com/lib/5/hierarchy.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 data = {
value: 0,
children: [
{
name: "コーヒー",
children: ds_coffee
},
{
name: "紅茶",
children: ds_tea
},
{
name: "日本茶",
children: ds_japan
},
{
name: "ソーダ",
children: ds_soda
}
],
};
var zoomableContainer = root.container.children.push(
am5.ZoomableContainer.new(root, {
width: am5.p100,
height: am5.p100,
wheelable: true,
pinchZoom: true
})
);
var zoomTools = zoomableContainer.children.push(am5.ZoomTools.new(root, {
target: zoomableContainer
}));
var series = zoomableContainer.contents.children.push(am5hierarchy.ForceDirected.new(root, {
maskContent:false,
singleBranchOnly: false,
downDepth: 2,
topDepth: 1,
initialDepth: 3,
valueField: "value",
categoryField: "name",
childDataField: "children",
idField: "name",
linkWithField: "linkWith",
manyBodyStrength: -10,
centerStrength: 0.8
}));
series.get("colors").setAll({
step: 2
});
series.links.template.set("strength", 0.5);
series.labels.template.set("minScale", 0);
series.data.setAll([data]);
series.set("selectedDataItem", series.dataItems[0]);
series.appear(1000, 100);
});
});
};
コード
generateChart
generateChart = function(options) {
var $chartDrawDiv = $(options.divSelector);
var processedCoffee = processCoffee(options.dataset.data);
var processedTea = processTea(options.dataset.data);
var processedJapan = processJapan(options.dataset.data);
var processedSoda = processSoda(options.dataset.data);
doDrawing($chartDrawDiv, processedCoffee, processedTea, processedJapan, processedSoda);
},
JavaScript グラフの処理において、最初に呼び出されるのが generateChart = function(options) です。
[データ] ステップでテーブルに追加した情報が options に格納されて、メソッドに受け渡されます。
processCoffee、ProcessTea、ProcessJapan、ProcessSoda でデータ処理を行うメソッドを呼び出し、doDrawingで描画するメソッドをそれぞれ呼び出しています。各メソッドで実行する具体的な処理は後述します。
processCoffee
processCoffee = function(dataset) {
var ds_coffee = [];
for (i=0;i<dataset.category.length;i++){
if(dataset.category[i].raw_data === "コーヒー"){
ds_coffee.push({
name: dataset.bland[i].raw_data,
value: dataset.value[i].raw_data,
});
}
}
console.log(JSON.stringify(ds_coffee));
return ds_coffee;
},
コーヒーのツリーに結び付けるデータを、配列の形でデータセットに格納します。name にブランドを、value に売上を格納します。
console.log(JSON.stringify(ds_coffee))
を仕込んでおくと、下のようにブラウザのコンソールで具体的なデータを確認することができます。
processTea
processTea = function(dataset) {
var ds_tea = [];
for (ii=0;ii<dataset.category.length;ii++){
if(dataset.category[ii].raw_data === "紅茶"){
ds_tea.push({
name: dataset.bland[ii].raw_data,
value: dataset.value[ii].raw_data,
});
}
}
console.log(JSON.stringify(ds_tea));
return ds_tea;
},
同様に、紅茶のツリーに結び付けるデータを、配列の形でデータセットに格納します。
processJapan
processJapan = function(dataset) {
var ds_japan = [];
for (iii=0;iii<dataset.category.length;iii++){
if(dataset.category[iii].raw_data === "日本茶"){
ds_japan.push({
name: dataset.bland[iii].raw_data,
value: dataset.value[iii].raw_data,
});
}
}
console.log(JSON.stringify(ds_japan));
return ds_japan;
},
次に日本茶です。
processSoda
processSoda = function(dataset) {
var ds_soda = [];
for (iiii=0;iiii<dataset.category.length;iiii++){
if(dataset.category[iiii].raw_data === "ソーダ"){
ds_soda.push({
name: dataset.bland[iiii].raw_data,
value: dataset.value[iiii].raw_data,
});
}
}
console.log(JSON.stringify(ds_soda));
return ds_soda;
},
最後にソーダです。
CSS
##### CSS
#chartdiv{
height: 500px;
width: 100%;
}
CSS タブに上記を記述します。後ほど、定義した id を JavaScript から呼び出します。
doDrawing
doDrawing = function($chartDrawDiv, ds_coffee, ds_tea, ds_japan, ds_soda) {
require(['https://cdn.amcharts.com/lib/5/index.js','https://cdn.amcharts.com/lib/5/hierarchy.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 data = {
value: 0,
children: [
{
name: "コーヒー",
children: ds_coffee
},
{
name: "紅茶",
children: ds_tea
},
{
name: "日本茶",
children: ds_japan
},
{
name: "ソーダ",
children: ds_soda
}
],
};
var zoomableContainer = root.container.children.push(
am5.ZoomableContainer.new(root, {
width: am5.p100,
height: am5.p100,
wheelable: true,
pinchZoom: true
})
);
var zoomTools = zoomableContainer.children.push(am5.ZoomTools.new(root, {
target: zoomableContainer
}));
var series = zoomableContainer.contents.children.push(am5hierarchy.ForceDirected.new(root, {
maskContent:false,
singleBranchOnly: false,
downDepth: 2,
topDepth: 1,
initialDepth: 3,
valueField: "value",
categoryField: "name",
childDataField: "children",
idField: "name",
linkWithField: "linkWith",
manyBodyStrength: -10,
centerStrength: 0.8
}));
series.get("colors").setAll({
step: 2
});
series.links.template.set("strength", 0.5);
series.labels.template.set("minScale", 0);
series.data.setAll([data]);
series.set("selectedDataItem", series.dataItems[0]);
series.appear(1000, 100);
});
});
};
require[]
の中で、JavaScriptライブラリの場所を指定します。上記の例では CDN のアドレスを指定していますが、JS ライブラリをダウンロードして利用することも可能です。
var root = am5.Root.new("chartdiv")
で、CSS で定義した id を指定します。
root.setThemes
で、デザインのテーマを指定します。今回は動きのある Animated を指定していますが、その他にもこちらのテーマが指定可能です。
var data = {}
の中で、作成したデータセットを、描画用のメソッドに受け渡しています。
var zoomableContainer
と var zoomTools
で、マウス操作および画面上のアイコンによるズームを可能にします。
var series
以降で、表示内容やフィールド名称などに関する一通りの設定を設定し、適用しています。各設定の詳細はこちらでご確認ください。
出来上がり
最後に
オブジェクト同士のつながりは、やはり見やすいチャートで可視化したいものですね。
何より動きがあるチャートは見栄えが良い。
具体的な用途としては、人と人との関係性を可視化することなどにも使えそうですね。例えば親族同士のつながりを可視化して、インサイダー取引の疑いがある時に確認するなど。
他にも考えられ得る使用方法があれば是非ご意見ください。
では皆様、良いデータ分析を!