[英]Plot rolling/moving average in d3.js
尋找一種方法來繪制d3中的滾動/移動平均值,而無需事先操縱數據。 所以我想通過平均每個數據點和它后面的兩個數據點來平滑線。 我的代碼是這樣的
var data = [3, 66, 2, 76, 5, 20, 1, 3, 8, 90, 2, 5, 70];
var w = 20,
h = 80;
var x = d3.scale.linear()
.domain([0, 1])
.range([0, w]);
var y = d3.scale.linear()
.domain([0, 100])
.rangeRound([h, 0]);
var chart = d3.select("body").append("svg")
.attr("class", "chart")
.attr("width", w * data.length -1)
.attr("height", h);
var line = d3.svg.line()
.x(function(d,i) { return x(i); })
.y(function(d) { return y(d); })
var movingAverageLine = d3.svg.line()
.x(function(d,i) { return x(i); })
.y(function(d) { return y(d); })
chart.append("svg:path").attr("d", line(data));
chart.append("svg:path").attr("d", movingAverageLine(data));
我可以指定movingAverageLine來計算以下數據點的平均值嗎? 我想不出在該函數中訪問它們的方法。
我在jsfiddle上建立了一個例子。 http://jsfiddle.net/tjjjohnson/XXFrg/2/#run
先前的解決方案導致累積移動平均值。
我修改了 John O'Connor制作的小提琴 ,通過將自定義插值函數傳遞給d3.svg.line()
來提供n移動平均值 :
movingAvg = function(n) {
return function (points) {
points = points.map(function(each, index, array) {
var to = index + n - 1;
var subSeq, sum;
if (to < points.length) {
subSeq = array.slice(index, to + 1);
sum = subSeq.reduce(function(a,b) {
return [a[0] + b[0], a[1] + b[1]];
});
return sum.map(function(each) { return each / n; });
}
return undefined;
});
points = points.filter(function(each) { return typeof each !== 'undefined' })
// Note that one could re-interpolate the points
// to form a basis curve (I think...)
return points.join("L");
}
}
var movingAverageLine = d3.svg.line()
.x(function(d,i) { return x(i); })
.y(function(d,i) { return y(d); })
.interpolate(movingAvg(6));
以下行功能應該做你想要的。 公式基於http://en.wikipedia.org/wiki/Moving_average#Cumulative_moving_average 。
var _movingSum;
var movingAverageLine = d3.svg.line()
.x(function(d,i) { return x(i); })
.y(function(d,i) {
if (i == 0) {
return _movingSum = 0;
} else {
_movingSum += d;
}
return y(_movingSum / i);
})
.interpolate("basis");
不確定你的意思是“滾動平均值”,但是如果你想要一條顯示數據平均值的行,這是一種方法:
chart.append("svg:line")
.attr("x1", x(0))
.attr("x2", x(1))
.attr("y1", d3.mean(data))
.attr("y2", d3.mean(data))
.style('stroke', 'blue')
.style('stroke-width', 1)
你可以在這里看到jsfiddle: http : //jsfiddle.net/XXFrg/3/ 。 希望有所幫助,
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.