因此,目前可在以下位置获得的脚本://rawgithub.com/phpepe/highcharts-regression/master/highcharts-regression.js计算串行完整数据集的线性回归。是否可以修改此值以基于范围内的数据计算线性回归。即1个月线性回归,3个月线性回归...
function _linear(data, decimalPlaces, extrapolate) {
var sum = [0, 0, 0, 0, 0], n = 0, results = [], N = data.length;
for (; n < data.length; n++) {
if (data[n]['x'] != null) {
data[n][0] = data[n].x;
data[n][1] = data[n].y;
}
if (data[n][1] != null) {
sum[0] += data[n][0]; //Σ(X)
sum[1] += data[n][1]; //Σ(Y)
sum[2] += data[n][0] * data[n][0]; //Σ(X^2)
sum[3] += data[n][0] * data[n][1]; //Σ(XY)
sum[4] += data[n][1] * data[n][1]; //Σ(Y^2)
} else {
N -= 1;
}
}
我可以看到它正在计算完整data.length的线性回归。如何将数据长度设置在所选范围内。我想要每条回归线而不是一条回归线。
见jsfiddle:http://jsfiddle.net/x0pya5gt/
highcharts-regression默认情况下没有此功能。您可以更改regression.js并添加此功能。您应首先下载代码(显然)并将其放在某处并将该文件包含在您的代码中。那你应该像这样改变processSerie函数:
var processSerie = function (s, method, chart) {
if (s.regression && !s.rendered) {
s.regressionSettings = s.regressionSettings || {};
s.regressionSettings.tooltip = s.regressionSettings.tooltip || {};
s.regressionSettings.dashStyle = s.regressionSettings.dashStyle || 'solid';
s.regressionSettings.decimalPlaces = s.regressionSettings.decimalPlaces || 2;
s.regressionSettings.useAllSeries = s.regressionSettings.useAllSeries || false;
s.regressionSettings.selectedRange = s.regressionSettings.selectedRange || []; // Add selectedRange for passing the range to regression.
var regressionType = s.regressionSettings.type || "linear";
var regression;
var extraSerie = {
data: [],
color: s.regressionSettings.color || '',
yAxis: s.yAxis,
lineWidth: s.regressionSettings.lineWidth || 2,
marker: {enabled: false},
isRegressionLine: true,
visible: s.regressionSettings.visible,
type: s.regressionSettings.linetype || 'spline',
name: s.regressionSettings.name || "Equation: %eq",
id: s.regressionSettings.id,
dashStyle: s.regressionSettings.dashStyle || 'solid',
showInLegend: !s.regressionSettings.hideInLegend,
tooltip: {
valueSuffix: s.regressionSettings.tooltip.valueSuffix || ' '
}
};
if (typeof s.regressionSettings.index !== 'undefined') {
extraSerie.index = s.regressionSettings.index;
}
if (typeof s.regressionSettings.legendIndex !== 'undefined') {
extraSerie.legendIndex = s.regressionSettings.legendIndex;
}
var mergedData = s.data;
if (s.regressionSettings.useAllSeries) {
mergedData = [];
for (di = 0; di < series.length; di++) {
var seriesToMerge = series[di];
mergedData = mergedData.concat(seriesToMerge.data);
}
}
if (regressionType == "linear") {
var extrapolate = s.regressionSettings.extrapolate || 0;
regression = _linear(mergedData, s.regressionSettings.decimalPlaces, extrapolate, s.regressionSettings.selectedRange); // Here you add selectedRange parameter for _linear function
extraSerie.type = "line";
} else if (regressionType == "exponential") {
var extrapolate = s.regressionSettings.extrapolate || 0;
regression = _exponential(mergedData, extrapolate);
}
else if (regressionType == "polynomial") {
var order = s.regressionSettings.order || 2;
var extrapolate = s.regressionSettings.extrapolate || 0;
regression = _polynomial(mergedData, order, extrapolate);
} else if (regressionType == "power") {
var extrapolate = s.regressionSettings.extrapolate || 0;
regression = _power(mergedData, extrapolate);
} else if (regressionType == "logarithmic") {
var extrapolate = s.regressionSettings.extrapolate || 0;
regression = _logarithmic(mergedData, extrapolate);
} else if (regressionType == "loess") {
var loessSmooth = s.regressionSettings.loessSmooth || 25;
regression = _loess(mergedData, loessSmooth / 100);
} else {
console.error("Invalid regression type: ", regressionType);
return;
}
regression.rSquared = coefficientOfDetermination(mergedData, regression.points);
regression.rValue = _round(Math.sqrt(regression.rSquared), s.regressionSettings.decimalPlaces);
regression.rSquared = _round(regression.rSquared, s.regressionSettings.decimalPlaces);
regression.standardError = _round(standardError(mergedData, regression.points), s.regressionSettings.decimalPlaces);
extraSerie.data = regression.points;
extraSerie.name = extraSerie.name.replace("%r2", regression.rSquared);
extraSerie.name = extraSerie.name.replace("%r", regression.rValue);
extraSerie.name = extraSerie.name.replace("%eq", regression.string);
extraSerie.name = extraSerie.name.replace("%se", regression.standardError);
if (extraSerie.visible === false) {
extraSerie.visible = false;
}
extraSerie.regressionOutputs = regression;
return extraSerie;
}
}
考虑添加的行:
s.regressionSettings.selectedRange = s.regressionSettings.selectedRange || []; // Add selectedRange for passing the range to regression.
这条线改变了:
regression = _linear(mergedData, s.regressionSettings.decimalPlaces, extrapolate, s.regressionSettings.selectedRange); // Here you add selectedRange parameter for _linear function
然后在_linear函数中,您应该添加以下更改:
function _linear(data, decimalPlaces, extrapolate, selectedRange) {
var sum = [0, 0, 0, 0, 0], n = 0, i = 0, results = [], N = data.length;
for (; i < data.length; i++) {
if (selectedRange.length == 2)
if (i < selectedRange[0] || i > selectedRange[1])
continue;
if (data[n]['x'] != null) {
data[n][0] = data[n].x;
data[n][1] = data[n].y;
}
if (data[n][1] != null) {
sum[0] += data[n][0]; //Σ(X)
sum[1] += data[n][1]; //Σ(Y)
sum[2] += data[n][0] * data[n][0]; //Σ(X^2)
sum[3] += data[n][0] * data[n][1]; //Σ(XY)
sum[4] += data[n][1] * data[n][1]; //Σ(Y^2)
} else {
N -= 1;
}
的n ++; }
再次考虑将selectedRange添加到函数参数和下面添加的行:
if (selectedRange.length == 2)
if (i < selectedRange[0] || i > selectedRange[1])
continue;
和i = 0
和n++
。
最后要使用它,您可以在您在系列中使用的regressionSetting对象中传递selectedRange属性。