-
-/**
- * Calculates the rolling average of a data set.
- * If originalData is [label, val], rolls the average of those.
- * If originalData is [label, [, it's interpreted as [value, stddev]
- * and the roll is returned in the same form, with appropriately reduced
- * stddev for each value.
- * Note that this is where fractional input (i.e. '5/10') is converted into
- * decimal values.
- * @param {Array} originalData The data in the appropriate format (see above)
- * @param {Number} rollPeriod The number of days over which to average the data
- */
-DateGraph.prototype.rollingAverage = function(originalData, rollPeriod) {
- if (originalData.length < 2)
- return originalData;
- var rollPeriod = Math.min(rollPeriod, originalData.length - 1);
- var rollingData = [];
- var sigma = this.sigma_;
-
- if (this.fractions_) {
- var num = 0;
- var den = 0; // numerator/denominator
- var mult = 100.0;
- for (var i = 0; i < originalData.length; i++) {
- num += originalData[i][1][0];
- den += originalData[i][1][1];
- if (i - rollPeriod >= 0) {
- num -= originalData[i - rollPeriod][1][0];
- den -= originalData[i - rollPeriod][1][1];
- }
-
- var date = originalData[i][0];
- var value = den ? num / den : 0.0;
- if (this.errorBars_) {
- if (this.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;
- var low = (p + sigma * sigma / (2 * den) - pm) / denom;
- var high = (p + sigma * sigma / (2 * den) + pm) / denom;
- rollingData[i] = [date,
- [p * mult, (p - low) * mult, (high - p) * mult]];
- } else {
- rollingData[i] = [date, [0, 0, 0]];
- }
- } else {
- var stddev = den ? sigma * Math.sqrt(value * (1 - value) / den) : 1.0;
- rollingData[i] = [date, [mult * value, mult * stddev, mult * stddev]];
- }
- } else {
- rollingData[i] = [date, mult * value];
- }
- }
- } else if (this.customBars_) {
- // just ignore the rolling for now.
- // TODO(danvk): do something reasonable.
- for (var i = 0; i < originalData.length; i++) {
- var data = originalData[i][1];
- var y = data[1];
- rollingData[i] = [originalData[i][0], [y, y - data[0], data[2] - y]];
- }
- } else {
- // Calculate the rolling average for the first rollPeriod - 1 points where
- // there is not enough data to roll over the full number of days
- var num_init_points = Math.min(rollPeriod - 1, originalData.length - 2);
- if (!this.errorBars_){
- for (var i = 0; i < num_init_points; i++) {
- var sum = 0;
- for (var j = 0; j < i + 1; j++)
- sum += originalData[j][1];
- rollingData[i] = [originalData[i][0], sum / (i + 1)];
- }
- // Calculate the rolling average for the remaining points
- for (var i = Math.min(rollPeriod - 1, originalData.length - 2);
- i < originalData.length;
- i++) {
- var sum = 0;
- for (var j = i - rollPeriod + 1; j < i + 1; j++)
- sum += originalData[j][1];
- rollingData[i] = [originalData[i][0], sum / rollPeriod];
- }
- } else {
- for (var i = 0; i < num_init_points; i++) {
- var sum = 0;
- var variance = 0;
- for (var j = 0; j < i + 1; j++) {
- sum += originalData[j][1][0];
- variance += Math.pow(originalData[j][1][1], 2);
- }
- var stddev = Math.sqrt(variance)/(i+1);
- rollingData[i] = [originalData[i][0],
- [sum/(i+1), sigma * stddev, sigma * stddev]];
- }
- // Calculate the rolling average for the remaining points
- for (var i = Math.min(rollPeriod - 1, originalData.length - 2);
- i < originalData.length;
- i++) {
- var sum = 0;
- var variance = 0;
- for (var j = i - rollPeriod + 1; j < i + 1; j++) {
- sum += originalData[j][1][0];
- variance += Math.pow(originalData[j][1][1], 2);
- }
- var stddev = Math.sqrt(variance) / rollPeriod;
- rollingData[i] = [originalData[i][0],
- [sum / rollPeriod, sigma * stddev, sigma * stddev]];
- }
- }
- }
-
- return rollingData;
+DateGraph.prototype.drawGraph_=function(data){
+var maxY=null;
+this.layout_.removeAllDatasets();
+for(var i=1;i<data[0].length;i++){
+var _155=[];
+for(var j=0;j<data.length;j++){
+var date=data[j][0];
+_155[j]=[date,data[j][i]];
+}
+_155=this.rollingAverage(_155,this.rollPeriod_);
+var bars=this.errorBars_||this.customBars_;
+if(this.dateWindow_){
+var low=this.dateWindow_[0];
+var high=this.dateWindow_[1];
+var _159=[];
+for(var k=0;k<_155.length;k++){
+if(_155[k][0]>=low&&_155[k][0]<=high){
+_159.push(_155[k]);
+var y=bars?_155[k][1][0]:_155[k][1];
+if(maxY==null||y>maxY){
+maxY=y;
+}
+}
+}
+_155=_159;
+}else{
+for(var j=0;j<_155.length;j++){
+var y=bars?_155[j][1][0]:_155[j][1];
+if(maxY==null||y>maxY){
+maxY=bars?y+_155[j][1][1]:y;
+}
+}
+}
+if(bars){
+var vals=[];
+for(var j=0;j<_155.length;j++){
+vals[j]=[_155[j][0],_155[j][1][0],_155[j][1][1],_155[j][1][2]];
+}
+this.layout_.addDataset(this.labels_[i-1],vals);
+}else{
+this.layout_.addDataset(this.labels_[i-1],_155);
+}
+}
+if(this.valueRange_!=null){
+this.addYTicks_(this.valueRange_[0],this.valueRange_[1]);
+}else{
+maxY*=1.1;
+if(maxY<=0){
+maxY=1;
+}else{
+var _161=Math.pow(10,Math.floor(Math.log(maxY)/Math.log(10)));
+maxY=_161*Math.ceil(maxY/_161);
+}
+this.addYTicks_(0,maxY);
+}
+this.addXTicks_();
+this.layout_.evaluateWithError();
+this.plotter_.clear();
+this.plotter_.render();
+this.canvas_.getContext("2d").clearRect(0,0,this.canvas_.width,this.canvas_.height);
+};
+DateGraph.prototype.rollingAverage=function(_162,_163){
+if(_162.length<2){
+return _162;
+}
+var _163=Math.min(_163,_162.length-1);
+var _164=[];
+var _165=this.sigma_;
+if(this.fractions_){
+var num=0;
+var den=0;
+var mult=100;
+for(var i=0;i<_162.length;i++){
+num+=_162[i][1][0];
+den+=_162[i][1][1];
+if(i-_163>=0){
+num-=_162[i-_163][1][0];
+den-=_162[i-_163][1][1];
+}
+var date=_162[i][0];
+var _168=den?num/den:0;
+if(this.errorBars_){
+if(this.wilsonInterval_){
+if(den){
+var p=_168<0?0:_168,n=den;
+var pm=_165*Math.sqrt(p*(1-p)/n+_165*_165/(4*n*n));
+var _171=1+_165*_165/den;
+var low=(p+_165*_165/(2*den)-pm)/_171;
+var high=(p+_165*_165/(2*den)+pm)/_171;
+_164[i]=[date,[p*mult,(p-low)*mult,(high-p)*mult]];
+}else{
+_164[i]=[date,[0,0,0]];
+}
+}else{
+var _172=den?_165*Math.sqrt(_168*(1-_168)/den):1;
+_164[i]=[date,[mult*_168,mult*_172,mult*_172]];
+}
+}else{
+_164[i]=[date,mult*_168];
+}
+}
+}else{
+if(this.customBars_){
+var low=0;
+var mid=0;
+var high=0;
+var _174=0;
+for(var i=0;i<_162.length;i++){
+var data=_162[i][1];
+var y=data[1];
+_164[i]=[_162[i][0],[y,y-data[0],data[2]-y]];
+low+=data[0];
+mid+=y;
+high+=data[2];
+_174+=1;
+if(i-_163>=0){
+var prev=_162[i-_163];
+low-=prev[1][0];
+mid-=prev[1][1];
+high-=prev[1][2];
+_174-=1;
+}
+_164[i]=[_162[i][0],[1*mid/_174,1*(mid-low)/_174,1*(high-mid)/_174]];
+}
+}else{
+var _176=Math.min(_163-1,_162.length-2);
+if(!this.errorBars_){
+for(var i=0;i<_176;i++){
+var sum=0;
+for(var j=0;j<i+1;j++){
+sum+=_162[j][1];
+}
+_164[i]=[_162[i][0],sum/(i+1)];
+}
+for(var i=Math.min(_163-1,_162.length-2);i<_162.length;i++){
+var sum=0;
+for(var j=i-_163+1;j<i+1;j++){
+sum+=_162[j][1];
+}
+_164[i]=[_162[i][0],sum/_163];
+}
+}else{
+for(var i=0;i<_176;i++){
+var sum=0;
+var _178=0;
+for(var j=0;j<i+1;j++){
+sum+=_162[j][1][0];
+_178+=Math.pow(_162[j][1][1],2);
+}
+var _172=Math.sqrt(_178)/(i+1);
+_164[i]=[_162[i][0],[sum/(i+1),_165*_172,_165*_172]];
+}
+for(var i=Math.min(_163-1,_162.length-2);i<_162.length;i++){
+var sum=0;
+var _178=0;
+for(var j=i-_163+1;j<i+1;j++){
+sum+=_162[j][1][0];
+_178+=Math.pow(_162[j][1][1],2);
+}
+var _172=Math.sqrt(_178)/_163;
+_164[i]=[_162[i][0],[sum/_163,_165*_172,_165*_172]];
+}
+}
+}
+}
+return _164;