【カスタマイズビュー】値のカウントと比率を表示

お世話になっております。

標題の件について、

カスタマイズビューでレコードの値をカウントした数値の表示と比率を表示させたいと考えております。

下記のようなイメージです。

| 性 別 |

|男性|30人|42.8%|

|女性|40人|57.1%|

現在、下記のようなコードで試しているのですが、比率の表示がうまくいきません。

ご教授いただければ幸いです。宜しくお願い致します。

chart_0.name = "性別";
chart_0.data_set = [
    {
        label:"性別",
        value:0,
        ratio:0
    },
    {
        label:"男性",
        value:0,
        ratio:0
    },
    {
        label:"女性",
        value:0,
        ratio:0
    }
];
chart_0.data_set = setChartData(chart_0, resp.records);
chart_0.labels = $.map(chart_0.data_set, function(value, index){
    if(index !== 0) return value.label;
});
chart_0.data = $.map(chart_0.data_set, function(value, index){
    if(index !== 0) return value.value;
});
chart_0.labels = $.map(chart_0.data_set, function(ratio, index){
    if(index !== 0) return ratio.label;
});
chart_0.data = $.map(chart_0.data_set, function(ratio, index){
    if(index !== 0) return ratio.ratio;
});
chart_0.table = table_set(chart_0);

function table_set(chart){
    chart.table = document.createElement("table");
    $.each(chart.data_set, function(key, val){
        var lbl,v,r;
        if(key === 0){
            var headerRow = chart.table.insertRow(-1);
            lbl = headerRow.insertCell(0);
            lbl.innerHTML = val.label;
            lbl.colSpan = 3;
        }else{
            var newRow = chart.table.insertRow(-1);
            lbl = newRow.insertCell(0);
            v = newRow.insertCell(1);
            r = newRow.insertCell(2);
            lbl.innerHTML = val.label;
            v.innerHTML = val.value + " 人";
            r.innerHTML = val.ratio + " %";
        }
    });
    return chart.table;
}
function setChartData(chart, records){
    var data_set = $.map(chart.data_set, function(value, index){
        var count = records.filter(function(data){
            return data[chart.name].value === value.label;
        }).length;
        return {label:value.label, value:count};
    });
    var data_set = $.map(chart.data_set, function(ratio, index){
    });
    return data_set;
}

Nao さん
ざっと見たところ、下記が気になりました。

// chart_0.ratio ?
chart_0.data = $.map(chart_0.data_set, function(ratio, index){
if(index !== 0) return ratio.ratio;
});


function setChartData
...
// ratio 算出?
var data_set = $.map(chart.data_set, function(ratio, index){
});

 

 

ちょっと集計処理に手間がかかりすぎていると思われます。
集計だけなら下記のようなコードで出来ると思います。

var countGender = {
'男性': { value: 0, ratio: 0 },
'女性': { value: 0, ratio: 0 }
};
resp.records.forEach(function(record) {
var gender = record['性別'].value;
countGender[gender].value++;
countGender[gender].ratio = (countGender[gender].value * 100 / resp.records.length).toFixed(1);
});
console.table(countGender);

rex0220 様

ご返信ありがとうございます

 

実は、集計だけではなく、日付での絞込とグラフの表示も合わせて行っているので、

少し手間がかかったコードになっております。

現在全てのコードが下記になっております。

