2016年10月30日日曜日

開発環境

素数夜曲 (吉田 武 (著)、東海大学出版会)の付録D(女王陛下のLISP)、D.6(パスカルの三角形と剰余)、D.6.4(係数の分布を調べる)、分布のグラフ(円グラフ、Pie layout、パイチャート)を JavaScript で取り組んでみる。

コード(Emacs)

HTML5

<div id="graph0"></div>
<label for="row0">段数: </label>
<input id="k0" type="number" min="0" step="1" value="5">
<label for="n0">除数: </label>
<input id="n0" type="number" min="1" step="1" value="4">

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.6/d3.min.js" integrity="sha256-5idA201uSwHAROtCops7codXJ0vja+6wbBrZdQ6ETQc=" crossorigin="anonymous"></script>

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

JavaScript

{
    let div_graph = document.querySelector('#graph0'),
        input_k = document.querySelector('#k0'),
        input_n = document.querySelector('#n0'),
        inputs = [input_k, input_n],
        width = 600,
        height = 600,
        outerRadius = width / 2,
        innerRadius = 0,
        pie = d3.pie(),
        arc,
        svg,
        color = d3.schemeCategory10;

    pie.sort((a, b) => a.rem - b.rem);
    arc = d3.arc()
        .innerRadius(innerRadius)
        .outerRadius(outerRadius);

    let iota = (start, end, step=1) => {
        let result = [];
        
        for (let i = start; i <= end; i += step) {
            result.push(i);
        }
        return result;
    };
    let fact = (n) => {
        let result = 1;
        for (let i = 2; i <= n; i += 1) {
            result *= i;
        }
        return result;
    };
    let bc = (n, r) => {
        return Math.round(fact(n) / (fact(r) * fact(n - r)));
    };

    let row = (n) => {
        return iota(0, n).map((x) => bc(n, x));
    };
    let row_mod = (n, m) => {
        return row(n).map((x) => x % m);
    };
    let pas_mod = (n, m) => {
        return iota(0, n).map((x) => row_mod(x, m));
    };
    let dis_1 = (k, n, i) => {
        return [i,
                pas_mod(k, n)
                .reduce((x, y) => x.concat(y))
                .filter((x) => x === i)
                .length]
    };
    let bc_dis = (k, n) => {
        return iota(0, n - 1).map((x) => dis_1(k, n, x));
    };
    let pile = (k, n) => {
        return bc_dis(k, n).map((x) => {
            return {rem: x[0], n: x[1]};
        });
    };

    let draw = () => {
        let k = parseInt(input_k.value, 10),
            n = parseInt(input_n.value, 10),
            dataset = pile(k, n);

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

        let arcs = svg.selectAll('g.arc')
            .data(pie.value((d) => d.n)(dataset))
            .enter()
            .append('g')
            .attr('class', 'arc')
            .attr('transform', `translate(${outerRadius}, ${outerRadius})`);

        arcs.append('path')
            .attr('fill', (d, i) => color[i])
            .attr('d', arc);

        arcs.append('text')
            .attr('transform', (d) => `translate(${arc.centroid(d)})`)
            .attr('text-anchor', 'middle')
            .text((d) => d.value);
    };
    inputs.forEach((input) => input.onchange = draw);
    draw();
}

0 コメント:

コメントを投稿