2016年8月19日金曜日

開発環境

Pythonからはじめる数学入門 (Amit Saha (著)、黒川 利明 (翻訳)、オライリージャパン)の2章(データをグラフで可視化する)、2.6(プログラミングチャレンジ)、問題2-4(支出を可視化する)をJavaScript(とD3.js)で取り組んでみる。(バージョンアップで D3.js にいろいろ変更点があったみたい。)

問題2-4(支出を可視化する)

コード(Emacs)

HTML5

<div id="graph0"></div>
<label forid="categories_num">Enter the number of categories: </label> 
<input id="categories_num" type="number" min="1" step="1" value="4">
<div id="categories"></div>

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.2/d3.min.js"></script>

<script src="sample4.js"></script>

JavaScript

(function () {
    'use strict';
    var categories_num,
        width = 600,
        height = 400,
        padding = 50,
        padding_left = 100,
        bar_padding = 5,
        bar_width,

        div_graph = document.querySelector('#graph0'),
        input_categories_num = document.querySelector('#categories_num'),
        div_categories = document.querySelector('#categories'),

        createCategory,
        outputCategories,
        drawBarChart;

    createCategory = function (n) {
        var html =
            '<label for="category' + n + '">Enter category: </label>' +
            '<input id="category' + n + '" class="categories" type="text">' +
            '<br>' +
            '<label for="expenditure' + n + '">Expenditure: </label>' +
            '<input id="expenditure' + n + '" class="expenditures" ' +
            'type="number" min="0" step="1"' + 'value="' +
            (Math.floor(Math.random() * 100)) + '"><br>';

        return html;
    };
    outputCategories = function () {
        var i,
            html = '',
            class_names = ['.categories', '.expenditures'];
        
        categories_num = parseInt(input_categories_num.value, 10);
        for (i = 0; i < categories_num; i += 1) {
            html += createCategory(i);
        }

        div_categories.innerHTML = html;
        class_names.forEach(function (class_name) {
            var inputs = document.querySelectorAll(class_name),
                input,
                i,
                max;

            for (i = 0, max = inputs.length; i < max; i += 1) {
                input = inputs[i];
                input.onchange = drawBarChart;
                input.onkeyup = drawBarChart;
            }
        });
        drawBarChart();
    };
    drawBarChart = function () {
        var categories = [],
            expenditures = [],
            
            class_categories = document.querySelectorAll('.categories'),
            class_expenditures = document.querySelectorAll('.expenditures'),
            svg,
            xscale,
            xaxis,
            i,
            max;    

        for (i = 0, max = categories_num; i < max; i += 1) {
            categories.push(class_categories[i].value);
            expenditures.push(parseInt(class_expenditures[i].value, 10));
        }
        xscale = d3.scaleLinear()
            .domain([0, d3.max(expenditures)])
            .range([padding_left, width]);
        xaxis = d3.axisBottom().scale(xscale);

        div_graph.innerHTML = '';
        svg = d3.select('#graph0')
            .append('svg')
            .attr('width', width)
            .attr('height', height);

        bar_width = (height - padding * 2) / categories_num - bar_padding * 2;
        svg.selectAll('rect')
            .data(expenditures)
            .enter()
            .append('rect')
            .attr('x', xscale(0))
            .attr('y', function (d, i) {
                return padding + i * (bar_width + bar_padding * 2) +
                    bar_padding;
            })
            .attr('width', function (d) {
                return xscale(d);
            })
            .attr('height', function (d, i) {
                return bar_width;
            })
            .attr('fill', 'green');

        svg.append('g')
            .attr('transform', 'translate(0, ' + (height - padding) + ')')
            .call(xaxis);
        svg.append('text')
            .attr('x', xscale(d3.max(expenditures) / 2))
            .attr('y', padding / 2)
            .attr('text-anchor', 'middle')
            .text('1週間の支出');
        svg.append('text')
            .attr('x', xscale(d3.max(expenditures) / 2))
            .attr('y', height - padding / 4)
            .attr('text-anchor', 'middle')
            .text('計');
        for (i = 0; i < categories_num; i += 1) {
            svg.append('text')
                .attr('x', padding)
                .attr('y',
                      padding + (bar_padding * 2 + bar_width) * i +
                      bar_padding + bar_width / 2)
                .attr('text-anchor', 'middle')
                .text(categories[i]);
        }
    };
    input_categories_num.onchange = outputCategories;
    input_categories_num.onkeyup = outputCategories;

    outputCategories();
}());

0 コメント:

コメントを投稿