Commit 2adbe3e1 by Axel Committed by Torkel Ödegaard

Prettify duration value format (#6875)

* Prettify duration unit format

Format duration like "2 days, 19 hours, 48 minutes" and make Decimals useful e.g.
0 decimals: 2 days
2 decimals: 2 days, 19 hours, 48 minutes
3 decimals: 2 days, 19 hours, 48 minutes, 27 seconds

Previous code did some rounding that is now gone so numbers might be
different.

* Rewrite kbn.toDuration without moment.js

Because https://github.com/moment/moment/issues/3653

* Add tests for kbn.toDuration
parent ba7a990f
define([
'jquery',
'lodash',
'moment'
'lodash'
],
function($, _, moment) {
function($, _) {
'use strict';
var kbn = {};
......@@ -631,16 +630,50 @@ function($, _, moment) {
}
};
kbn.toDuration = function(size, timeScale) {
return moment.duration(size, timeScale);
kbn.toDuration = function(size, decimals, timeScale) {
if (size === null) { return ""; }
if (size === 0) { return "0 " + timeScale + "s"; }
if (size < 0) { return kbn.toDuration(-size, decimals, timeScale) + " ago"; }
var units = [
{short: "y", long: "year"},
{short: "M", long: "month"},
{short: "w", long: "week"},
{short: "d", long: "day"},
{short: "h", long: "hour"},
{short: "m", long: "minute"},
{short: "s", long: "second"},
{short: "ms", long: "millisecond"}
];
// convert $size to milliseconds
// intervals_in_seconds uses seconds (duh), convert them to milliseconds here to minimize floating point errors
size *= kbn.intervals_in_seconds[units.find(function(e) { return e.long === timeScale; }).short] * 1000;
var string = [];
// after first value >= 1 print only $decimals more
var decrementDecimals = false;
for (var i = 0; i < units.length && decimals >= 0; i++) {
var interval = kbn.intervals_in_seconds[units[i].short] * 1000;
var value = size / interval;
if (value >= 1 || decrementDecimals) {
decrementDecimals = true;
var floor = Math.floor(value);
var unit = units[i].long + (floor !== 1 ? "s" : "");
string.push(floor + " " + unit);
size = size % interval;
decimals--;
}
}
return string.join(", ");
};
kbn.valueFormats.dtdurationms = function(size) {
return kbn.toDuration(size, 'ms').humanize();
kbn.valueFormats.dtdurationms = function(size, decimals) {
return kbn.toDuration(size, decimals, 'millisecond');
};
kbn.valueFormats.dtdurations = function(size) {
return kbn.toDuration(size, 's').humanize();
kbn.valueFormats.dtdurations = function(size, decimals) {
return kbn.toDuration(size, decimals, 'second');
};
///// FORMAT MENU /////
......
......@@ -214,4 +214,75 @@ define([
expect(str).to.be('-0x41.8');
});
});
describe('duration', function() {
it('null', function() {
var str = kbn.toDuration(null, 0, "millisecond");
expect(str).to.be('');
});
it('0 milliseconds', function() {
var str = kbn.toDuration(0, 0, "millisecond");
expect(str).to.be('0 milliseconds');
});
it('1 millisecond', function() {
var str = kbn.toDuration(1, 0, "millisecond");
expect(str).to.be('1 millisecond');
});
it('-1 millisecond', function() {
var str = kbn.toDuration(-1, 0, "millisecond");
expect(str).to.be('1 millisecond ago');
});
it('seconds', function() {
var str = kbn.toDuration(1, 0, "second");
expect(str).to.be('1 second');
});
it('minutes', function() {
var str = kbn.toDuration(1, 0, "minute");
expect(str).to.be('1 minute');
});
it('hours', function() {
var str = kbn.toDuration(1, 0, "hour");
expect(str).to.be('1 hour');
});
it('days', function() {
var str = kbn.toDuration(1, 0, "day");
expect(str).to.be('1 day');
});
it('weeks', function() {
var str = kbn.toDuration(1, 0, "week");
expect(str).to.be('1 week');
});
it('months', function() {
var str = kbn.toDuration(1, 0, "month");
expect(str).to.be('1 month');
});
it('years', function() {
var str = kbn.toDuration(1, 0, "year");
expect(str).to.be('1 year');
});
it('decimal days', function() {
var str = kbn.toDuration(1.5, 2, "day");
expect(str).to.be('1 day, 12 hours, 0 minutes');
});
it('decimal months', function() {
var str = kbn.toDuration(1.5, 3, "month");
expect(str).to.be('1 month, 2 weeks, 1 day, 0 hours');
});
it('no decimals', function() {
var str = kbn.toDuration(38898367008, 0, "millisecond");
expect(str).to.be('1 year');
});
it('1 decimal', function() {
var str = kbn.toDuration(38898367008, 1, "millisecond");
expect(str).to.be('1 year, 2 months');
});
it('too many decimals', function() {
var str = kbn.toDuration(38898367008, 20, "millisecond");
expect(str).to.be('1 year, 2 months, 3 weeks, 4 days, 5 hours, 6 minutes, 7 seconds, 8 milliseconds');
});
it('floating point error', function() {
var str = kbn.toDuration(36993906007, 8, "millisecond");
expect(str).to.be('1 year, 2 months, 0 weeks, 3 days, 4 hours, 5 minutes, 6 seconds, 7 milliseconds');
});
});
});
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