dir/include/smoothing.js

81 lines
2.6 KiB
JavaScript

(function(){
window.Smoothing = {
/**
* Applies both a moving average bracket and and exponential smoothing.
* @param {array} raw The raw Y values.
* @param {float} factor The exponential smoothing factor to apply (between o and 1).
* @param {int} bracket The amount of datapoints to add to the backet on each side! (2 = 5 data points)
* @return {array} The smoothed Y values.
*/
exponentialMovingAverage: function(raw, factor, bracket){
var output = [];
var smoother = new ExponentialSmoother(factor);
//Transform each data point with the smoother.
for (var i = 0; i < raw.length; i++){
var input = raw[i];
//See if we should bracket.
if(bracket > 0){
//Cap our start and end so it doesn't go out of bounds.
var start = Math.max(i-bracket, 0);
var end = Math.min(i+bracket, raw.length);
//Push the range to our input.
input = [];
for(var j = start; j < end; j++){
input.push(raw[j]);
}
}
output.push(
smoother.transform(input)
);
};
return output;
}
};
// Exponential Smoother class.
var ExponentialSmoother = function(factor){
this.currentValue = null;
this.smoothingFactor = factor || 1;
};
ExponentialSmoother.prototype.transform = function(input){
// In case our input is a bracket, first average it.
if(input.length){
var len = input.length;
var sum = 0;
for (var i = input.length - 1; i >= 0; i--)
sum += input[i]
input = sum/len;
}
// Start with our initial value.
if(this.currentValue === null){
this.currentValue = input;
}
// Our output is basically an updated value.
return this.currentValue =
// Weigh our current value with the smoothing factor.
(this.currentValue * this.smoothingFactor) +
// Add the input to it with the inverse value of the smoothing factor.
( (1-this.smoothingFactor) * input );
};
})();