Browse Source

Merge remote-tracking branch 'upstream/master'

Rashid Khan 12 years ago
parent
commit
822ef96a7e

+ 23 - 18
src/app/components/kbn.js

@@ -206,30 +206,35 @@ function($, _) {
     return str;
   };
 
+  kbn.interval_regex = /(\d+(?:\.\d+)?)([Mwdhmsy])/;
+
   // histogram & trends
-  kbn.interval_to_seconds = function(string) {
-    var matches = string.match(/(\d+(?:\.\d+)?)([Mwdhmsy])/);
-    switch (matches[2]) {
-    case 'y':
-      return matches[1]*31536000;
-    case 'M':
-      return matches[1]*2592000;
-    case 'w':
-      return matches[1]*604800;
-    case 'd':
-      return matches[1]*86400;
-    case 'h':
-      return matches[1]*3600;
-    case 'm':
-      return matches[1]*60;
-    case 's':
-      return matches[1];
+  var intervals_in_seconds = {
+    y: 31536000,
+    M: 2592000,
+    w: 604800,
+    d: 86400,
+    h: 3600,
+    m: 60,
+    s: 1
+  };
+
+  kbn.interval_to_ms = function(string) {
+    var matches = string.match(kbn.interval_regex);
+    if (!matches || !_.has(intervals_in_seconds, matches[2])) {
+      throw new Error('Invalid interval string, expexcting a number followed by one of "Mwdhmsy"');
+    } else {
+      return intervals_in_seconds[matches[2]] * matches[1] * 1000;
     }
   };
 
+  kbn.interval_to_seconds = function (string) {
+    return kbn.interval_to_ms(string)/1000;
+  };
+
   // This should go away, moment.js can do this
   kbn.time_ago = function(string) {
-    return new Date(new Date().getTime() - (kbn.interval_to_seconds(string)*1000));
+    return new Date(new Date().getTime() - (kbn.interval_to_ms(string)));
   };
 
   // LOL. hahahahaha. DIE.

+ 58 - 0
src/app/panels/histogram/interval.js

@@ -0,0 +1,58 @@
+define([
+  'kbn'
+],
+function (kbn) {
+  'use strict';
+
+  /**
+   * manages the interval logic
+   * @param {[type]} interval_string  An interval string in the format '1m', '1y', etc
+   */
+  function Interval(interval_string) {
+    this.string = interval_string;
+    this.ms = kbn.interval_to_ms(interval_string);
+
+    var matches = interval_string.match(kbn.interval_regex);
+    this.count = parseInt(matches[1], 10);
+    this.type = matches[2];
+
+    // does the length of the interval change based on the current time?
+    if (this.type === 'y' || this.type === 'M') {
+      // we will just modify this time object rather that create a new one constantly
+      this.get = this.get_complex;
+      this.date = new Date(0);
+    } else {
+      this.get = this.get_simple;
+    }
+  }
+
+  Interval.prototype = {
+    toString: function () {
+      return this.string;
+    },
+    after: function(current_ms) {
+      return this.get(current_ms, this.count);
+    },
+    before: function (current_ms) {
+      return this.get(current_ms, -this.count);
+    },
+    get_complex: function (current, delta) {
+      this.date.setTime(current);
+      switch(this.type) {
+      case 'M':
+        this.date.setUTCMonth(this.date.getUTCMonth() + delta);
+        break;
+      case 'y':
+        this.date.setUTCFullYear(this.date.getUTCFullYear() + delta);
+        break;
+      }
+      return this.date.getTime();
+    },
+    get_simple: function (current, delta) {
+      return current + (delta * this.ms);
+    }
+  };
+
+  return Interval;
+
+});

+ 7 - 3
src/app/panels/histogram/module.js

@@ -339,7 +339,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
           } catch(e) {return;}
 
           // Set barwidth based on specified interval
-          var barwidth = kbn.interval_to_seconds(scope.panel.interval)*1000;
+          var barwidth = kbn.interval_to_ms(scope.panel.interval);
 
           var stack = scope.panel.stack ? true : null;
 
@@ -401,9 +401,13 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
             // so that the stacking happens in the proper order
             var required_times = [];
             if (scope.data.length > 1) {
-              required_times = _.uniq(Array.prototype.concat.apply([], _.map(scope.data, function (query) {
+              required_times = Array.prototype.concat.apply([], _.map(scope.data, function (query) {
                 return query.time_series.getOrderedTimes();
-              })).sort(), true);
+              }));
+              required_times = _.uniq(required_times.sort(function (a, b) {
+                // decending numeric sort
+                return a-b;
+              }), true);
             }
 
             for (var i = 0; i < scope.data.length; i++) {

+ 15 - 9
src/app/panels/histogram/timeSeries.js

@@ -1,5 +1,8 @@
-define(['underscore', 'kbn'],
-function (_, kbn) {
+define([
+  'underscore',
+  './interval'
+],
+function (_, Interval) {
   'use strict';
 
   var ts = {};
@@ -39,7 +42,7 @@ function (_, kbn) {
     });
 
     // the expected differenece between readings.
-    this.interval_ms = base10Int(kbn.interval_to_seconds(opts.interval)) * 1000;
+    this.interval = new Interval(opts.interval);
 
     // will keep all values here, keyed by their time
     this._data = {};
@@ -75,7 +78,10 @@ function (_, kbn) {
     if (_.isArray(include)) {
       times = times.concat(include);
     }
-    return _.uniq(times.sort(), true);
+    return _.uniq(times.sort(function (a, b) {
+      // decending numeric sort
+      return a - b;
+    }), true);
   };
 
   /**
@@ -104,7 +110,7 @@ function (_, kbn) {
       this      // context
     );
 
-    // if the start and end of the pairs are inside either the start or end time,
+    // if the first or last pair is inside either the start or end time,
     // add those times to the series with null values so the graph will stretch to contain them.
     if (this.start_time && (pairs.length === 0 || pairs[0][0] > this.start_time)) {
       pairs.unshift([this.start_time, null]);
@@ -128,7 +134,7 @@ function (_, kbn) {
     // check for previous measurement
     if (i > 0) {
       prev = times[i - 1];
-      expected_prev = time - this.interval_ms;
+      expected_prev = this.interval.before(time);
       if (prev < expected_prev) {
         result.push([expected_prev, 0]);
       }
@@ -140,7 +146,7 @@ function (_, kbn) {
     // check for next measurement
     if (times.length > i) {
       next = times[i + 1];
-      expected_next = time + this.interval_ms;
+      expected_next = this.interval.after(time);
       if (next > expected_next) {
         result.push([expected_next, 0]);
       }
@@ -160,8 +166,8 @@ function (_, kbn) {
 
     result.push([ times[i], this._data[times[i]] || 0 ]);
     next = times[i + 1];
-    expected_next = times[i] + this.interval_ms;
-    for(; times.length > i && next > expected_next; expected_next+= this.interval_ms) {
+    expected_next = this.interval.after(time);
+    for(; times.length > i && next > expected_next; expected_next = this.interval.after(expected_next)) {
       result.push([expected_next, 0]);
     }
 

+ 2 - 2
src/app/panels/trends/module.js

@@ -80,8 +80,8 @@ function (angular, app, _, kbn) {
 
       $scope.time = filterSrv.timeRange('min');
       $scope.old_time = {
-        from : new Date($scope.time.from.getTime() - kbn.interval_to_seconds($scope.panel.ago)*1000),
-        to   : new Date($scope.time.to.getTime() - kbn.interval_to_seconds($scope.panel.ago)*1000)
+        from : new Date($scope.time.from.getTime() - kbn.interval_to_ms($scope.panel.ago)),
+        to   : new Date($scope.time.to.getTime() - kbn.interval_to_ms($scope.panel.ago))
       };
 
       var _segment = _.isUndefined(segment) ? 0 : segment;