chart.jsで積み上げ横棒グラフを描く

#はじめに
項目数が多いから縦グラフじゃなくて横グラフで描きたいってときありますよね。

#方法
###１．データの用意

データがなくちゃ始まらない。

```php
   $datas = array(
	'太郎' => array (
			'国語' => 81
			, '数学' => 79
			, '理科' => 66
			, '社会' => 72
			, '英語' => 89
		),
	'次郎' => array (
			'国語' => 60
			, '数学' => 68
			, '理科' => 50
			, '社会' => 49
			, '英語' => 91
		),
	'三郎' => array (
			'国語' => 81
			, '数学' => 65
			, '理科' => 98
			, '社会' => 81
			, '英語' => 66
		)
   );
```


###２．データのこねくり回し

chart.jsに渡す用のデータを作成します。

```php
//変数の初期化
$labels   = '';
$japanese = '';
$math     = '';
$science  = '';
$social   = '';
$english  = '';

//データを文字列に
foreach ($datas as $name => $values){
	$labels   = sprintf('%s"%s", ', $labels, $name);
	$japanese = sprintf('%s%s, ', $japanese, $values['国語']);
	$math     = sprintf('%s%s, ', $math,     $values['数学']);
	$science  = sprintf('%s%s, ', $science,  $values['理科']);
	$social   = sprintf('%s%s, ', $social,   $values['社会']);
	$english  = sprintf('%s%s, ', $english,  $values['英語']);
}

//いらない部分を削除
$labels   = mb_substr($labels, 0, -2);
$japanese = mb_substr($japanese, 0, -2);
$math     = mb_substr($math, 0, -2);
$science  = mb_substr($science, 0, -2);
$social   = mb_substr($social, 0, -2);
$english  = mb_substr($english, 0, -2);
```

中身は、
labels = "太郎", "次郎", "三郎"
math   = 81, 60, 81
こんな感じの文字列が入っています。

もうちょっと綺麗にしたいですね♨

###３．HTML

```html

<!DOCTYPE html>
<html>
   <head>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script>
      <title>得点グラフ</title>
   </head>
   <body>
      <div class = "graph_box">
         <canvas id="score" class = "chart"></canvas>
      </div>
   </body>
</html>
```

canvasタグの間にグラフが入ります。

###４．chart.js

```html
<script>
//ロス回数
var ctx = document.getElementById("score");
var myChartSt = new Chart(ctx, {
	type: "horizontalBar"      //barで縦グラフ
	, data: {
		labels:  [<?php echo $labels;?>]
		, datasets: [
			{
				label: '国語'
				, borderWidth: 1
				, backgroundColor: "red"
				, borderColor: "red"
				, data: [<?php echo $japanese;?>]
			}
			, {
				label: '数学'
				, borderWidth: 1
				, backgroundColor: 'orange'
				, borderColor: 'orange'
				, data: [<?php echo $math;?>]
			}
			, {
				label: '理科'
				, borderWidth: 1
				, backgroundColor: 'green'
				, borderColor: 'green'
				, data: [<?php echo $science;?>]
			}
			, {
				label: '社会'
				, borderWidth: 1
				, backgroundColor: 'skyblue'
				, borderColor: 'skyblue'
				, data: [<?php echo $social;?>]
			}
			,{
				label: '英語'
				, borderWidth: 1
				, backgroundColor: 'black'
				, borderColor: 'black'
				, data: [<?php echo $english;?>]
			}
		]
	}
	, options: {
		title: {
			display: true
			, text: 'みんなの点数'		//グラフの見出し
			, padding: 3
			, fontSize: 20
		}
		, scales: {
			yAxes: [
				{ 
					stacked: true			   //積み上げ棒グラフの設定
					, xbarThickness: 16		   //棒グラフの幅
					, scaleLabel: {            // 軸ラベル
						display: true		   // 表示設定
						, labelString: '名前'  // ラベル
						, fontSize: 16         // フォントサイズ
					}
				}
			]
			, xAxes: [
				{
					stacked: true 		        //積み上げ棒グラフにする設定
					, scaleLabel: {             // 軸ラベル
						display: false		    // 表示設定
						, labelString: '総得点' 	// ラベル
						, fontSize: 16 		    // フォントサイズ
					}
				}
			]
		}
		, legend: {
			labels: {
				boxWidth:30
				, padding:20 		//凡例の各要素間の距離
			}
			, display: true
		}
		, tooltips: {
			mode: "label"
		}
	}
});
</script>
```
積み立て横棒グラフにするには、
・type: "horizontalBar"
・yAxes:[{stacked: true}]
とする。

