scichart
Version:
Fast WebGL JavaScript Charting Library and Framework
201 lines (200 loc) • 8.58 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.XyMovingAverageFilter = void 0;
var DataFilterType_1 = require("../../../types/DataFilterType");
var XyFilterBase_1 = require("./XyFilterBase");
var vectorToArray_1 = require("../../../utils/vectorToArray");
/**
* An XyDataSeries that is the moving average of the original series
*/
var XyMovingAverageFilter = /** @class */ (function (_super) {
__extends(XyMovingAverageFilter, _super);
function XyMovingAverageFilter(originalSeries, options) {
var _this = this;
var _a;
_this = _super.call(this, originalSeries, options) || this;
_this.lengthProperty = 30;
_this.lengthProperty = (_a = options === null || options === void 0 ? void 0 : options.length) !== null && _a !== void 0 ? _a : _this.lengthProperty;
if (!originalSeries.dataDistributionCalculator.isSortedAscending) {
throw new Error("XyMovingAverageFilter requires original data to be sorted in X");
}
if (_this.getOriginalCount() > 0) {
_this.calculate(0);
}
return _this;
}
Object.defineProperty(XyMovingAverageFilter.prototype, "length", {
/**
* Gets or Sets the length of the moving average
*/
get: function () {
return this.lengthProperty;
},
/**
* Gets or Sets the length of the moving average
*/
set: function (value) {
this.lengthProperty = value;
this.calculate(0);
},
enumerable: false,
configurable: true
});
// @ts-ignore
XyMovingAverageFilter.prototype.toJSON = function (excludeData) {
if (excludeData === void 0) { excludeData = false; }
var json = _super.prototype.toJSON.call(this, excludeData);
var options = json.options;
if (!excludeData) {
options.xValues = (0, vectorToArray_1.vectorToArray)(this.getOriginalXValues(), this.webAssemblyContext);
options.yValues = (0, vectorToArray_1.vectorToArray)(this.getOriginalYValues(), this.webAssemblyContext);
}
options.filter = {
type: DataFilterType_1.EDataFilterType.XyMovingAverage,
options: { field: this.field, xField: this.xField, length: this.length }
};
return __assign(__assign({}, json), { options: options });
};
XyMovingAverageFilter.prototype.onOriginalPropertyChanged = function (name) { };
XyMovingAverageFilter.prototype.filterOnAppend = function (count) {
this.calculate(this.count());
};
XyMovingAverageFilter.prototype.filterOnUpdate = function (index) {
var y = this.getOriginalYValues().get(index) || 0;
this.calculateUpdate(index, y);
};
XyMovingAverageFilter.prototype.filterOnInsert = function (startIndex, count) {
this.calculate(startIndex);
};
XyMovingAverageFilter.prototype.filterOnRemove = function (startIndex, count) {
this.calculate(startIndex);
};
XyMovingAverageFilter.prototype.filterAll = function () {
this.calculate(0);
};
XyMovingAverageFilter.prototype.calculateUpdate = function (index, y) {
if (index < this.count() - 1) {
this.calculate(index);
}
else {
if (index >= this.length - 1) {
// Just update latest
var bufferTotal = 0;
var yValuesView = (0, vectorToArray_1.vectorToArrayViewF64)(this.getOriginalYValues(), this.webAssemblyContext);
for (var i = index - (this.length - 1); i <= index; i++) {
bufferTotal += yValuesView[i];
}
this.update(index, bufferTotal / this.length);
}
}
};
XyMovingAverageFilter.prototype.calculate = function (start) {
var originalStart = start;
var xValuesView = (0, vectorToArray_1.vectorToArrayViewF64)(this.getOriginalXValues(), this.webAssemblyContext);
var yValuesView = (0, vectorToArray_1.vectorToArrayViewF64)(this.getOriginalYValues(), this.webAssemblyContext);
var bufferTotal = 0;
if (start < this.count()) {
if (start === 0) {
this.clear();
}
else {
this.removeRange(start, this.count() - start);
}
}
var s = Math.max(0, start - this.length);
for (var i = s; i < start; i++) {
bufferTotal += yValuesView[i] || 0;
}
var originalCount = this.getOriginalCount();
var newX = [];
var newY = [];
if (this.originalSeries.dataDistributionCalculator.containsNaN) {
// Nan checks here add about 5%
for (var i = start; i < originalCount; i++) {
var x = xValuesView[i];
var y = yValuesView[i] || 0;
newX.push(x);
if (i > this.length - 1) {
var startPointer = i - this.length;
var oldY = yValuesView[startPointer] || 0;
bufferTotal = bufferTotal + y - oldY;
newY.push(bufferTotal / this.length);
}
else if (i === this.length - 1) {
bufferTotal = bufferTotal + y;
newY.push(bufferTotal / this.length);
}
else {
bufferTotal = bufferTotal + y;
newY.push(NaN);
}
}
}
else {
for (var i = start; i < originalCount; i++) {
var x = xValuesView[i];
var y = yValuesView[i];
newX.push(x);
if (i > this.length - 1) {
var startPointer = i - this.length;
var oldY = yValuesView[startPointer];
bufferTotal = bufferTotal + y - oldY;
newY.push(bufferTotal / this.length);
}
else if (i === this.length - 1) {
bufferTotal = bufferTotal + y;
newY.push(bufferTotal / this.length);
}
else {
bufferTotal = bufferTotal + y;
newY.push(NaN);
}
}
}
this.appendRange(newX, newY);
// old
// const rawX = this.getOriginalXValues();
// const rawY = this.getOriginalYValues();
// for (let i = start; i < this.getOriginalCount(); i++) {
// const x = rawX.get(i) || 0;
// const y = rawY.get(i) || 0;
// i = (i + 1) % this.length;
// const oldY = this.buffer[i];
// this.buffer[i] = y;
// bufferTotal = bufferTotal + y - (oldY ?? 0);
// if (this.buffer.length === this.length) {
// this.append(x, bufferTotal / this.length);
// } else if (originalStart < this.length) {
// this.append(x, NaN);
// }
// }
};
return XyMovingAverageFilter;
}(XyFilterBase_1.XyFilterBase));
exports.XyMovingAverageFilter = XyMovingAverageFilter;