|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<head> |
|
<style> |
|
.axis { |
|
font: 10px sans-serif; |
|
} |
|
path { |
|
stroke: steelblue; |
|
stroke-width: 2; |
|
fill: none; |
|
} |
|
|
|
.axis path, |
|
.axis line { |
|
fill: none; |
|
stroke: #000; |
|
shape-rendering: crispEdges; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<div id="BandSelect" align=center></div> |
|
<script src="http://d3js.org/d3.v3.min.js"></script> |
|
<script> |
|
|
|
var data = [] |
|
|
|
for (var i = 0; i < 20; i++){ |
|
var a = 6 * Math.random(); |
|
data.push({'x': a,'y': 0.9 * Math.sin(a) + (0.25 * Math.random()) - 0.125}); |
|
} |
|
|
|
var sliderLabel = d3.select("#BandSelect") |
|
.append("label") |
|
.attr("for", "fader") |
|
.text("bandwidth"); |
|
|
|
var slider = d3.select("#BandSelect").append("input") |
|
.attr("id","slider2").attr("type","range") |
|
.attr("min","0.5").attr("max","6") |
|
.attr("step","0.25").attr("value","1") |
|
.attr("oninput","outputUpdate(value)"); |
|
|
|
var sliderOutput = d3.select("#BandSelect") |
|
.append("output").attr("for","fader") |
|
.attr("id","band") |
|
.text("1"); |
|
|
|
var margin = {top: 80, right: 180, bottom: 80, left: 180}, |
|
width = 960 - margin.left - margin.right, |
|
height = 500 - margin.top - margin.bottom; |
|
|
|
var svg = d3.select("body").append("svg") |
|
.attr("width", width + margin.left + margin.right) |
|
.attr("height", height + margin.top + margin.bottom) |
|
.append("g") |
|
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); |
|
|
|
var y = d3.scale.linear() |
|
.domain([-1, 1]) |
|
.range([height, 0]); |
|
|
|
var x = d3.scale.linear() |
|
.domain([0, 6]) |
|
.range([0, width]) |
|
|
|
var xAxis = d3.svg.axis() |
|
.scale(x) |
|
.orient("bottom"); |
|
|
|
var yAxis = d3.svg.axis() |
|
.scale(y) |
|
.orient("left"); |
|
|
|
var line = d3.svg.line() |
|
.x(function(d) { return x(d.x); }) |
|
.y(function(d) { return y(d.y); }); |
|
|
|
svg.append("g") |
|
.attr("class", "x axis") |
|
.attr("transform", "translate(0," + height + ")") |
|
.call(xAxis) |
|
|
|
svg.append("g") |
|
.attr("class", "y axis") |
|
.call(yAxis); |
|
|
|
svg.selectAll(".dot") |
|
.data(data) |
|
.enter().append("circle") |
|
.attr("class", "dot") |
|
.attr("r", 3.5) |
|
.attr("cx", function(d){ |
|
return x(d.x); |
|
}) |
|
.attr("cy", function(d){ |
|
return y(d.y) |
|
}) |
|
.style("fill", "black"); |
|
|
|
var smoothed = boxcarSmoother(data, 1, 0, 6, 1000); |
|
|
|
svg.append("path") |
|
.datum(smoothed) |
|
.attr("class", "line") |
|
.attr("d", line); |
|
|
|
slider.on("change", function(d){ |
|
band = ChangeReg(); |
|
|
|
var smoothed = boxcarSmoother(data, band, 0, 6, 1000); |
|
|
|
svg.selectAll(".line") |
|
.datum(smoothed) |
|
.transition() |
|
.attr("class", "line") |
|
.attr("d", line); |
|
}); |
|
function boxcarSmoother(data, bandwidth, rangeMin, rangeMax, samples){ |
|
//Takes a dataset and a bandwith parameter and performs a loess |
|
var support = []; |
|
var step = (rangeMax - rangeMin) / samples; |
|
|
|
//generate support set for given resolution |
|
for (var i = 0; i < samples; i++){ |
|
support.push(step * i); |
|
} |
|
|
|
var smoothData = []; |
|
for (var i = 0; i < samples; i++){ |
|
var activePoints = data.filter(function(d){ |
|
return ((support[i] >= d.x - bandwidth) && (support[i] <= d.x + bandwidth)); |
|
}).map(function(d){ |
|
return d.y; |
|
}); |
|
if (activePoints.length == 0){ |
|
activePoints.push(0); |
|
} |
|
var estimateY = activePoints.reduce(function(a, b){ |
|
return a + b; |
|
}); |
|
smoothData.push({'x': support[i], 'y': estimateY / activePoints.length}); |
|
} |
|
return smoothData; |
|
} |
|
function ChangeReg() { |
|
var e = document.getElementById("band"); |
|
var selection = +e.value; |
|
return selection; |
|
} |
|
function outputUpdate(vol) { |
|
document.querySelector('#band').value = vol; |
|
} |
|
</script> |
|
</body> |