Excelに頼らず表形式データをChartistJSで棒グラフ化

# 始まり

ある日の出来事。
「こんな感じの棒グラフを1年分くらい作ってくれない？」
「1年分？！　・・・な、なるほど… 」（さらっときたな。手打ちだと死ぬ、VBAは覚えたくない、どうしよ・・・）

■こんな感じでーと言われた実際の例（数値は適当に変えてあります）
![元ネタ.png](https://qiita-image-store.s3.amazonaws.com/0/6463/32fac09d-e23c-efe1-7ce8-53efbc1e8611.png)

# ChartistJS

![chartisttop.png](https://qiita-image-store.s3.amazonaws.com/0/6463/a9248abe-57cd-450c-057b-8f386107d099.png)

後々の利便性を考えるとブラウザに表示しちゃうのが一番だと思ったのでその方向で。
「JavaScript　Chart」でググると以下の記事が出てきたので、日本で流行って無さそうなChartistJSを利用することに決めました。
ロゴのヒゲおじさんが格好いい。

PentahoといったBIの利用も一瞬頭をよぎりましたが、それはそれで牛刀だったので今回は不採用。

> [The 15 Best JavaScript Charting Libraries](http://www.sitepoint.com/15-best-javascript-charting-libraries/)

# データ

元データは既に存在（Excelに入っていた）のをCSV（カンマ区切り、囲み文字無し）に抽出。

入力データは以下の様な横持ちの時系列データ。
1日分のデータが3行ずつ固定で存在する形式です。

全部で大体1000行くらい、100KBくらいのデータ量です。

>```text:input1.csv
ymd,name,00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23
20140410,A,1,0,34,3,0,0,0,0,45,577,13442,683,796,1916,1971,4743,6711,6771,4659,890,424,80,36,9
20140410,B,209,0,19,0,0,8,42,503,3886,6602,5134,3084,1622,700,1359,1375,608,216,411,548,224,16,120,0
20140410,C,1070,635,301,1309,570,591,4619,11993,4767,2904,2180,1676,1338,1453,1634,1193,189,140,217,71,177,67,344,1194
20140411,A,12,0,0,2,1,50,0,0,99,584,14724,1976,945,2133,3148,4631,7282,6952,5429,704,333,130,16,13
20140411,B,25,1,0,0,0,11,17,294,3276,6643,5469,3345,1487,815,1355,1142,681,237,361,441,176,15,3,1
20140411,C,817,558,474,481,1123,849,4910,11737,5615,2549,1741,1820,1198,1621,1824,692,202,86,207,94,60,36,5,560
20140412,A,1,48,1,2,2,0,0,0,11,62,15274,627,689,624,897,1834,3134,1696,111,18,108,5,2,10
20140412,B,29,2,2,0,0,148,15,390,1933,3481,2509,1707,1231,564,467,744,436,252,356,349,70,7,2,1
20140412,C,883,319,271,437,605,296,1400,8041,3573,2012,729,1029,760,961,1129,1088,593,700,1212,516,143,134,3,10
20140413,A,0,0,0,2,0,0,0,0,34,13,70,218,185,645,253,398,983,433,13,9,6,5,5,0
20140413,B,45,0,7,0,0,7,0,9,799,1359,1987,1283,698,350,215,274,243,111,278,268,102,8,1,0
20140413,C,45,0,7,1,0,35,712,4594,3554,2199,770,816,996,1898,1731,1330,545,869,892,290,323,264,6,0
```

# 流れ

0. CSVをJSで読み込み
0. ChartistJSの欲しい構造に加工
0. ChartistJSで棒グラフをプロット

# 環境構築

初期環境構築は以下を参照下さい。
* [初めてChartist.jsを使うまでにやったこと - Qiita](http://qiita.com/laqiiz/items/b67ac5ae93f83c4bd0b6)

# 開発作業

## ディレクトリ階層

ファイルは以下のように配備しています。

```sh:フォルダ階層
~/html
  |--bower_components
  |--index.html
  |--input1.csv
```

## コーディング

HTML+JavaScriptです。
CSVファイル読み込み＋データ加工＋プロットを一気に実行しています。

```html:index.html
<!DOCTYPE html>
<html>
  <head>
	<title>My first Chartist Tests</title>
	<link rel="stylesheet"
		  href="bower_components/chartist/dist/chartist.min.css">
  </head>
  <body>
	<div id="ct-charts">
	</div>

	<script src="bower_components/chartist/dist/chartist.min.js"></script>
	<script type="text/javascript">
		
		// CSV読み込み
		function csv2Array(filePath) {
			var data = new XMLHttpRequest();
			data.open("GET", filePath, false); //true:非同期,false:同期
			data.send(null);
		 
			var LF = String.fromCharCode(10); //改行ｺｰﾄﾞ
			var lines = data.responseText.split(LF);
			
			// 読み込んだデータをカンマで分割
			var arr = new Array();
			for (var i = 0; i < lines.length; i++) {
				var cells = lines[i].split(",");
				arr.push(cells);
			}
			return arr;
		}

		var csvArr = csv2Array("input2.csv");

		var datas = new Array();
		var series = new Array();
		var chartNames = new Array();

		// 不要なデータ部を除去して、chartistが求めるlabelsととseriesを生成
		// 複数日分のグラフを作成したいので、data配列を準備
		for (var i = 1; i < csvArr.length; i++) {
			var arr = csvArr[i];
			series.push(arr.slice(2, -1));	
			if ((i +1) % 3 == 0) {
				var data = {};
				data.labels = csvArr[0].slice(2, -1);
				data.series = series;
				datas.push(data);
				series = new Array();
				chartNames.push(arr[0]);
			}
		}

		var options = {
			seriesBarDistance : 15, // 棒の間隔
			width : 600, // グラフサイズ横
			height : 400, // グラフサイズ縦
                        high : 25000 // Y軸の最大値
		};

		var responsiveOptions = [
		  ['screen and (min-width: 641px) and (max-width: 1024px)', {
			seriesBarDistance: 10,
			axisX : {
				labelInterpolationFnc: function (value) {
					return value;
				}
			}
		  }],
		  ['screen and (max-width: 640px)', {
			seriesBarDistance: 5,
			axisX: {
			  labelInterpolationFnc: function (value) {
				return value[0];
				}
			}
			}]
		];

		// 複数日分のグラフを出力するため出力用のdivタグを生成
		// Chartistではグラフに名称を付与することが出来ないようなので、divタグの中身に設定する
		for (var i = 0; i < datas.length; i++) {
            var div1 = document.createElement('div');
            div1.innerHTML = chartNames[i];
            div1.className = 'ct-chart' + (i + 1);
            var div = document.getElementById('ct-charts').appendChild(div1);

            var data = datas[i];
            new Chartist.Bar('.ct-chart' + (i + 1), datas[i], options, responsiveOptions);
		}
	</script>
  </body>
</html>
```


# 出力結果

以下にアクセスすると、上手くでてくれた！
1年分のデータ量でもほとんどフリーズせず動いてくれました。
本当は7列ずつ表示とか良かったのかもしれませんが、力尽きたので1列で。

> http://FQDN/username/index.html

![最終結果.png](https://qiita-image-store.s3.amazonaws.com/0/6463/2c55e427-1e3f-a4d7-ae2e-4ebd59ae89db.png)

スクロールも中々スムーズでした。
この調子だとページングしなくてもギリギリ大丈夫そうです。（ﾎｯ

# 出来たこと

* グラフサイズの変更
* Y軸のグラフの最大値・最小値は設定

# 出来なかったこと

力及ばず色々出来ませんでした。

* グラフの凡例
    * よく分からなかったため出力できず…（本家のAPIも見当たらず…）
* グラフ全体に名称を入れること
    * これも正しい手順が良くわからず

# 参考情報
* The 15 Best JavaScript Charting Libraries
    * http://www.sitepoint.com/15-best-javascript-charting-libraries/

* CHARTIST - EXAMPLES(OVERLAPPING BARS ON MOBILE)
    * https://gionkunz.github.io/chartist-js/examples.html#overlapping-bars-on-mobile

* JavaScriptからCSVの読み込み方
    * https://gist.github.com/tigawa/8858345

 
# おしまい

* 手でポチポチやるより遥かに楽できたので幸せです :sunny: 
* Chartist本来の強みであるレスポンシブな要素は全く使えなかったので、機会があれば利用したいですね :sparkles: