2016年8月20日土曜日

開発環境

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

問題2-5(フィボナッチ数列と黄金比の関係を調べる)

コード(Emacs)

HTML5

<div id="graph0"></div>
<label for="number0">n = </label>
<input id="number0" type="number" min="2" step="1" value="100">

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

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

JavaScript

(function () {
    'use strict';
    var width = 600,
        height = 400,
        padding = 50,
        padding_left = 50,
        div_graph = document.querySelector('#graph0'),
        input_number = document.querySelector('#number0'),

        fibo,
        drawGraph;

    fibo = function (n) {
        var series,
            a,
            b,
            c,
            i;
        
        if (n === 1) {
            return [1];
        }
        if (n === 2) {
            return [1, 1];
        }
        a = 1;
        b = 1;
        series = [a, b];
        for (i = 2; i < n ; i += 1) {
            c = a + b;
            series[i] = c;
            a = b;
            b = c;
        }
        return series;
    };

    drawGraph = function () {
        var number = parseInt(input_number.value, 10),
            series = fibo(number + 1),
            ratios = [],
            
            svg,
            xscale,
            xaxis,
            yscale,
            yaxis,
            
            i;

        for (i = 0; i < number; i += 1) {
            ratios[i] = series[i + 1] / series[i];
        }
        xscale = d3.scaleLinear()
            .domain([0, number - 1])
            .range([padding_left, width - padding]);
        xaxis = d3.axisBottom().scale(xscale);

        yscale = d3.scaleLinear()
            .domain([d3.min(ratios), d3.max(ratios)])
            .range([height - padding, padding]);
        yaxis = d3.axisLeft().scale(yscale);
        div_graph.innerHTML = '';
        svg = d3.select('#graph0')
            .append('svg')
            .attr('width', width)
            .attr('height', height);

        svg.selectAll('line')
            .data(ratios)
            .enter()
            .append('line')
            .attr('x1', function (d, i) {
                if (i === number - 1) {
                    return 0;
                }
                return xscale(i);
            })
            .attr('y1', function (d, i) {
                if (i === number - 1) {
                    return 0;
                }
                return yscale(d);
            })
            .attr('x2', function (d, i) {
                if (i === number - 1) {
                    return 0;
                }
                return xscale(i + 1);
            })
            .attr('y2', function (d, i) {
                if (i === number - 1) {
                    return 0;
                }
                return yscale(ratios[i + 1]);
            })
            .attr('stroke', 'green');
        
        svg.append('text')
            .attr('x', (width - padding_left) / 2)
            .attr('y', padding / 2)
            .attr('text-anchor', 'middle')
            .text('隣り合うフィボナッチ数の比');
        
        svg.append('g')
            .attr('transform', 'translate(0, ' + (height - padding) + ')')
            .call(xaxis);
        
        svg.append('g')
            .attr('transform', 'translate(' + padding_left + ', 0)')
            .call(yaxis);
        svg.append('text')
            .attr('x', (width - padding_left) / 2)
            .attr('y', height - padding / 4)
            .attr('text-anchor', 'middle')
            .text('数');
        svg.append('text')
            .attr('x', padding_left / 4)
            .attr('y', height / 2)
            .attr('text-anchor', 'middle')
            .text('比');
    };

    input_number.onchange = drawGraph;
    input_number.onkeyup = drawGraph;

    drawGraph();
}());

0 コメント:

コメントを投稿