diff --git a/platform/commonUI/formats/bundle.js b/platform/commonUI/formats/bundle.js index 7525aaff9d..a074fe3134 100644 --- a/platform/commonUI/formats/bundle.js +++ b/platform/commonUI/formats/bundle.js @@ -61,6 +61,17 @@ define([ "key": "DEFAULT_TIME_FORMAT", "value": "utc" } + ], + "licenses": [ + { + "name": "d3", + "version": "3.0.0", + "description": "Incorporates modified code from d3 Time Scales", + "author": "Mike Bostock", + "copyright": "Copyright 2010-2016 Mike Bostock. " + + "All rights reserved.", + "link": "https://github.com/d3/d3/blob/master/LICENSE" + } ] } }); diff --git a/platform/commonUI/formats/src/UTCTimeFormat.js b/platform/commonUI/formats/src/UTCTimeFormat.js index be3610d518..03176272d1 100644 --- a/platform/commonUI/formats/src/UTCTimeFormat.js +++ b/platform/commonUI/formats/src/UTCTimeFormat.js @@ -41,6 +41,12 @@ define([ DAYS = 24 * HOURS, MONTHS = (365 / 12) * DAYS; + /** + * @typedef Scale + * @property {number} min the minimum scale value, in ms + * @property {number} max the maximum scale value, in ms + */ + /** * Formatter for UTC timestamps. Interprets numeric values as * milliseconds since the start of 1970. @@ -57,42 +63,43 @@ define([ * the threshold required. * @private */ - function getScaledFormat (d, threshold) { - //Adapted from D3 formatting rules - if (!(d instanceof Date)){ - d = new Date(moment.utc(d)); - } + function getScaledFormat (d) { + var m = moment.utc(d); + /** + * Uses logic from d3 Time-Scales, v3 of the API. See + * https://github.com/d3/d3-3.x-api-reference/blob/master/Time-Scales.md + * + * Licensed + */ return [ - [".SSS", function(d) { return d.getMilliseconds() >= threshold; }], - [":ss", function(d) { return d.getSeconds() * SECONDS >= threshold; }], - ["HH:mm", function(d) { return d.getMinutes() * MINUTES >= threshold; }], - ["HH", function(d) { return d.getHours() * HOURS >= threshold; }], - ["ddd DD", function(d) { - return d.getDay() * DAYS >= threshold && - d.getDate() != 1; + [".SSS", function(m) { return m.milliseconds(); }], + [":ss", function(m) { return m.seconds(); }], + ["HH:mm", function(m) { return m.minutes(); }], + ["HH", function(m) { return m.hours(); }], + ["ddd DD", function(m) { + return m.days() && + m.date() != 1; }], - ["MMM DD", function(d) { return d.getDate() != 1; }], - ["MMMM", function(d) { - return d.getMonth() * MONTHS >= threshold; + ["MMM DD", function(m) { return m.date() != 1; }], + ["MMMM", function(m) { + return m.month(); }], ["YYYY", function() { return true; }] ].filter(function (row){ - return row[1](d); + return row[1](m); })[0][0]; }; /** * * @param value - * @param {number} [threshold] Optionally provides context to the - * format request, allowing for scale-appropriate formatting. This value - * should be the minimum unit to be represented by this format, in ms. For - * example, to display seconds, a threshold of 1 * 1000 should be provided. + * @param {Scale} [scale] Optionally provides context to the + * format request, allowing for scale-appropriate formatting. * @returns {string} the formatted date */ - UTCTimeFormat.prototype.format = function (value, threshold) { - if (threshold !== undefined){ - var scaledFormat = getScaledFormat(value, threshold); + UTCTimeFormat.prototype.format = function (value, scale) { + if (scale !== undefined){ + var scaledFormat = getScaledFormat(value, scale); if (scaledFormat) { return moment.utc(value).format(scaledFormat); } diff --git a/platform/features/conductor-v2/src/ui/MctConductorAxis.js b/platform/features/conductor-v2/src/ui/MctConductorAxis.js index c175ed24e6..94c1285089 100644 --- a/platform/features/conductor-v2/src/ui/MctConductorAxis.js +++ b/platform/features/conductor-v2/src/ui/MctConductorAxis.js @@ -57,39 +57,23 @@ define( axisElement.call(xAxis); } - // Calculates the precision of date for formatting. Relies on - // D3's behavior to tick on round units - function threshold(date){ - var ms = date.getTime(); - return [ - 365 * 24 * 60 * 60 * 1000, // years - (365 / 12) * 24 * 60 * 60 * 1000, // months - 7 * 24 * 60 * 60 * 1000, // weeks - 24 * 60 * 60 * 1000, // days - 60 * 60 * 1000, // hours - 60 * 1000, // minutes - 1000, // seconds - 1 // ms - ].filter(function (boundary) { - return ms % boundary === 0; - })[0]; - } - function changeTimeSystem(timeSystem) { var key = timeSystem.formats()[0]; if (key !== undefined) { var format = formatService.getFormat(key); + var b = conductor.bounds(); //Define a custom format function xAxis.tickFormat(function (date) { - return format.format(date, threshold(date)); + return format.format(date, {min: b.start, max: b.end}); }); axisElement.call(xAxis); } } scope.resize = function () { - setScale(conductor.bounds().start, conductor.bounds().end); + var b = conductor.bounds(); + setScale(b.start, b.end); }; conductor.on('timeSystem', changeTimeSystem); @@ -98,9 +82,9 @@ define( conductor.on('bounds', function (bounds) { setScale(bounds.start, bounds.end); }); - //Set initial scale. - setScale(conductor.bounds().start, conductor.bounds().end); + var bounds = conductor.bounds(); + setScale(bounds.start, bounds.end); if (conductor.timeSystem() !== undefined) { changeTimeSystem(conductor.timeSystem());