開発環境
- OS X El Capitan - Apple (OS)
- Emacs (Text Editor)
- JavaScript (プログラミング言語)
- D3.js (JavaScript Library)
- Safari(Web browser)
- JavaScript 第6版 (David Flanagan(著)、村上 列(翻訳)、オライリージャパン)(参考書籍)
- インタラクティブ・データビジュアライゼーション(Scott Murray(著)、長尾 高弘(翻訳)、オライリージャパン)(参考書籍)
Pythonからはじめる数学入門 (Amit Saha (著)、黒川 利明 (翻訳)、オライリージャパン)の3章(データを統計量で記述する)、3.9(プログラミングチャレンジ)、問題3-2(統計電卓)をJavaScript(とD3.js)で取り組んでみる。(バージョンアップで D3.js にいろいろ変更点があったみたい。)
問題3-2(統計電卓)
コード(Emacs)
HTML5
<div id="graph0"></div>
<br>
値: <span style="color:blue">----------</span>
平均値: <span style="color:green">----------</span>
中央値: <span style="color:red">----------</span>
<div id="output0"></div>
<input id="nums_data" type="file">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.2/d3.min.js"></script>
<script src="sample2.js"></script>
JavaScript
(function () {
'use strict';
var width = 600,
height = 400,
padding = 50,
padding_left = 50,
div_graph = document.querySelector('#graph0'),
div_output = document.querySelector('#output0'),
input_file = document.querySelector('#nums_data'),
readFile,
getNumbers,
display,
drawGraph;
Array.prototype.sum = function () {
var s = 0;
this.forEach(function (num) {
s += num;
});
return s;
};
Array.prototype.mean = function () {
var s = this.sum(),
n = this.length;
return s / n;
};
Array.prototype.median = function () {
var numbers = this.slice(),
len = numbers.length,
i1,
i2,
median;
numbers.sort();
if (len % 2 === 0) {
i1 = len / 2 - 1;
i2 = i1 + 1;
median = (numbers[i1] + numbers[i2]) / 2;
} else {
i1 = (len + 1) / 2 - 1;
median = numbers[i1];
}
return median;
};
Array.prototype.modes = function () {
var obj = {},
count,
num,
max = 0,
modes = [];
this.forEach(function (num) {
if (obj[num] === undefined) {
obj[num] = 1;
if (max === 0) {
max = 1;
}
} else {
count = obj[num] + 1;
obj[num] = count;
if (count > max) {
max = count;
}
}
});
for (num in obj) {
if (obj[num] === max) {
modes.push(parseInt(num, 10));
}
}
return modes;
};
Array.prototype.differences = function () {
var mean = this.mean(),
diff;
diff = this.map(function (num) {
return num - mean;
});
return diff;
};
Array.prototype.variance = function () {
var diff = this.differences(),
squared_diff,
len = this.length;
squared_diff = diff.map(function (x) {
return Math.pow(x, 2);
});
return squared_diff.sum() / len;
};
Array.prototype.standard_deviation = function () {
var variance = this.variance(),
std_deviation = Math.sqrt(variance);
return std_deviation;
};
getNumbers = function () {
var file = input_file.files[0],
reader,
numbers = [],
i,
max = 100;
if (file === undefined) {
for (i = 0; i < max; i += 1) {
numbers[i] = Math.floor(Math.random() * 100) + 1;
}
display(numbers);
}
reader = new FileReader()
reader.readAsText(file);
reader.onload = function () {
var text = reader.result;
numbers = text.split('\n')
.map(function (x) {
return x.trim();
})
.filter(function (x) {
return x !== '';
})
.map(function (x) {
return parseFloat(x);
});
display(numbers);
};
reader.onerror = function (error) {
throw error;
};
};
display = function (numbers) {
var mean = numbers.mean(),
median = numbers.median(),
modes = numbers.modes(),
variance = numbers.variance(),
std_dev = numbers.standard_deviation();
div_output.innerHTML =
'平均: ' + mean + '<br>' +
'中央値: ' + median + '<br>' +
'最頻値: ' + modes.join(', ') + '<br>' +
'分散: ' + variance + '<br>' +
'標準偏差: ' + std_dev + '<br>';
drawGraph(numbers, mean, median, modes, std_dev);
};
drawGraph = function (numbers, mean, median, modes, std_dev) {
var n = numbers.length,
svg,
xscale,
xaxis,
yscale,
yaxis;
xscale = d3.scaleLinear()
.domain([0, n])
.range([padding_left, width - padding]);
xaxis = d3.axisBottom().scale(xscale);
yscale = d3.scaleLinear()
.domain([d3.min(numbers), d3.max(numbers)])
.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('circle')
.data(numbers)
.enter()
.append('circle')
.attr('cx', function (d, i) {
return xscale(i);
})
.attr('cy', function (d, i) {
return yscale(d);
})
.attr('r', 4)
.attr('fill', 'blue');
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', padding_left / 4)
.attr('y', height / 2)
.attr('text-anchor', 'middle')
.text('値');
svg.append('line')
.attr('x1', xscale(0))
.attr('y1', yscale(mean))
.attr('x2', xscale(n))
.attr('y2', yscale(mean))
.attr('stroke', 'green');
svg.append('line')
.attr('x1', xscale(0))
.attr('y1', yscale(median))
.attr('x2', xscale(n))
.attr('y2', yscale(median))
.attr('stroke', 'red');
};
input_file.onchange = getNumbers;
getNumbers();
}());
値: ----------
平均値: ----------
中央値: ----------
0 コメント:
コメントを投稿