(function () {
    "use strict";
    
    kintone.events.on(['app.record.create.show'], function (event) {
        var record = event.record;
        return event;
        });

    kintone.events.on(['app.record.edit.show'], function (event) {
        var record = event.record;
    });

    kintone.events.on(['app.record.index.show'], function (event) {
        var records = event.records;

        if (event.viewId !== 5324104) {
            return;
        }

        var dateFormat = "yy-mm-dd";
        $.datepicker.setDefaults($.datepicker.regional["ja"]);
        $("#condition_start").datepicker(
            {
                dateFormat: dateFormat
            }
        );
        $("#condition_end").datepicker(
            {
                dateFormat: dateFormat
            }
        );
        $("#chart_space").hide();
        $("#condition_submit").click(function(){

            if(!$("#condition_start").val() || !$("#condition_end").val()){
                window.alert("日付が入力されていません。");
                return;
            }
            if(moment($("#condition_start").val()).isAfter(moment($("#condition_end").val()))){
                window.alert("日付が入力が正しくありません。");
                return;
            }

            var param_query = "";
            param_query += '日付 >= "' + moment($("#condition_start").val()).format("YYYY-MM-DD") + '" and ';
            param_query += '日付 <= "' + moment($("#condition_end").val()).format("YYYY-MM-DD") + '"';

            var param = {
                app: kintone.app.getId(),
                query: param_query,
                totalCount: true,
                isGuest: false
            };

            var sum = function(arr, fn) {
                if (fn) {
                    return sum(arr.map(fn));
                }
                else {
                    return arr.reduce(function(prev, current, i, arr) {
                            return prev+current;
                    });
                }
            };
            var average = function(arr, fn) {
                return sum(arr, fn)/arr.length;
            };

            kintoneUtility.rest.getAllRecordsByQuery(param).then(function(resp) {

                if(resp.records.length == 0){
                    window.alert("対象のアンケートがありませんでした。");
                    return;
                }

                $("#chart_space").show();
                var rate;
                if($("#attend").val()){
                    rate = Math.round((resp.records.length / parseInt($("#attend").val())) * 1000) / 10;
                }else{
                    rate = "回収率を計算するには参加者数を入力してください。";
                }
                $("#enquete_cnt").html(resp.records.length + " 人");
                $("#rate").html(rate + " %");

                var chart_1 = {};
                var chart_2 = {};
                var background_color = [
                    "#FF74A5",
                    "#FFDEAD",
                    "#000080",
                    "#FDF5E6",
                    "#808000",
                    "#5959AB",
                    "#FFA500"
                ];


                chart_1.name = "性別";
                chart_1.data_set = [
                    {
                        label:"性別",
                        value:0,
                        ratio:0
                    },
                    {
                        label:"男性",
                        value:0,
                        ratio:0
                    },
                    {
                        label:"女性",
                        value:0,
                        ratio:0
                    }
                ];
                chart_1.backgroundColor = background_color;
                chart_1.data_set = setChartData(chart_1, resp.records);
                chart_1.labels = $.map(chart_1.data_set, function(value, index){
                    if(index !== 0) return value.label;
                });
                chart_1.data = $.map(chart_1.data_set, function(value, index){
                    if(index !== 0) return value.value;
                });
                chart_1.table = table_set(chart_1);

                $("#gender_table").html(chart_1.table);
                $("#gender_table").addClass("data_table");

                chart_2.name = "住まい";
                chart_2.data_set = [
                    {
                        label:"住まい",
                        value:0,
                        ratio:0
                    },
                    {
                        label:"県内",
                        value:0,
                        ratio:0
                    },
                    {
                        label:"県外",
                        value:0,
                        ratio:0
                    },
                    {
                        label:"国外",
                        value:0,
                        ratio:0
                    }
                ];
                chart_2.backgroundColor = background_color;
                chart_2.data_set = setChartData(chart_2, resp.records);
                chart_2.labels = $.map(chart_2.data_set, function(value, index){
                    if(index !== 0) return value.label;
                });
                chart_2.data = $.map(chart_2.data_set, function(value, index){
                    if(index !== 0) return value.value;
                });
                chart_2.table = table_set(chart_2);
                $("#region_table").html(chart_2.table);
                $("#region_table").addClass("data_table");
                
                var Chart_1 = new Chart(document.getElementById("chart_1_graph"), {
                    type: 'pie',
                    data: {
                        labels: chart_1.labels,
                        datasets: [{
                            backgroundColor: chart_1.backgroundColor,
                            data: chart_1.data
                        }]
                    }
                });

                var Chart_2 = new Chart(document.getElementById("chart_2_graph"), {
                    type: 'pie',
                    data: {
                        labels: chart_2.labels,
                        datasets: [{
                            backgroundColor: chart_2.backgroundColor,
                            data: chart_2.data
                        }]
                    }
                });
            }).catch(function(error){
                window.alert(error.message);
            });
        });
        return event;
    });
})();

function table_set(chart){
    chart.table = document.createElement("table");
    $.each(chart.data_set, function(key, val){
        var lbl,v,r;
        if(key === 0){
            var headerRow = chart.table.insertRow(-1);
            lbl = headerRow.insertCell(0);
            lbl.innerHTML = val.label;
            lbl.colSpan = 3;
        }else{
            var newRow = chart.table.insertRow(-1);
            lbl = newRow.insertCell(0);
            v = newRow.insertCell(1);
            r = newRow.insertCell(2);
            lbl.innerHTML = val.label;
            v.innerHTML = val.value + " 人";
            r.innerHTML = val.ratio + " %";
        }
    });
    return chart.table;
}

function setChartData(chart, records){

    var data_set = $.map(chart.data_set, function(value, index){
        var count = records.filter(function(data){

            return data[chart.name].value === value.label;
        }).length;
        return {label:value.label, value:count};
    });
    return data_set;
}

Chart.pluginService.register({
    beforeRender: function (chart) {
        if (chart.config.options.showAllTooltips) {

            chart.pluginTooltips = [];
            chart.config.data.datasets.forEach(function (dataset, i) {
                chart.getDatasetMeta(i).data.forEach(function (sector, j) {
                    chart.pluginTooltips.push(new Chart.Tooltip({
                        _chart: chart.chart,
                        _chartInstance: chart,
                        _data: chart.data,
                        _options: chart.options.tooltips,
                        _active: [sector]
                    }, chart));
                });
            });

            chart.options.tooltips.enabled = false;
        }
    },
    afterDraw: function (chart, easing) {
        if (chart.config.options.showAllTooltips) {

            if (!chart.allTooltipsOnce) {
                if (easing !== 1)
                    return;
                chart.allTooltipsOnce = true;
            }

            chart.options.tooltips.enabled = true;
            Chart.helpers.each(chart.pluginTooltips, function (tooltip) {
                tooltip.initialize();
                tooltip.update();
                tooltip.pivot();
                tooltip.transition(easing).draw();
            });
            chart.options.tooltips.enabled = false;
        }
    }
});

上記コードですと、比率の表示値が「undefined %」と表示され、宣言だけで、何も代入されていない変数となっています。

おそらく下記コード部分に式を書くのかと思っているのですが、どのように書けばよいのかわからず、ご質問させていただきました。

function setChartData(chart, records){

    var data_set = $.map(chart.data_set, function(value, index){
        var count = records.filter(function(data){

            return data[chart.name].value === value.label;
        }).length;
        return {label:value.label, value:count};
    });
    return data_set;
}

度々お手数でございますが、ご教授いただければ幸いです。宜しくお願い致します。

raito 計算して、リターン情報に設定するだけでいいと思います。

 

function setChartData(chart, records){

var data_set = $.map(chart.data_set, function(value, index){
var count = records.filter(function(data){

return data[chart.name].value === value.label;
}).length;
// return {label:value.label, value:count};
var ratio = (count * 100 / records.length).toFixed(1);
return {label:value.label, value:count, ratio: ratio};
});
return data_set;
}

rex0220 様

早速のご返信ありがとうございます。

ご教授いただいたように書き換えると、問題なく表示されました。

いつも本当にありがとうございます。