UNPKG

@progress/kendo-charts

Version:

Kendo UI platform-independent Charts library

84 lines (69 loc) 2.52 kB
import { Matrix } from '../../common'; const MIN_ORDER = 1; const MAX_ORDER = 6; function calculatePolynomial(sourceValues, valueGetter, order) { let k = Math.min(Math.max(order || MIN_ORDER, MIN_ORDER), MAX_ORDER) + 1; let X = new Matrix(); let Y = new Matrix(); let count = 0; let xMin = Number.MAX_VALUE; let xMax = Number.MIN_VALUE; let valueMapper = x => x; let coefficients = []; for (let i = 0; i < sourceValues.length; i++) { const value = sourceValues[i]; let { xValue, yValue } = valueGetter(value); if (isFinite(xValue) && xValue !== null && isFinite(yValue) && yValue !== null) { xMin = Math.min(xValue, xMin); xMax = Math.max(xValue, xMax); count++; // Set Y value in matrix Y.set(i, 0, yValue); // Set indicator column to 1 for valid values X.set(i, 0, 1); X.set(i, 1, xValue); for (let pow = 2; pow <= k; pow++) { X.set(i, pow, Math.pow(X.get(i, 1), pow)); } } else { // Set indicator column to 0 for missing values X.set(i, 0, 0); } } // Limit order to number of values. X.width = Math.min(k, count); if (count > 0) { // Polynomial trendline equation: // y = aN * x^N + ... + a2 * x^2 + a1 * x + a0 coefficients = linearRegression(X, Y); valueMapper = x => coefficients.reduce((y, a, n) => y + a * Math.pow(x, n), 0); } return { coefficients, count, valueMapper, xMin, xMax }; } function linearRegression(X, Y) { const Xt = X.transpose(); const B = Xt.multiply(X).inverse().multiply(Xt).multiply(Y); // the last square estimate of the coefficients const coefficients = []; for (let i = 0; i < B.height; i++) { coefficients.push(B.get(i, 0)); } // y_intercept and regression coefficients ('slopes') return coefficients; // It's possible to calculate statistics for the regression based on // the LINEST function implementation in kendo-spreadsheet-common/src/calc.js // // * The standard errors (of coefficients and y-intercept) // * The coefficient of determination (R^2) // * The standard error for the y estimate // * The F statistic // * The degrees of freedom // * The regression sum of squares (SSR) // * The residual sum of squares (SSE) } export default calculatePolynomial;