Commit a0a98cb0 by Torkel Ödegaard

feat(timepicker2): working on richer timepicker options

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