Google Chartsを使ってみた

##初めに
　こんにちは。[CYBIRDエンジニア Advent Calendar 2015](http://qiita.com/advent-calendar/2015/cybird) 18日目を担当します[@cy-hiroshi-chiba](http://qiita.com/cy-hiroshi-chiba)です。今年中途入社で、現在はデータ分析の仕事をしています。

　昨日は[@doidoidon](http://qiita.com/doidoidon)さんの[Cocos Studio2を触ってみた](http://qiita.com/doidoidon/items/d4475b5f0892e35314b4)でした。アプリ作成にも興味があるので今すぐにでも試してみたくなりました。年末年始で触ってみます！！

　今日は、少し前にグラフライブラリの検討していたのですが、その中のGoogle Chartsを紹介したいと思います。

##Google Charts
　[Google Charts](https://developers.google.com/chart/)は様々なグラフが簡単に描け、デザイン・イベント処理などのカスタマイズが容易なライブラリです。同様のグラフライブラリは現在多く存在してますが、[HighCharts](http://www.highcharts.com/)、[amCharts](http://www.amcharts.com/)のように商用利用不可のライブラリとは違い、商用利用でも無料で利用することができます。
##とりあえず使ってみる
まずヘッダにJavascriptのリンクを張ります。

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Google Charts Test</title>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
</head>
<body>

</body>
</html>
```

次にグラフを描画するためのHTMLタグを記述します。

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Google Charts Test</title>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
</head>
<body>
<div id="chart" style="width: 100%; height: 100%; border: 1px solid #aaa;"></div>
</body>
</html>
```

こんな感じです。

では実際にグラフを描画する部分を記述していきます。
使用するデータは、スマホアプリ[Lifelog](http://www.sonymobile.co.jp/myxperia/app/lifelog/)で計測した、12月8日～12月14日まで歩数、乗車時間、消費カロリーデータを使用します。

| 日       | 歩数    | 乗車時間 | 消費カロリー |
|:--------:|:------:|:--------:|:-----------:|
| 12月 8日 | 7,432歩 | 80分    | 2,199kcal   |
| 12月 9日 | 5,474歩 | 54分    | 2,069kcal   |
| 12月10日 | 5,751歩 | 56分    | 2,075kcal   |
| 12月11日 | 6,037歩 | 109分   | 2,161kcal   |
| 12月12日 | 7,402歩 | 72分    | 2,359kcal   |
| 12月13日 |   532歩 | 16分    | 2,023kcal   |
| 12月14日 | 5,188歩 | 91分    | 2,093kcal   |

作りたいグラフををExcelで表現すると、こんな感じです。
![excel_screenshot.png](https://qiita-image-store.s3.amazonaws.com/0/100287/80120c20-e1a5-a654-707c-2457b4a453d0.png)
※Excelで第3軸が作れなかったため、歩数と消費カロリーは主軸で共有しています。

Google Chartsでこのグラフを作成するためには[Combo Chart](https://developers.google.com/chart/interactive/docs/gallery/combochart)を使います。コードはこんな感じです。


```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Google Charts Test</title>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
</head>
<body>
<div id="chart" style="width: 100%; border: 1px solid #aaa;"></div>
<script>
google.load('visualization', '1', { packages : [ 'corechart' ]});
google.setOnLoadCallback(drawChart);

function drawChart(){
     // 表示するデータの設定
	var data = new google.visualization.DataTable();
	data.addColumn('string', '日');
	data.addColumn('number', '歩数');
	data.addColumn('number', '乗車時間');
	data.addColumn('number', '消費カロリー');
	
	data.addRows([
	    ["12月8日",  7432,  80, 2199], 
	    ["12月9日",  5474,  54, 2069], 
	    ["12月10日", 5751,  56, 2075], 
	    ["12月11日", 6037, 109, 2161], 
	    ["12月12日", 7402,  72, 2359], 
	    ["12月13日",  532,  16, 2023], 
	    ["12月14日", 5188,  91, 2093]
	]);
	
    // グラフの設定
	var option = {
		title: 'Lifelogでとったデータ',
		width: '100%',
		height: '100%',
		series: [
			{ type: 'bars', targetAxisIndex: 0 },
			{ type: 'line', targetAxisIndex: 1 },
			{ type: 'area', targetAxisIndex: 2 }
		],
		vAxes: [
			{ title: '歩数(歩)' },
			{ title: '乗車時間（分）' }, 
			{ title: '消費カロリー（kcal）' }
		]
	};
	
	var chart = new google.visualization.ComboChart(document.getElementById('chart'));
	chart.draw(data, option);
}
</script>
</body>
</html>
```

表示するデータの設定部分は、DataTableのインスタンスを生成して、列の設定・データの追加をする方法のほか、CSV形式のような記述や、

```js
var data = google.visualization.arrayToDataTable([
    [     "日", "歩数", "乗車時間", "消費カロリー"]
    ["12月8日",  7432,         80,          2199], 
    ["12月9日",  5474,         54,          2069], 
    ["12月10日", 5751,         56,          2075], 
    ["12月11日", 6037,        109,          2161], 
    ["12月12日", 7402,         72,          2359], 
    ["12月13日",  532,         16,          2023], 
    ["12月14日", 5188,         91,          2093]
]);
```

JSON形式にも対応しています。

```js
var data = new google.visualization.DataTable({
    "cols": [
        {"type": "string", "label": "日"},
        {"type": "number", "label": "歩数"},
        {"type": "number", "label": "乗車時間"},
        {"type": "number", "label": "消費カロリー"}
    ],
    "rows": [
        {"c": [{"v": "12月8日"}, {"v": 7432}, {"v":  80}, {"v": 2199}]},
        {"c": [{"v": "12月9日"}, {"v": 5474}, {"v":  54}, {"v": 2069}]},
        {"c": [{"v": "12月10日"},{"v": 5751}, {"v":  56}, {"v": 2075}]},
        {"c": [{"v": "12月11日"},{"v": 6037}, {"v": 109}, {"v": 2161}]},
        {"c": [{"v": "12月12日"},{"v": 7402}, {"v":  72}, {"v": 2359}]},
        {"c": [{"v": "12月13日"},{"v":  532}, {"v":  16}, {"v": 2023}]},
        {"c": [{"v": "12月14日"},{"v": 5188}, {"v":  91}, {"v": 2093}]}
    ]
});
```

表示してみると...
![google_charts1.png](https://qiita-image-store.s3.amazonaws.com/0/100287/3d8c0968-9aa1-9ee0-3649-3af9cf92e516.png)
右側の縦軸の表記が、重なってしまいました...

その場合はoption内の設定を変更します。
textPositionは縦軸の表記の表示位置を'none', 'out', 'in'から選択し設定することができます。

```js
vAxes: [
   { title: '歩数(歩)' },
   { title: '乗車時間（分）', textPosition: 'in' }, 
   { title: '消費カロリー（kcal）' }
]
```
![google_charts2.png](https://qiita-image-store.s3.amazonaws.com/0/100287/0e87ea10-b220-578f-23fe-0a599d6667c8.png)

少々重なってはいますが、とりあえず分けることができます。

##Tooltipをカスタマイズする
デフォルトで、マウスオーバーすることでTooltipが表示され、対象日の対応する系列の情報が表示されるのですが、

![google_charts3.png](https://qiita-image-store.s3.amazonaws.com/0/100287/a4a31ddd-c090-a68e-fb56-96415eba3bc5.png)

これを対象日の歩数、乗車時間、消費カロリーをまとめて見たい場合は、optionに、

```js
focusTarget: 'category'
```

を追加すると、
![google_charts4.png](https://qiita-image-store.s3.amazonaws.com/0/100287/c5c9ae05-e667-0aff-b595-928a3d2bcde8.png)

のようにできます。

また、もっと細かく設定したい場合にはHTMLで記述していきます。
手順はまず、option内にTooltipの内容をHTMLで記述するための設定を有効にします。

```js

var option = {
   ...
   tooltip: {isHtml: true}
}
```

次に、HTMLを記述するための列を追加します。

```js
var data = new google.visualization.DataTable();
    data.addColumn('string', '日');
    data.addColumn({'type': 'string', 'role': 'tooltip', 'p': {'html': true}});
    data.addColumn('number', '歩数');
    ...
```

そして、実際に表示させる内容をHTMLで記述します。

```js
data.addRows([
      ["12月8日", '<p>12月8日</p><table><tr><th>歩数</th> ...', 7432,  80, 2199], 
      ...
]);
```

とりあえず自分はこうしてみました。

![google_charts5.png](https://qiita-image-store.s3.amazonaws.com/0/100287/fa735785-6d4f-b659-0f50-eb93a66db041.png)




また、Tooltip表示時に挿入される google-visualization-tooltipクラスを使ってスタイルを変更することもできます。

```css
.google-visualization-tooltip {
	opacity: 0.9;  /* 透明度を変えてみる */
}
```

![google_charts6.png](https://qiita-image-store.s3.amazonaws.com/0/100287/eb71dc7c-bc16-c6c8-5e60-6bdb99fa68e9.png)



##もっとこうしたい！！
Google Chartsを使ってみて、「もっとこうしたい！！」と思ったことです。少しでも参考になればと思います。
###Windowサイズにグラフのサイズを動的に変える
　Google Chartsはoptionにサイズを100%と設定するとdivなどのブロックのサイズに合わせてグラフを作成しますが、それはページロード時のみで、Windowサイズを変更してもグラフのサイズは変わりません。

![google_charts7.png](https://qiita-image-store.s3.amazonaws.com/0/100287/49332ba6-7d3f-f529-a2b0-2403e7835200.png)

必要であれば、以下のコードを追加します。

```js
$(window).resize(function(){
    chart.draw(data, option);
});
```

###HTMLで記述したTooltipの情報を動的に変更したい
　紹介したHTMLを利用したTooltipのカスタマイズでは、DataTableに直接記述しなければいけませんが、大量データを扱う場合、この方法ではHTMLだけでも膨大な情報量になるため、動的に生成できないかと考えました。

そこで、Tooltip表示時に挿入される google-visualization-tooltipクラスを使って以下の方法を試しました。

```js
//
// DataTableに記述したTooltipに関する情報は削除します。
//
var data = new google.visualization.DataTable();
data.addColumn('string', '日');
data.addColumn('number', '歩数');
data.addColumn('number', '乗車時間');
data.addColumn('number', '消費カロリー');

data.addRows([ 
     ["12月8日",  7432,  80, 2199], 
     ["12月9日",  5474,  54, 2069], 
     ["12月10日", 5751,  56, 2075], 
     ["12月11日", 6037, 109, 2161], 
     ["12月12日", 7402,  72, 2359], 
     ["12月13日",  532,  16, 2023], 
     ["12月14日", 5188,  91, 2093]
]);

// ・・・（中略）

var appendCustomTooltip = function(d){
     $(".google-visualization-tooltip").html(" ここにTooltipの内容を書く　");
}
google.visualization.events.addListener(chart, 'onmouseover', appendCustomTooltip);

```

すると、

![google_charts8.png](https://qiita-image-store.s3.amazonaws.com/0/100287/3a95f330-4958-4b37-a7b0-ab6405b7938b.png)
できました。

が、しかし・・・
![google_charts9.png](https://qiita-image-store.s3.amazonaws.com/0/100287/999f1135-331f-d144-6a07-779733ea758e.png)
Tooltip上にマウスカーソルを合わせると元に戻ってしまします…

でも、もう少しで出来そうですね…　
解決できたら報告します。


###凡例で系列の表示／非表示を切り替えたい
　HighCharts、amChartsでは、凡例をクリックするとデータの表示・非表示を切り替える機能があります。Google Chartsではその機能はありません。これを実現してみたいのですが、

>[Show/hide lines in Google Chart and show grayed text in legend](http://stackoverflow.com/questions/23806664/show-hide-lines-in-google-chart-and-show-grayed-text-in-legend)

を参考にしてみたところ、できました。
![google_charts10.png](https://qiita-image-store.s3.amazonaws.com/0/100287/14e1236d-f72a-2bbf-b78f-6ee2f180d49e.png)


##まとめ
　Google Chartsはグラフが簡単に描け、自由度も高いグラフライブラリです。でも、こだわりがありすぎると多少苦労するかもしれません…　皆さんもぜひ利用してみてください！！

##最後に
明日の[CYBIRDエンジニア Advent Calendar 2015](http://qiita.com/advent-calendar/2015/cybird)は、[@cy-katsuhiro-miura](http://qiita.com/cy-katsuhiro-miura)さんのです！どんな内容が出てくるのでしょうか？お楽しみに！