Newer
Older
12001
12002
12003
12004
12005
12006
12007
12008
12009
12010
12011
12012
12013
12014
12015
12016
12017
12018
12019
12020
12021
12022
12023
12024
12025
12026
12027
12028
12029
12030
12031
12032
12033
12034
12035
12036
12037
12038
12039
12040
12041
12042
12043
12044
12045
12046
12047
12048
12049
12050
12051
12052
12053
12054
12055
12056
12057
12058
12059
12060
12061
12062
12063
12064
12065
12066
12067
12068
12069
12070
12071
12072
12073
12074
12075
12076
12077
12078
12079
12080
12081
12082
12083
12084
12085
12086
12087
12088
12089
12090
12091
12092
12093
12094
12095
12096
12097
12098
12099
12100
12101
12102
12103
12104
12105
12106
12107
12108
12109
12110
12111
12112
12113
12114
12115
12116
12117
12118
12119
12120
12121
12122
12123
12124
12125
12126
12127
12128
12129
12130
12131
12132
12133
12134
12135
12136
12137
12138
12139
12140
12141
12142
12143
12144
12145
12146
12147
12148
12149
12150
12151
12152
12153
12154
12155
12156
12157
12158
12159
12160
12161
12162
12163
12164
12165
12166
12167
12168
12169
12170
12171
12172
// Extract to the unified data format.
if (point !== null) {
y = point[0];
if (y !== null && !isNaN(y)) {
variance = sigma * point[1];
// preserve original error value in extras for further
// filtering
series.push([ x, y, [ y - variance, y + variance, point[1] ] ]);
} else {
series.push([ x, y, [ y, y, y ] ]);
}
} else {
series.push([ x, null, [ null, null, null ] ]);
}
}
return series;
};
/** @inheritDoc */
ErrorBarsHandler.prototype.rollingAverage =
function(originalData, rollPeriod, options) {
rollPeriod = Math.min(rollPeriod, originalData.length);
var rollingData = [];
var sigma = options.get("sigma");
var i, j, y, v, sum, num_ok, stddev, variance, value;
// Calculate the rolling average for the first rollPeriod - 1 points
// where there is not enough data to roll over the full number of points
for (i = 0; i < originalData.length; i++) {
sum = 0;
variance = 0;
num_ok = 0;
for (j = Math.max(0, i - rollPeriod + 1); j < i + 1; j++) {
y = originalData[j][1];
if (y === null || isNaN(y))
continue;
num_ok++;
sum += y;
variance += Math.pow(originalData[j][2][2], 2);
}
if (num_ok) {
stddev = Math.sqrt(variance) / num_ok;
value = sum / num_ok;
rollingData[i] = [ originalData[i][0], value,
[value - sigma * stddev, value + sigma * stddev] ];
} else {
// This explicitly preserves NaNs to aid with "independent
// series".
// See testRollingAveragePreservesNaNs.
v = (rollPeriod == 1) ? originalData[i][1] : null;
rollingData[i] = [ originalData[i][0], v, [ v, v ] ];
}
}
return rollingData;
};
})();
/**
* @license
* Copyright 2013 David Eberlein (david.eberlein@ch.sauter-bc.com)
* MIT-licensed (http://opensource.org/licenses/MIT)
*/
/**
* @fileoverview DataHandler implementation for the combination
* of error bars and fractions options.
* @author David Eberlein (david.eberlein@ch.sauter-bc.com)
*/
(function() {
/*global Dygraph:false */
"use strict";
/**
* @constructor
* @extends Dygraph.DataHandlers.BarsHandler
*/
Dygraph.DataHandlers.FractionsBarsHandler = function() {
};
var FractionsBarsHandler = Dygraph.DataHandlers.FractionsBarsHandler;
FractionsBarsHandler.prototype = new Dygraph.DataHandlers.BarsHandler();
/** @inheritDoc */
FractionsBarsHandler.prototype.extractSeries = function(rawData, i, options) {
// TODO(danvk): pre-allocate series here.
var series = [];
var x, y, point, num, den, value, stddev, variance;
var mult = 100.0;
var sigma = options.get("sigma");
var logScale = options.get('logscale');
for ( var j = 0; j < rawData.length; j++) {
x = rawData[j][0];
point = rawData[j][i];
if (logScale && point !== null) {
// On the log scale, points less than zero do not exist.
// This will create a gap in the chart.
if (point[0] <= 0 || point[1] <= 0) {
point = null;
}
}
// Extract to the unified data format.
if (point !== null) {
num = point[0];
den = point[1];
if (num !== null && !isNaN(num)) {
value = den ? num / den : 0.0;
stddev = den ? sigma * Math.sqrt(value * (1 - value) / den) : 1.0;
variance = mult * stddev;
y = mult * value;
// preserve original values in extras for further filtering
series.push([ x, y, [ y - variance, y + variance, num, den ] ]);
} else {
series.push([ x, num, [ num, num, num, den ] ]);
}
} else {
series.push([ x, null, [ null, null, null, null ] ]);
}
}
return series;
};
/** @inheritDoc */
FractionsBarsHandler.prototype.rollingAverage =
function(originalData, rollPeriod, options) {
rollPeriod = Math.min(rollPeriod, originalData.length);
var rollingData = [];
var sigma = options.get("sigma");
var wilsonInterval = options.get("wilsonInterval");
var low, high, i, stddev;
var num = 0;
var den = 0; // numerator/denominator
var mult = 100.0;
for (i = 0; i < originalData.length; i++) {
num += originalData[i][2][2];
den += originalData[i][2][3];
if (i - rollPeriod >= 0) {
num -= originalData[i - rollPeriod][2][2];
den -= originalData[i - rollPeriod][2][3];
}
var date = originalData[i][0];
var value = den ? num / den : 0.0;
if (wilsonInterval) {
// For more details on this confidence interval, see:
// http://en.wikipedia.org/wiki/Binomial_confidence_interval
if (den) {
var p = value < 0 ? 0 : value, n = den;
var pm = sigma * Math.sqrt(p * (1 - p) / n + sigma * sigma / (4 * n * n));
var denom = 1 + sigma * sigma / den;
low = (p + sigma * sigma / (2 * den) - pm) / denom;
high = (p + sigma * sigma / (2 * den) + pm) / denom;
rollingData[i] = [ date, p * mult,
[ low * mult, high * mult ] ];
} else {
rollingData[i] = [ date, 0, [ 0, 0 ] ];
}
} else {
stddev = den ? sigma * Math.sqrt(value * (1 - value) / den) : 1.0;
rollingData[i] = [ date, mult * value,
[ mult * (value - stddev), mult * (value + stddev) ] ];
}
}
return rollingData;
};
})();