【Chart.js】データベースからグラフを作成する

## 実装したいこと
![グラフ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3082297/a462d26f-4577-b702-d915-9b5aaf34239f.png)
年齢人数を調べたデータベース「age_data」からグラフを作成する。
## 環境
* XAMPP Version 8.1.10
* Visual Studio Code Version 1.74.2
## データベース(phpMyAdmin)
|テーブル「age_data」|テーブル「age」|
|---|---|
|![テーブル「age_data」](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3082297/3f6b1897-9834-8b3a-efd6-f4c157653f76.png "テーブル「age_data」")|![テーブル「age」](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3082297/5a925a29-a939-e350-0d20-21527369422b.png "テーブル「age」")|
## お手本にしたコード
```php
<div>
  <canvas id="myChart"></canvas>
</div>

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<script>
  const ctx = document.getElementById('myChart');

  new Chart(ctx, {
    type: 'bar',
    data: {
      labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
      datasets: [{
        label: '# of Votes',
        data: [12, 19, 3, 5, 2, 3],
        borderWidth: 1
      }]
    },
    options: {
      scales: {
        y: {
          beginAtZero: true
        }
      }
    }
  });
</script>
```
引用 : [Getting Started | Chart.js](https://www.chartjs.org/docs/latest/getting-started/#:~:text=%23-,Create%20a%20Chart,-In%20this%20example)
## phpファイル
```php
<?php 
    try {
            $pdo = new PDO(
                'mysql:dbname=xxx;host=localhost;charset=utf8',
                'xxx',
                'xxx',
                [
                    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
                    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
                    PDO::ATTR_EMULATE_PREPARES =>false
                ]
            );
            $sql = "SELECT age,count(age_id) FROM age_data
                    RIGHT OUTER JOIN age on age.id = age_data.age_id
                    GROUP BY age
                    ORDER BY age.id";
            $stmt = $pdo->prepare($sql);
            $stmt->execute();
            $result = $stmt->fetchAll();
        } catch (PDOException $e) {
            header('Content-Type: text/plain; charset=UTF-8', true, 500);
            exit($e->getMessage()); 
        }
        header('Content-Type: text/html; charset=utf-8');
?>
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>example2</title>
    </head>
    <body>
        <center>
            <div class="chart-container" style="position: relative; height:40vh; width:60vw">
                <canvas id="myChart" ></canvas>
                <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
                <script>
                    var ctx = document.getElementById('myChart').getContext('2d');
                    var myChart = new Chart(ctx, {
                        type: 'bar',
                        data: {
                            labels: [<?php foreach($result as $row){
                                            echo '"'.($row["age"]).'",';
                                     } ?>],
                            datasets: [{
                                label: '年齢',
                                data: [<?php foreach($result as $row){
                                            echo $row["count(age_id)"].",";
                                       } ?>],
                                backgroundColor: 
                                    'rgba(255, 99, 132, 0.2)',
                                borderColor: 
                                    'rgba(255, 99, 132, 1)',
                                borderWidth: 1
                            }]
                        },
                        options: {
                            scales: {
                                yAxes: [{
                                    ticks: {     
                                        beginAtZero: true,
                                        max: 10
                                    }
                                }]
                            }
                        }
                    });
                </script>
            </div>
        </center>     
    </body>
</html>
```
## ポイント解説
```php
            $sql = "SELECT age,count(age_id) FROM age_data
                    RIGHT OUTER JOIN age on age.id = age_data.age_id
                    GROUP BY age
                    ORDER BY age.id";
```
テーブル`age`と`age_data`を<a href="https://wa3.i-3-i.info/word15311.html">左外部結合</a>する。
これで年齢データがない年代も0人として、グラフに表示されるようになる。
カラム`age`をグループ化することで、「10歳未満」、「10代」、「20代」…ごとにまとめる。
テーブル`age`のカラム`id`を昇順で並べてあげることで、「10歳未満」、「10代」、「20代」…のように順に表示させる。
```php
 <div class="chart-container" style="position: relative; height:40vh; width:60vw">
    <canvas id="myChart" ></canvas>
```
グラフのサイズを変更するには、`<canvas>`タグを`<div>`タグで囲む。
参考：[Responsive Charts | Chart.js](https://www.chartjs.org/docs/latest/configuration/responsive.html#:~:text=%23-,Important%20Note,-Detecting%20when%20the)

```php
                        data: {
                            labels: [<?php foreach($result as $row){
                                            echo '"'.($row["age"]).'",';
                                     } ?>],                           
```
`labels`(x軸)には、テーブル`age`のカラム`age`をループで、「10歳未満」、「10代」、「20代」…と表示。
文字列は、`""`でくくる。
変数と文字列を結合するには、`.`でくくる。
```php
                                data: [<?php foreach($result as $row){
                                            echo $row["count(age_id)"].",";
                                       } ?>],
```
年代別の人数`count(age_id)`をグラフのデータとして、渡す。
```php
                        options: {
                            scales: {
                                yAxes: [{
                                    ticks: {     
                                        beginAtZero: true,
                                        max: 10
                                    }
                                }]
                            }
                        }
```
Y軸`yAxes`の最大値を10とする。
## 参考文献
- [chart.js mysql接続　データ登録からグラフ表示まで - Qiita](https://qiita.com/H-Toshi/items/d548c92647a9ee30bc95)
- [Getting Started | Chart.js](https://www.chartjs.org/docs/latest/getting-started/#:~:text=%23-,Create%20a%20Chart,-In%20this%20example)
- [Responsive Charts | Chart.js](https://www.chartjs.org/docs/latest/configuration/responsive.html#:~:text=%23-,Important%20Note,-Detecting%20when%20the)
- [左外部結合とは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word15311.html)