chart.js+ajax:チェックボックス形式で見たい地区のデータを可視化するプログラム

まずは結果から

以上のようなチェックボックスを作り、見たい地区についてチェックをつける。

ここで世田谷区と練馬区にチェックを入れると、以下のように世田谷区と練馬区の人口データのグラフが現れる。(単位は1000人)

港区と文京区にチェックを入れて送信すると、その2つの区のデータも追加される。

最終的にすべての項目にチェックを入れると以下のようになる。港区と文京区の人口が意外と少なく、世田谷区が一番多い。

手法

  1. 項目を選んで、サーバーに送信する
  2. 選んだ項目についてのデータをphp側で処理する
  3. データをフロントエンド側でchart.jsを用いて可視化する

コード

コードは大雑把に分けるとフォームの部分、グラフの部分、データのやり取りの部分。

1.フォームの部分

(phpでfor文を回してformをもっと簡潔に見せることもできたはずだが、時既に遅し)

wordpress/wp-content/themes/twentytwenty/header.php

<div id="div_ward_graphform" style="padding: 30px 30px">
    <form id="ward_graphform">
        <div>
            <div style="padding: 10px 10px">
                世田谷区:<input type="checkbox" name="setagaya" value="世田谷区">
            </div>
            <div style="padding: 10px 10px">
                葛飾区:<input type="checkbox" name="katsushika" value="葛飾区">
            </div>
        </div>
        <div>
            <div style="padding: 10px 10px">
                港区:<input type="checkbox" name="minato" value="港区">
            </div>
            <div style="padding: 10px 10px">
                文京区:<input type="checkbox" name="bunkyo" value="文京区">
            </div>
        </div>
        <div>
            <div style="padding: 10px 10px">
                江戸川区:<input type="checkbox" name="edogawa" value="江戸川区">
            </div>
            <div style="padding: 10px 10px">
                練馬区:<input type="checkbox" name="nerima" value="練馬区">
            </div>
        </div>
        <br>
        <input type="submit" value="送信">
    </form>
</div>
<div style="width: 50%;">
    <canvas id="myChart4"></canvas>
</div>
<br>
<br>

2.グラフの部分

wordpress/wp-content/themes/twentytwenty/header.php (同じなので、フォームの下に貼り付けるのでよい。)

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script>
<script>
jQuery(function($){
    // formの送信ボタンが押されたときの処理
    $( '#ward_graphform' ).submit( function(event){
        // クリックイベントをこれ以上伝播させない
        event.preventDefault();
        var fd = new FormData( this );
        console.log(fd);
        for (let value of fd.entries()) {
            console.log(value);
        }
        // サーバー側で何の処理をするかを指定。後ほどphp側で実装する
        fd.append('action'  , 'drawwardgraph' );
        $.ajax({
            type: 'POST',
            url: ajaxurl,
            data: fd,
            processData: false,
            contentType: false,
            success: function( response ){
                var jdata = JSON.parse(response);
                console.log(jdata);
                console.log(jdata["population"])
                var params = {
                    type: 'horizontalBar',
                    data: {
                        labels: jdata["place"],
                        datasets:[
                            {
                                data: jdata["population"],
                                label: "population"
                            }
                        ]
                    },
                    options: {
                        scales:{
                            xAxes:[{ticks:{min:0, fontSize:18}, scaleLabel: {fontSize: 18}}],
                            yAxes:[{ticks: {fontSize:18}, scaleLabel: {fontSize: 18}}]
                        },
                        title: {
                            display: true,
                            fontSize: 18,
                            text: '23区の人口'
                        }
                    }
                }
                var ctx = document.getElementById("myChart4").getContext('2d');
                var myBarChart = new Chart(ctx, params);
            },
            error: function( response ){
                console.log("errror");
            }
        });
        // ajaxの通信
        return false;
    });
});
</script>

3.phpでデータをやり取りする部分

本当はCSVを読み込みたかったが、エンコードのエラーなどが解決できず、そのまま貼ることにした。

wordpress/wp-content/themes/twentytwenty/functions.php

function add_my_ajaxurl() {
    ?>
        <script>
            var ajaxurl = '<?php echo admin_url( 'admin-ajax.php'); ?>';
        </script>
    <?php
}
add_action( 'wp_head', 'add_my_ajaxurl', 1 );


function drawwardgraph(){
        //データをarrayに格納
    $arr = array("世田谷区" => 883.3,
    "練馬区" => 719.1,
    "大田区" => 712.1,
    "江戸川区" => 686.4,
    "足立区" => 678.6,
    "杉並区" => 553.3,
    "板橋区" => 550.8,
    "江東区" => 501.5,
    "葛飾区" => 452.8,
    "品川区" => 378.1,
    "北区" => 341.3,
    "新宿区" => 334.2,
    "中野区" => 321.7,
    "豊島区" => 280.6,
    "目黒区" => 271.5,
    "墨田区" => 261.7,
    "港区" => 244.0,
    "渋谷区" => 219.9,
    "荒川区" => 211.3,
    "文京区" => 210.3,
    "台東区" => 191.7,
    "中央区" => 143.0,
    "千代田区" => 58.6);
    foreach($_POST as $key => $value){
            if (array_key_exists($value, $arr)) {
                $data["place"][] = $value;
                $data["population"][] = intval($arr[$value]);
            }
    }
    // echoで、クライアント側に返すデータを送信する
    echo json_encode($data);
    // dieしておかないと末尾に余計なデータ「0」が付与されるので注意
    die();

}
add_action( 'wp_ajax_drawwardgraph', 'drawwardgraph' );
add_action('wp_ajax_nopriv_drawwardgraph', 'drawwardgraph');