Commit 1afec73f by spenceralger

Merge pull request #468 from spenceralger/numeric-sort

Fixes for #466
parents 8a142d91 6e728480
...@@ -208,30 +208,35 @@ function($, _) { ...@@ -208,30 +208,35 @@ function($, _) {
return str; return str;
}; };
kbn.interval_regex = /(\d+(?:\.\d+)?)([Mwdhmsy])/;
// histogram & trends // histogram & trends
kbn.interval_to_seconds = function(string) { var intervals_in_seconds = {
var matches = string.match(/(\d+(?:\.\d+)?)([Mwdhmsy])/); y: 31536000,
switch (matches[2]) { M: 2592000,
case 'y': w: 604800,
return matches[1]*31536000; d: 86400,
case 'M': h: 3600,
return matches[1]*2592000; m: 60,
case 'w': s: 1
return matches[1]*604800; };
case 'd':
return matches[1]*86400; kbn.interval_to_ms = function(string) {
case 'h': var matches = string.match(kbn.interval_regex);
return matches[1]*3600; if (!matches || !_.has(intervals_in_seconds, matches[2])) {
case 'm': throw new Error('Invalid interval string, expexcting a number followed by one of "Mwdhmsy"');
return matches[1]*60; } else {
case 's': return intervals_in_seconds[matches[2]] * matches[1] * 1000;
return matches[1];
} }
}; };
kbn.interval_to_seconds = function (string) {
return kbn.interval_to_ms(string)/1000;
};
// This should go away, moment.js can do this // This should go away, moment.js can do this
kbn.time_ago = function(string) { 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. // LOL. hahahahaha. DIE.
......
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;
});
\ No newline at end of file
...@@ -339,7 +339,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) { ...@@ -339,7 +339,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
} catch(e) {return;} } catch(e) {return;}
// Set barwidth based on specified interval // 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; var stack = scope.panel.stack ? true : null;
...@@ -401,9 +401,13 @@ function (angular, app, $, _, kbn, moment, timeSeries) { ...@@ -401,9 +401,13 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
// so that the stacking happens in the proper order // so that the stacking happens in the proper order
var required_times = []; var required_times = [];
if (scope.data.length > 1) { 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(); 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++) { for (var i = 0; i < scope.data.length; i++) {
......
define(['underscore', 'kbn'], define([
function (_, kbn) { 'underscore',
'./interval'
],
function (_, Interval) {
'use strict'; 'use strict';
var ts = {}; var ts = {};
...@@ -39,7 +42,7 @@ function (_, kbn) { ...@@ -39,7 +42,7 @@ function (_, kbn) {
}); });
// the expected differenece between readings. // 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 // will keep all values here, keyed by their time
this._data = {}; this._data = {};
...@@ -75,7 +78,10 @@ function (_, kbn) { ...@@ -75,7 +78,10 @@ function (_, kbn) {
if (_.isArray(include)) { if (_.isArray(include)) {
times = times.concat(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) { ...@@ -104,7 +110,7 @@ function (_, kbn) {
this // context 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. // 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)) { if (this.start_time && (pairs.length === 0 || pairs[0][0] > this.start_time)) {
pairs.unshift([this.start_time, null]); pairs.unshift([this.start_time, null]);
...@@ -128,7 +134,7 @@ function (_, kbn) { ...@@ -128,7 +134,7 @@ function (_, kbn) {
// check for previous measurement // check for previous measurement
if (i > 0) { if (i > 0) {
prev = times[i - 1]; prev = times[i - 1];
expected_prev = time - this.interval_ms; expected_prev = this.interval.before(time);
if (prev < expected_prev) { if (prev < expected_prev) {
result.push([expected_prev, 0]); result.push([expected_prev, 0]);
} }
...@@ -140,7 +146,7 @@ function (_, kbn) { ...@@ -140,7 +146,7 @@ function (_, kbn) {
// check for next measurement // check for next measurement
if (times.length > i) { if (times.length > i) {
next = times[i + 1]; next = times[i + 1];
expected_next = time + this.interval_ms; expected_next = this.interval.after(time);
if (next > expected_next) { if (next > expected_next) {
result.push([expected_next, 0]); result.push([expected_next, 0]);
} }
...@@ -160,8 +166,8 @@ function (_, kbn) { ...@@ -160,8 +166,8 @@ function (_, kbn) {
result.push([ times[i], this._data[times[i]] || 0 ]); result.push([ times[i], this._data[times[i]] || 0 ]);
next = times[i + 1]; next = times[i + 1];
expected_next = times[i] + this.interval_ms; expected_next = this.interval.after(time);
for(; times.length > i && next > expected_next; expected_next+= this.interval_ms) { for(; times.length > i && next > expected_next; expected_next = this.interval.after(expected_next)) {
result.push([expected_next, 0]); result.push([expected_next, 0]);
} }
......
...@@ -80,8 +80,8 @@ function (angular, app, _, kbn) { ...@@ -80,8 +80,8 @@ function (angular, app, _, kbn) {
$scope.time = filterSrv.timeRange('min'); $scope.time = filterSrv.timeRange('min');
$scope.old_time = { $scope.old_time = {
from : new Date($scope.time.from.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_seconds($scope.panel.ago)*1000) to : new Date($scope.time.to.getTime() - kbn.interval_to_ms($scope.panel.ago))
}; };
var _segment = _.isUndefined(segment) ? 0 : segment; var _segment = _.isUndefined(segment) ? 0 : segment;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment