mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(timepicker2): working on richer timepicker options
This commit is contained in:
parent
d705108be5
commit
a0a98cb035
@ -7,103 +7,105 @@ var units = ['y', 'M', 'w', 'd', 'h', 'm', 's'];
|
||||
var unitsAsc = _.sortBy(units, function (unit) {
|
||||
return moment.duration(1, unit).valueOf();
|
||||
});
|
||||
|
||||
var unitsDesc = unitsAsc.reverse();
|
||||
|
||||
export class DateMath {
|
||||
function parse(text, roundUp?) {
|
||||
if (!text) { return undefined; }
|
||||
if (moment.isMoment(text)) { return text; }
|
||||
if (_.isDate(text)) { return moment(text); }
|
||||
|
||||
static parse(text, roundUp?) {
|
||||
if (!text) { return undefined; }
|
||||
if (moment.isMoment(text)) { return text; }
|
||||
if (_.isDate(text)) { return moment(text); }
|
||||
var time;
|
||||
var mathString = '';
|
||||
var index;
|
||||
var parseString;
|
||||
|
||||
var time;
|
||||
var mathString = '';
|
||||
var index;
|
||||
var parseString;
|
||||
|
||||
if (text.substring(0, 3) === 'now') {
|
||||
time = moment();
|
||||
mathString = text.substring('now'.length);
|
||||
if (text.substring(0, 3) === 'now') {
|
||||
time = moment();
|
||||
mathString = text.substring('now'.length);
|
||||
} else {
|
||||
index = text.indexOf('||');
|
||||
if (index === -1) {
|
||||
parseString = text;
|
||||
mathString = ''; // nothing else
|
||||
} else {
|
||||
index = text.indexOf('||');
|
||||
if (index === -1) {
|
||||
parseString = text;
|
||||
mathString = ''; // nothing else
|
||||
} else {
|
||||
parseString = text.substring(0, index);
|
||||
mathString = text.substring(index + 2);
|
||||
}
|
||||
// We're going to just require ISO8601 timestamps, k?
|
||||
time = moment(parseString);
|
||||
parseString = text.substring(0, index);
|
||||
mathString = text.substring(index + 2);
|
||||
}
|
||||
|
||||
if (!mathString.length) {
|
||||
return time;
|
||||
}
|
||||
|
||||
return DateMath.parseDateMath(mathString, time, roundUp);
|
||||
// We're going to just require ISO8601 timestamps, k?
|
||||
time = moment(parseString);
|
||||
}
|
||||
|
||||
static parseDateMath(mathString, time, roundUp?) {
|
||||
var dateTime = time;
|
||||
var i = 0;
|
||||
var len = mathString.length;
|
||||
|
||||
while (i < len) {
|
||||
var c = mathString.charAt(i++);
|
||||
var type;
|
||||
var num;
|
||||
var unit;
|
||||
|
||||
if (c === '/') {
|
||||
type = 0;
|
||||
} else if (c === '+') {
|
||||
type = 1;
|
||||
} else if (c === '-') {
|
||||
type = 2;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (isNaN(mathString.charAt(i))) {
|
||||
num = 1;
|
||||
} else if (mathString.length === 2) {
|
||||
num = mathString.charAt(i);
|
||||
} else {
|
||||
var numFrom = i;
|
||||
while (!isNaN(mathString.charAt(i))) {
|
||||
i++;
|
||||
if (i > 10) { return undefined; }
|
||||
}
|
||||
num = parseInt(mathString.substring(numFrom, i), 10);
|
||||
}
|
||||
|
||||
if (type === 0) {
|
||||
// rounding is only allowed on whole, single, units (eg M or 1M, not 0.5M or 2M)
|
||||
if (num !== 1) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
unit = mathString.charAt(i++);
|
||||
|
||||
if (!_.contains(units, unit)) {
|
||||
return undefined;
|
||||
} else {
|
||||
if (type === 0) {
|
||||
if (roundUp) {
|
||||
dateTime.endOf(unit);
|
||||
}
|
||||
else {
|
||||
dateTime.startOf(unit);
|
||||
}
|
||||
} else if (type === 1) {
|
||||
dateTime.add(num, unit);
|
||||
} else if (type === 2) {
|
||||
dateTime.subtract(num, unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dateTime;
|
||||
if (!mathString.length) {
|
||||
return time;
|
||||
}
|
||||
|
||||
return parseDateMath(mathString, time, roundUp);
|
||||
}
|
||||
|
||||
function parseDateMath(mathString, time, roundUp?) {
|
||||
var dateTime = time;
|
||||
var i = 0;
|
||||
var len = mathString.length;
|
||||
|
||||
while (i < len) {
|
||||
var c = mathString.charAt(i++);
|
||||
var type;
|
||||
var num;
|
||||
var unit;
|
||||
|
||||
if (c === '/') {
|
||||
type = 0;
|
||||
} else if (c === '+') {
|
||||
type = 1;
|
||||
} else if (c === '-') {
|
||||
type = 2;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (isNaN(mathString.charAt(i))) {
|
||||
num = 1;
|
||||
} else if (mathString.length === 2) {
|
||||
num = mathString.charAt(i);
|
||||
} else {
|
||||
var numFrom = i;
|
||||
while (!isNaN(mathString.charAt(i))) {
|
||||
i++;
|
||||
if (i > 10) { return undefined; }
|
||||
}
|
||||
num = parseInt(mathString.substring(numFrom, i), 10);
|
||||
}
|
||||
|
||||
if (type === 0) {
|
||||
// rounding is only allowed on whole, single, units (eg M or 1M, not 0.5M or 2M)
|
||||
if (num !== 1) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
unit = mathString.charAt(i++);
|
||||
|
||||
if (!_.contains(units, unit)) {
|
||||
return undefined;
|
||||
} else {
|
||||
if (type === 0) {
|
||||
if (roundUp) {
|
||||
dateTime.endOf(unit);
|
||||
}
|
||||
else {
|
||||
dateTime.startOf(unit);
|
||||
}
|
||||
} else if (type === 1) {
|
||||
dateTime.add(num, unit);
|
||||
} else if (type === 2) {
|
||||
dateTime.subtract(num, unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
return dateTime;
|
||||
}
|
||||
|
||||
export = {
|
||||
parse: parse,
|
||||
parseDateMath: parseDateMath
|
||||
};
|
||||
|
@ -3,8 +3,9 @@ define([
|
||||
'lodash',
|
||||
'config',
|
||||
'kbn',
|
||||
'moment'
|
||||
], function (angular, _, config, kbn, moment) {
|
||||
'moment',
|
||||
'app/core/utils/datemath'
|
||||
], function (angular, _, config, kbn, moment, dateMath) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.services');
|
||||
@ -131,8 +132,8 @@ define([
|
||||
var _to = _t.to || new Date();
|
||||
|
||||
return {
|
||||
from: kbn.parseDate(_from),
|
||||
to: kbn.parseDate(_to)
|
||||
from: dateMath.parse(_from, false),
|
||||
to: dateMath.parse(_to, true)
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@ -4,6 +4,7 @@ import angular = require('angular');
|
||||
import _ = require('lodash');
|
||||
import moment = require('moment');
|
||||
import kbn = require('kbn');
|
||||
import dateMath = require('app/core/utils/datemath');
|
||||
import {TimeRange} from './timerange';
|
||||
|
||||
export class TimePickerCtrl {
|
||||
@ -59,11 +60,11 @@ export class TimePickerCtrl {
|
||||
|
||||
getTimeObj(date): any {
|
||||
return {
|
||||
date: new Date(date),
|
||||
hour: this.pad(date.getHours(), 2),
|
||||
minute: this.pad(date.getMinutes(), 2),
|
||||
second: this.pad(date.getSeconds(), 2),
|
||||
millisecond: this.pad(date.getMilliseconds(), 3)
|
||||
date: date,
|
||||
hour: this.pad(date.hours(), 2),
|
||||
minute: this.pad(date.minutes(), 2),
|
||||
second: this.pad(date.seconds(), 2),
|
||||
millisecond: this.pad(date.milliseconds(), 3)
|
||||
};
|
||||
};
|
||||
|
||||
@ -154,7 +155,7 @@ export class TimePickerCtrl {
|
||||
|
||||
this.timeSrv.setTime(range);
|
||||
|
||||
this.$scope.time = this.getScopeTimeObj(kbn.parseDate(range.from), new Date());
|
||||
this.$scope.time = this.getScopeTimeObj(dateMath.parse(range.from), moment());
|
||||
}
|
||||
|
||||
validate(time): any {
|
||||
|
@ -285,8 +285,8 @@ function (angular, $, kbn, moment, _, GraphTooltip) {
|
||||
|
||||
function addTimeAxis(options) {
|
||||
var ticks = elem.width() / 100;
|
||||
var min = _.isUndefined(scope.range.from) ? null : scope.range.from.getTime();
|
||||
var max = _.isUndefined(scope.range.to) ? null : scope.range.to.getTime();
|
||||
var min = _.isUndefined(scope.range.from) ? null : scope.range.from.valueOf();
|
||||
var max = _.isUndefined(scope.range.to) ? null : scope.range.to.valueOf();
|
||||
|
||||
options.xaxis = {
|
||||
timezone: dashboard.timezone,
|
||||
|
@ -3,14 +3,14 @@ define([
|
||||
'lodash',
|
||||
'jquery',
|
||||
'config',
|
||||
'kbn',
|
||||
'app/core/utils/datemath',
|
||||
'moment',
|
||||
'./directives',
|
||||
'./queryCtrl',
|
||||
'./funcEditor',
|
||||
'./addGraphiteFunc',
|
||||
],
|
||||
function (angular, _, $, config, kbn, moment) {
|
||||
function (angular, _, $, config, dateMath, moment) {
|
||||
'use strict';
|
||||
|
||||
var module = angular.module('grafana.services');
|
||||
@ -29,8 +29,8 @@ function (angular, _, $, config, kbn, moment) {
|
||||
GraphiteDatasource.prototype.query = function(options) {
|
||||
try {
|
||||
var graphOptions = {
|
||||
from: this.translateTime(options.range.from, 'round-down'),
|
||||
until: this.translateTime(options.range.to, 'round-up'),
|
||||
from: this.translateTime(options.range.from, false),
|
||||
until: this.translateTime(options.range.to, true),
|
||||
targets: options.targets,
|
||||
format: options.format,
|
||||
cacheTimeout: options.cacheTimeout || this.cacheTimeout,
|
||||
@ -135,7 +135,7 @@ function (angular, _, $, config, kbn, moment) {
|
||||
|
||||
return this.doGraphiteRequest({
|
||||
method: 'GET',
|
||||
url: '/events/get_data?from=' + this.translateTime(options.range.from) + '&until=' + this.translateTime(options.range.to) + tags,
|
||||
url: '/events/get_data?from=' + this.translateTime(options.range.from, false) + '&until=' + this.translateTime(options.range.to, true) + tags,
|
||||
});
|
||||
}
|
||||
catch(err) {
|
||||
@ -143,28 +143,30 @@ function (angular, _, $, config, kbn, moment) {
|
||||
}
|
||||
};
|
||||
|
||||
GraphiteDatasource.prototype.translateTime = function(date, rounding) {
|
||||
GraphiteDatasource.prototype.translateTime = function(date, roundUp) {
|
||||
if (_.isString(date)) {
|
||||
if (date === 'now') {
|
||||
return 'now';
|
||||
}
|
||||
else if (date.indexOf('now') >= 0) {
|
||||
else if (date.indexOf('now-') >= 0) {
|
||||
date = date.substring(3);
|
||||
date = date.replace('m', 'min');
|
||||
date = date.replace('M', 'mon');
|
||||
return date;
|
||||
}
|
||||
date = kbn.parseDate(date);
|
||||
console.log('date: ' + date + ' round up: ' + roundUp);
|
||||
date = dateMath.parse(date, roundUp);
|
||||
console.log('date: ' + date + ' round up: ' + roundUp + ' ' + date.format('YYYY-MM-DD:HH:mm'));
|
||||
}
|
||||
|
||||
date = moment.utc(date);
|
||||
|
||||
if (rounding === 'round-up') {
|
||||
if (roundUp) {
|
||||
if (date.get('s')) {
|
||||
date.add(1, 'm');
|
||||
}
|
||||
}
|
||||
else if (rounding === 'round-down') {
|
||||
else if (roundUp === false) {
|
||||
// graphite' s from filter is exclusive
|
||||
// here we step back one minute in order
|
||||
// to guarantee that we get all the data that
|
||||
|
@ -1,10 +1,10 @@
|
||||
import {DateMath} from 'app/core/utils/datemath'
|
||||
import {describe, beforeEach, it, sinon, expect} from 'test/lib/common'
|
||||
|
||||
import dateMath = require('app/core/utils/datemath')
|
||||
import _ = require('lodash')
|
||||
import moment = require('moment')
|
||||
|
||||
describe.only("DateMath", () => {
|
||||
describe("DateMath", () => {
|
||||
var spans = ['s', 'm', 'h', 'd', 'w', 'M', 'y'];
|
||||
var anchor = '2014-01-01T06:06:06.666Z';
|
||||
var unix = moment(anchor).valueOf();
|
||||
@ -13,25 +13,25 @@ describe.only("DateMath", () => {
|
||||
|
||||
describe('errors', () => {
|
||||
it('should return undefined if passed something falsy', () => {
|
||||
expect(DateMath.parse(false)).to.be(undefined);
|
||||
expect(dateMath.parse(false)).to.be(undefined);
|
||||
});
|
||||
|
||||
it('should return undefined if I pass an operator besides [+-/]', () => {
|
||||
expect(DateMath.parse('now&1d')).to.be(undefined);
|
||||
expect(dateMath.parse('now&1d')).to.be(undefined);
|
||||
});
|
||||
|
||||
it('should return undefined if I pass a unit besides' + spans.toString(), () => {
|
||||
expect(DateMath.parse('now+5f')).to.be(undefined);
|
||||
expect(dateMath.parse('now+5f')).to.be(undefined);
|
||||
});
|
||||
|
||||
it('should return undefined if rounding unit is not 1', () => {
|
||||
expect(DateMath.parse('now/2y')).to.be(undefined);
|
||||
expect(DateMath.parse('now/0.5y')).to.be(undefined);
|
||||
expect(dateMath.parse('now/2y')).to.be(undefined);
|
||||
expect(dateMath.parse('now/0.5y')).to.be(undefined);
|
||||
});
|
||||
|
||||
it('should not go into an infinite loop when missing a unit', () => {
|
||||
expect(DateMath.parse('now-0')).to.be(undefined);
|
||||
expect(DateMath.parse('now-00')).to.be(undefined);
|
||||
expect(dateMath.parse('now-0')).to.be(undefined);
|
||||
expect(dateMath.parse('now-00')).to.be(undefined);
|
||||
});
|
||||
});
|
||||
|
||||
@ -42,7 +42,7 @@ describe.only("DateMath", () => {
|
||||
expected.setSeconds(0);
|
||||
expected.setMilliseconds(0);
|
||||
|
||||
var startOfDay = DateMath.parse('now/d', false).valueOf()
|
||||
var startOfDay = dateMath.parse('now/d', false).valueOf()
|
||||
expect(startOfDay).to.be(expected.getTime());
|
||||
});
|
||||
|
||||
@ -61,16 +61,16 @@ describe.only("DateMath", () => {
|
||||
var thenEx = anchor + '||-5' + span;
|
||||
|
||||
it('should return 5' + span + ' ago', () => {
|
||||
expect(DateMath.parse(nowEx).format(format)).to.eql(now.subtract(5, span).format(format));
|
||||
expect(dateMath.parse(nowEx).format(format)).to.eql(now.subtract(5, span).format(format));
|
||||
});
|
||||
|
||||
it('should return 5' + span + ' before ' + anchor, () => {
|
||||
expect(DateMath.parse(thenEx).format(format)).to.eql(anchored.subtract(5, span).format(format));
|
||||
expect(dateMath.parse(thenEx).format(format)).to.eql(anchored.subtract(5, span).format(format));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('rounding', () => {
|
||||
describe.only('rounding', () => {
|
||||
var now;
|
||||
var anchored;
|
||||
|
||||
@ -82,11 +82,11 @@ describe.only("DateMath", () => {
|
||||
|
||||
_.each(spans, (span) => {
|
||||
it('should round now to the beginning of the ' + span, function () {
|
||||
expect(DateMath.parse('now/' + span).format(format)).to.eql(now.startOf(span).format(format));
|
||||
expect(dateMath.parse('now/' + span).format(format)).to.eql(now.startOf(span).format(format));
|
||||
});
|
||||
|
||||
it('should round now to the end of the ' + span, function () {
|
||||
expect(DateMath.parse('now/' + span, true).format(format)).to.eql(now.endOf(span).format(format));
|
||||
expect(dateMath.parse('now/' + span, true).format(format)).to.eql(now.endOf(span).format(format));
|
||||
});
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user