21
22

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-03-05

はじめに

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

方法

1.データの用意

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

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

2.データのこねくり回し

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

//変数の初期化
$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
こんな感じの文字列が入っています。

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

3.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タグの間にグラフが入ります。

4.chart.js

<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

まとめ

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

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

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>

あとがき

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

21
22
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
22