静的に入力されたtableの値と、Chart.jsを連携してみた


ある案件で、tableに入力された値と、Chart.jsを連携する実装がありました。
今回は円グラフを使用しましたが、他のグラフでも応用可能だと思います。
参考になれば、幸いです。

##はじめに
table構造はとてもシンプルです。
（実際の運用では、それぞれの数値に関してhtmlは触らずに、WordPressのカスタムフィールドでの運用を想定しています。）
<p class="codepen" data-height="301" data-theme-id="dark" data-default-tab="html,result" data-user="___dan" data-slug-hash="yLgPKmx" style="height: 301px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="table - basic">
  <span>See the Pen <a href="https://codepen.io/___dan/pen/yLgPKmx">
  table - basic</a> by dan (<a href="https://codepen.io/___dan">@___dan</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

このtableを元に、以下の2つのパターンを実装しました。

- **カテゴリ毎の合計値**<br>
（tableでは年度別の合計値が出力されているが、Chart.js上ではカテゴリ毎の合計値を出力する。）
- **対合計比**<br>
（総計を基準にし、各カテゴリの合計値が何%なのかを出力する。）

##実装編
###カテゴリ毎の合計値

<p class="codepen" data-height="440" data-theme-id="dark" data-default-tab="css,result" data-user="___dan" data-slug-hash="wvgPRgy" style="height: 440px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="table(total) - chart.js">
  <span>See the Pen <a href="https://codepen.io/___dan/pen/wvgPRgy">
  table(total) - chart.js</a> by dan (<a href="https://codepen.io/___dan">@___dan</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
<br>
記述したjsは以下の通りです。
（trをscope範囲とし、それぞれの数値が記入されているtdをtargetとする。）

```JavaScript
//空の配列を用意
let total = [];

$('.scope').each(function () {
    let target = $(this).find('.target');
    let sum = 0;

    for (let i = 0; i < target.length; i++) {
        //取得したtextが文字列のため、parseIntで数値型に変換
        //sum = $(target[i]).text() * 1 + sum;のように、1を掛けて数値型に変更するのもアリかと思います。
        sum = parseInt($(target[i]).text()) + sum;
    }

    //push()メソッドを使用して、sumの値を配列でtotalへ返却
    total.push(sum);
});

console.log(total);
//実行結果[60, 30, 6, 96] - カテゴリ毎の合計値が配列に格納
```
<br>
Chart.js内のdataに、作成したtotal変数をセットしてあげて完成です。

```JavaScript
data: total
```
<br>
なお、optionsの値がブラウザで確認したところ正常に動いていたのですが、
codepenで確認すると丸々抜けているようです、、、。
（本来であれば、円グラフの上に「進学先 人数」というタイトルと、ホバーしたときのラベルが〇〇人と表示されます。）

```JavaScript
options: {
    title: {
        display: true,
        text: '進学先 人数'
    },
    tooltips: {
        callbacks: {
            label: function (tooltipItem, data) {
                var label = data.labels[tooltipItem.index];

                if (label) {
                    label += ': ';
                }
                label +=
                    data.datasets[0].data[tooltipItem.index] + '人';
                return label;
            }
        }
    }
}
```

<br>
###対合計比

<p class="codepen" data-height="440" data-theme-id="dark" data-default-tab="js,result" data-user="___dan" data-slug-hash="eYgebxm" style="height: 440px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="table(ratio) - chart.js">
  <span>See the Pen <a href="https://codepen.io/___dan/pen/eYgebxm">
  table(ratio) - chart.js</a> by dan (<a href="https://codepen.io/___dan">@___dan</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
※こちらもoptionsの値が動いておりません、、、。
（本来であれば、円グラフの上に「進学先 割合」というタイトルと、ホバーしたときのラベルが〇〇%と表示されます。）
<br>
追加記述したjsは以下の通りです。

```JavaScript
//空の配列を用意
let ratio = [];

//先ほど取得したtotalの値が[60, 30, 6, 96]だが、合計値である96は不必要なのでlengthから-1する
for (let i = 0; i < total.length - 1; i++) {

    //total[i] - totalのi番目、つまり0番目の場合は60を取得
    //[total.length - 1] - 配列の最後の値である96を取得（全体の合計値）
    let calc = (total[i] / total[total.length - 1]) * 100;
    ratio.push(calc);
}

console.log(ratio);
//実行結果[62.5, 31.25, 6.25] - 合計値に対する、各カテゴリの割合が格納
```
<br>
Chart.js内のdataに、作成したratio変数をセットしてあげて完成です。

```JavaScript
data: ratio
```

##おわりに
公式サイトでは、設定するdataの値が静的に配列で記述されていますが、
そのdataに、自分で作成した変数をセットすれば様々な要件に対応できるかと思います。

※Chart.jsの基本的な使い方については、下記のサイトを参考に致しました。
 [Chart.jsでグラフを描画してみた](https://qiita.com/Haruka-Ogawa/items/59facd24f2a8bdb6d369)



##参考サイト
 [Chart.js公式サイト](https://www.chartjs.org/)
 [Tooltipsの設定値一覧](https://tr.you84815.space/chartjs/configuration/tooltip.html#tooltip-callbacks)
 [Chart.jsでグラフを描画してみた](https://qiita.com/Haruka-Ogawa/items/59facd24f2a8bdb6d369)
 [pushで配列に要素を追加する方法](https://www.sejuku.net/blog/84475)