Commit 1afec73f by spenceralger

Merge pull request #468 from spenceralger/numeric-sort

Fixes for #466
parents 8a142d91 6e728480
......@@ -208,30 +208,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.
......
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) {
} 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++) {
......
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]);
}
......
......@@ -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;
......
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