I am currently in the process of migrating a project from Angular 1 to Angular 2. One of the key components is a chart that displays a moving average line, which requires the use of a circular queue with prototype methods like add, remove, and getAverage.
Here is the existing code written in Angular 1 JavaScript that needs to be converted to TypeScript:
Is there a way to import and call JavaScript functions from TypeScript?
Alternatively, is there a tool available to convert JavaScript to TypeScript seamlessly?
Any assistance would be greatly appreciated.
'use strict';
angular.module('testeApp.testChart')
.service('testRollingAverageSrc', function(){
this.performRollingAverage = RollingAverage;
function RollingAverage() {
if (!(this instanceof RollingAverage)) {
// multiple conditions need to be checked to properly emulate Array
if (arguments.length > 1 || typeof arguments[0] !== 'number') {
return RollingAverage.apply(new RollingAverage(arguments.length), arguments);
} else {
return new RollingAverage(arguments[0]);
}
}
// if no arguments, then nothing needs to be set
if (arguments.length === 0)
throw new Error('Missing Argument: You must pass a valid buffer length');
// this is the same in either scenario
this.size = this.start = this.end = 0;
this.overflow = null;
this.totalSum =0.0;
// emulate Array based on passed arguments
if (arguments.length > 1 || typeof arguments[0] !== 'number') {
this.data = new Array(arguments.length);
this.end = (this.length = arguments.length) - 1;
this.push.apply(this, arguments);
} else {
this.data = new Array(arguments[0]);
this.end = (this.length = arguments[0]) - 1;
}
return this;
}
RollingAverage.prototype = {
remove : function () {
var item;
if (this.size === 0) return;
item = this.data[this.end];
// remove the reference to the object so it can be garbage collected
if( !isNaN(this.data[this.end]) )
this.totalSum -= this.data[this.end];
delete this.data[this.end];
this.end = ((this.end - 1 + this.length) % this.length);
this.size--;
return item;
},
add : function () {
var i = 0;
// check if overflow is set, and if data is about to be overwritten
if (this.overflow && this.size + arguments.length > this.length) {
// call overflow function and send data that's about to be overwritten
for (; i < this.size + arguments.length - this.length; i++) {
this.overflow(this.data[(this.end + i + 1) % this.length], this);
}
}
// push items to the end, wrapping and erasing existing items
// using arguments variable directly to reduce gc footprint
for (i = 0; i < arguments.length; i++) {
// reduce the totalSum by the removed value
var value = this.data[(this.end + i + 1) % this.length];
if( !isNaN(value) )
this.totalSum -= value;
// save the new value
this.data[(this.end + i + 1) % this.length] = arguments[i];
// update totalSum
if( !isNaN((arguments[i])) )
this.totalSum += arguments[i];
}
// recalculate size
if (this.size < this.length) {
if (this.size + i > this.length) this.size = this.length;
else this.size += i;
}
// recalculate end
this.end = ((this.end + i) % this.length);
// recalculate start
this.start = (this.length + this.end - this.size + 1) % this.length;
return this.size;
},
avg : function () {
return this.size == 0 ? 0 : this.totalSum / this.size;
}
};
});