diff --git a/package-lock.json b/package-lock.json index 11fcb19be53..cbe39237fd3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2482,6 +2482,19 @@ "d3-path": "1" } }, + "d3-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz", + "integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA==" + }, + "d3-time-format": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.2.3.tgz", + "integrity": "sha512-RAHNnD8+XvC4Zc4d2A56Uw0yJoM7bsvOlJR33bclxq399Rak/b9bhvu/InjxdWhPtkgU53JJcleJTGkNRnN6IA==", + "requires": { + "d3-time": "1" + } + }, "d3-timer": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz", diff --git a/package.json b/package.json index 875885a4576..7b2092835a9 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,7 @@ "d3-force": "^1.2.1", "d3-hierarchy": "^1.1.9", "d3-interpolate": "^1.4.0", + "d3-time-format": "^2.2.3", "delaunay-triangulate": "^1.1.6", "es6-promise": "^4.2.8", "fast-isnumeric": "^1.1.4", diff --git a/src/constants/docs.js b/src/constants/docs.js index 72e06e9af84..fc24f8ee953 100644 --- a/src/constants/docs.js +++ b/src/constants/docs.js @@ -10,5 +10,5 @@ module.exports = { FORMAT_LINK: 'https://github.com/d3/d3-3.x-api-reference/blob/master/Formatting.md#d3_format', - DATE_FORMAT_LINK: 'https://github.com/d3/d3-3.x-api-reference/blob/master/Time-Formatting.md#format' + DATE_FORMAT_LINK: 'https://github.com/d3/d3-time-format#locale_format' }; diff --git a/src/lib/dates.js b/src/lib/dates.js index 52ca20433e1..4fc8387d2cb 100644 --- a/src/lib/dates.js +++ b/src/lib/dates.js @@ -9,7 +9,7 @@ 'use strict'; -var d3 = require('d3'); +var timeFormat = require('d3-time-format').timeFormat; var isNumeric = require('fast-isnumeric'); var Loggers = require('./loggers'); @@ -25,7 +25,7 @@ var EPOCHJD = constants.EPOCHJD; var Registry = require('../registry'); -var utcFormat = d3.time.format.utc; +var utcFormat = require('d3-time-format').utcFormat; var DATETIME_REGEXP = /^\s*(-?\d\d\d\d|\d\d)(-(\d?\d)(-(\d?\d)([ Tt]([01]?\d|2[0-3])(:([0-5]\d)(:([0-5]\d(\.\d+)?))?(Z|z|[+\-]\d\d(:?\d\d)?)?)?)?)?)?\s*$/m; // special regex for chinese calendars to support yyyy-mmi-dd etc for intercalary months @@ -306,7 +306,7 @@ exports.ms2DateTimeLocal = function(ms) { var msecTenths = Math.floor(mod(ms + 0.05, 1) * 10); var d = new Date(Math.round(ms - msecTenths / 10)); - var dateStr = d3.time.format('%Y-%m-%d')(d); + var dateStr = timeFormat('%Y-%m-%d')(d); var h = d.getHours(); var m = d.getMinutes(); var s = d.getSeconds(); diff --git a/src/lib/index.js b/src/lib/index.js index 331c5dbefb4..2ea7cda940c 100644 --- a/src/lib/index.js +++ b/src/lib/index.js @@ -9,6 +9,7 @@ 'use strict'; var d3 = require('d3'); +var utcFormat = require('d3-time-format').utcFormat; var isNumeric = require('fast-isnumeric'); var numConstants = require('../constants/numerical'); @@ -1082,7 +1083,7 @@ function templateFormatString(string, labels, d3locale) { } if(format[0] === '|') { - fmt = d3locale ? d3locale.timeFormat.utc : d3.time.format.utc; + fmt = d3locale ? d3locale.timeFormat : utcFormat; var ms = lib.dateTime2ms(value); value = lib.formatDate(ms, format.replace(TEMPLATE_STRING_FORMAT_SEPARATOR, ''), false, fmt); } diff --git a/src/plots/cartesian/set_convert.js b/src/plots/cartesian/set_convert.js index 508d3731b00..0a2c86f4f6f 100644 --- a/src/plots/cartesian/set_convert.js +++ b/src/plots/cartesian/set_convert.js @@ -9,6 +9,7 @@ 'use strict'; var d3 = require('d3'); +var utcFormat = require('d3-time-format').utcFormat; var isNumeric = require('fast-isnumeric'); var Lib = require('../../lib'); @@ -954,7 +955,7 @@ module.exports = function setConvert(ax, fullLayout) { // Fall back on default format for dummy axes that don't care about formatting var locale = fullLayout._d3locale; if(ax.type === 'date') { - ax._dateFormat = locale ? locale.timeFormat.utc : d3.time.format.utc; + ax._dateFormat = locale ? locale.timeFormat : utcFormat; ax._extraFormat = fullLayout._extraFormat; } // occasionally we need _numFormat to pass through diff --git a/src/plots/plots.js b/src/plots/plots.js index 9fad0247f05..03ba70426c0 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -9,6 +9,7 @@ 'use strict'; var d3 = require('d3'); +var timeFormatLocale = require('d3-time-format').timeFormatLocale; var isNumeric = require('fast-isnumeric'); var Registry = require('../registry'); @@ -723,7 +724,10 @@ function getFormatter(formatObj, separators) { formatObj.decimal = separators.charAt(0); formatObj.thousands = separators.charAt(1); - return d3.locale(formatObj); + return { + numberFormat: d3.locale(formatObj).numberFormat, + timeFormat: timeFormatLocale(formatObj).utcFormat + }; } function fillMetaTextHelpers(newFullData, newFullLayout) { diff --git a/test/jasmine/tests/axes_test.js b/test/jasmine/tests/axes_test.js index 5c19984ce9e..f9c7b2a347c 100644 --- a/test/jasmine/tests/axes_test.js +++ b/test/jasmine/tests/axes_test.js @@ -1,5 +1,6 @@ var Plotly = require('@lib/index'); var d3 = require('d3'); +var utcFormat = require('d3-time-format').utcFormat; var Plots = require('@src/plots/plots'); var Lib = require('@src/lib'); @@ -5206,7 +5207,7 @@ function getZoomOutButton(gd) { } function getFormatter(format) { - return d3.time.format.utc(format); + return utcFormat(format); } describe('Test Axes.getTickformat', function() { diff --git a/test/jasmine/tests/lib_date_test.js b/test/jasmine/tests/lib_date_test.js index 70f5a94933c..5305adc5aee 100644 --- a/test/jasmine/tests/lib_date_test.js +++ b/test/jasmine/tests/lib_date_test.js @@ -7,7 +7,7 @@ var calComponent = require('@src/components/calendars'); // use only the parts of world-calendars that we've imported for our tests var calendars = require('@src/components/calendars/calendars'); -var utcFormat = require('d3').time.format.utc; +var utcFormat = require('d3-time-format').utcFormat; describe('dates', function() { 'use strict'; @@ -571,15 +571,24 @@ describe('dates', function() { ], [ '%B \'%y WOY:%U DOW:%w', - 'August \'12 WOY:32 DOW:1', + 'August \'12 WOY:33 DOW:1', 'Mesori \'28 WOY:## DOW:##' // world-cals doesn't support U or w ], + [ + '%B \'%y QOY:%q WOY:%W DOW:%u', + 'August \'12 QOY:3 WOY:33 DOW:1', + 'Mesori \'28 QOY:3 WOY:48 DOW:1' + ], + [ + 'seconds: %s and milliseconds: %Q since UNIX epoch', + 'seconds: 1344838774 and milliseconds: 1344838774567 since UNIX epoch', + 'seconds: 1344838774 and milliseconds: 1344838774567 since UNIX epoch' + ], [ '%c && %x && .%2f .%f', // %f is our addition - 'Mon Aug 13 06:19:34 2012 && 08/13/2012 && .57 .5678', - 'Pes Meso 7 06:19:34 1728 && 12/07/1728 && .57 .5678' + '8/13/2012, 6:19:34 AM && 8/13/2012 && .57 .5678', + 'Pes Meso 7 6:19:34 AM 1728 && 12/07/1728 && .57 .5678' ] - ].forEach(function(v) { var fmt = v[0]; var expectedGregorian = v[1]; diff --git a/test/jasmine/tests/localize_test.js b/test/jasmine/tests/localize_test.js index 92d2d0f556b..c4b1ea92088 100644 --- a/test/jasmine/tests/localize_test.js +++ b/test/jasmine/tests/localize_test.js @@ -3,6 +3,7 @@ var _ = Lib._; var Registry = require('@src/registry'); var d3 = require('d3'); +var utcFormat = require('d3-time-format').utcFormat; var Plotly = require('@lib'); var createGraphDiv = require('../assets/create_graph_div'); @@ -236,7 +237,7 @@ describe('localization', function() { expect(firstYLabel()).toBe('0~5'); var d0 = new Date(0); // thursday, Jan 1 1970 (UTC) // sanity check that d0 is what we think... - expect(d3.time.format.utc('%a %b %A %B')(d0)).toBe('Thu Jan Thursday January'); + expect(utcFormat('%a %b %A %B')(d0)).toBe('Thu Jan Thursday January'); // full names were not overridden, so fall back on english expect(gd._fullLayout.xaxis._dateFormat('%a %b %A %B')(d0)).toBe('t !1 Thursday January'); })