###結果
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/272618/13c6a313-5003-f379-0c7b-a1abe9d9cf97.png)


#まとめ
縦グラフのときと、x,yが逆になるので注意。

下に全ソースを貼っておきます

```php:aaa.php
<?php
$datas = array(
	'太郎' => array (
			'国語' => 81
			, '数学' => 79
			, '理科' => 66
			, '社会' => 72
			, '英語' => 89
		),
	'次郎' => array (
			'国語' => 60
			, '数学' => 68
			, '理科' => 50
			, '社会' => 49
			, '英語' => 91
		),
	'三郎' => array (
			'国語' => 81
			, '数学' => 65
			, '理科' => 98
			, '社会' => 81
			, '英語' => 66
		)
);

//変数の初期化
$labels = '';
$japanese = '';
$math = '';
$science = '';
$social = '';
$english = '';

//データを文字列に
foreach ($datas as $name => $values){
	$labels = sprintf('%s"%s", ', $labels, $name);
	$japanese = sprintf('%s%s, ', $japanese, $values['国語']);
	$math = sprintf('%s%s, ', $math, $values['数学']);
	$science = sprintf('%s%s, ', $science, $values['理科']);
	$social = sprintf('%s%s, ', $social, $values['社会']);
	$english = sprintf('%s%s, ', $english, $values['英語']);
}

//いらない部分を削除
$labels = mb_substr($labels, 0, -2);
$japanese = mb_substr($japanese, 0, -2);
$math = mb_substr($math, 0, -2);
$science = mb_substr($science, 0, -2);
$social = mb_substr($social, 0, -2);
$english = mb_substr($english, 0, -2);
?>
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script>
<title>得点グラフ</title>
</head>
<body>
	<div class = "graph_box">
		<canvas id="score" class = "chart"></canvas>
	</div>
</body>
</html>
<script>
//ロス回数
var ctx = document.getElementById("score");
var myChartSt = new Chart(ctx, {
	type: "horizontalBar"      //barで縦グラフ
	, data: {
		labels:  [<?php echo $labels;?>]
		, datasets: [
			{
				label: '国語'
				, borderWidth: 1
				, backgroundColor: "red"
				, borderColor: "red"
				, data: [<?php echo $japanese;?>]
			}
			, {
				label: '数学'
				, borderWidth: 1
				, backgroundColor: 'orange'
				, borderColor: 'orange'
				, data: [<?php echo $math;?>]
			}
			, {
				label: '理科'
				, borderWidth: 1
				, backgroundColor: 'green'
				, borderColor: 'green'
				, data: [<?php echo $science;?>]
			}
			, {
				label: '社会'
				, borderWidth: 1
				, backgroundColor: 'skyblue'
				, borderColor: 'skyblue'
				, data: [<?php echo $social;?>]
			}
			,{
				label: '英語'
				, borderWidth: 1
				, backgroundColor: 'black'
				, borderColor: 'black'
				, data: [<?php echo $english;?>]
			}
		]
	}
	, options: {
		title: {
			display: true
			, text: 'みんなの点数'		//グラフの見出し
			, padding: 3
			, fontSize: 20
		}
		, scales: {
			yAxes: [
				{ 
					stacked: true			   //積み上げ棒グラフの設定
					, xbarThickness: 16		   //棒グラフの幅
					, scaleLabel: {            // 軸ラベル
						display: true		   // 表示設定
						, labelString: '名前'  // ラベル
						, fontSize: 16         // フォントサイズ
					}
				}
			]
			, xAxes: [
				{
					stacked: true 		        //積み上げ棒グラフにする設定
					, scaleLabel: {             // 軸ラベル
						display: false		    // 表示設定
						, labelString: '総得点' 	// ラベル
						, fontSize: 16 		    // フォントサイズ
					}
				}
			]
		}
		, legend: {
			labels: {
				boxWidth:30
				, padding:20 		//凡例の各要素間の距離
			}
			, display: true
		}
		, tooltips: {
			mode: "label"
		}
	}
});
</script>
```

#あとがき
案外まとめられてる記事がなかったので、備忘録です。
というか、これ使いやすいし、わかりやすいからそんなにまとめる必要もないかもしれない。