From 6206b2978c239a3044a642ca8f6e7845535f0224 Mon Sep 17 00:00:00 2001 From: archmoj Date: Fri, 5 Jun 2020 09:40:17 -0400 Subject: [PATCH 1/2] refactor making msUTC an option object instead of a boolean --- src/plots/cartesian/set_convert.js | 10 +++++----- src/traces/bar/calc.js | 8 +++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/plots/cartesian/set_convert.js b/src/plots/cartesian/set_convert.js index 612cd668815..b8d0803e638 100644 --- a/src/plots/cartesian/set_convert.js +++ b/src/plots/cartesian/set_convert.js @@ -90,7 +90,7 @@ module.exports = function setConvert(ax, fullLayout) { * - inserts a dummy arg so calendar is the 3rd arg (see notes below). * - defaults to ax.calendar */ - function dt2ms(v, _, calendar, msUTC) { + function dt2ms(v, _, calendar, opts) { // NOTE: Changed this behavior: previously we took any numeric value // to be a ms, even if it was a string that could be a bare year. // Now we convert it as a date if at all possible, and only try @@ -99,7 +99,7 @@ module.exports = function setConvert(ax, fullLayout) { if(ms === BADNUM) { if(isNumeric(v)) { v = +v; - if(msUTC) { + if((opts || {}).msUTC) { // For now it is only used // to fix bar length in milliseconds. // It could be applied in other places in v2 @@ -798,7 +798,7 @@ module.exports = function setConvert(ax, fullLayout) { // the first letter of ax._id?) // in case the expected data isn't there, make a list of // integers based on the opposite data - ax.makeCalcdata = function(trace, axLetter, msUTC) { + ax.makeCalcdata = function(trace, axLetter, opts) { var arrayIn, arrayOut, i, len; var axType = ax.type; @@ -822,10 +822,10 @@ module.exports = function setConvert(ax, fullLayout) { arrayOut = new Array(len); for(i = 0; i < len; i++) { - arrayOut[i] = ax.d2c(arrayIn[i], 0, cal, msUTC); + arrayOut[i] = ax.d2c(arrayIn[i], 0, cal, opts); } } else { - var v0 = ((axLetter + '0') in trace) ? ax.d2c(trace[axLetter + '0'], 0, cal, false) : 0; + var v0 = ((axLetter + '0') in trace) ? ax.d2c(trace[axLetter + '0'], 0, cal) : 0; var dv = (trace['d' + axLetter]) ? Number(trace['d' + axLetter]) : 1; // the opposing data, for size if we have x and dx etc diff --git a/src/traces/bar/calc.js b/src/traces/bar/calc.js index e03d4799f24..67b994e98cb 100644 --- a/src/traces/bar/calc.js +++ b/src/traces/bar/calc.js @@ -19,13 +19,15 @@ module.exports = function calc(gd, trace) { var ya = Axes.getFromId(gd, trace.yaxis || 'y'); var size, pos; - var msUTC = !!(trace.base || trace.base === 0); + var sizeOpts = { + msUTC: !!(trace.base || trace.base === 0) + }; if(trace.orientation === 'h') { - size = xa.makeCalcdata(trace, 'x', msUTC); + size = xa.makeCalcdata(trace, 'x', sizeOpts); pos = ya.makeCalcdata(trace, 'y'); } else { - size = ya.makeCalcdata(trace, 'y', msUTC); + size = ya.makeCalcdata(trace, 'y', sizeOpts); pos = xa.makeCalcdata(trace, 'x'); } From 904351addf82b87b87243aa1f7680217c6451a61 Mon Sep 17 00:00:00 2001 From: archmoj Date: Fri, 5 Jun 2020 10:29:39 -0400 Subject: [PATCH 2/2] fix issue 4902 --- src/lib/index.js | 4 +-- src/plots/cartesian/axes.js | 16 +++++------ src/plots/gl3d/layout/tick_marks.js | 2 +- .../baselines/gl3d_ticks-milliseconds.png | Bin 0 -> 17452 bytes test/image/mocks/gl3d_ticks-milliseconds.json | 26 ++++++++++++++++++ 5 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 test/image/baselines/gl3d_ticks-milliseconds.png create mode 100644 test/image/mocks/gl3d_ticks-milliseconds.json diff --git a/src/lib/index.js b/src/lib/index.js index 9ec4313587e..331c5dbefb4 100644 --- a/src/lib/index.js +++ b/src/lib/index.js @@ -257,10 +257,10 @@ lib.bBoxIntersect = function(a, b, pad) { * func: the function to apply * x1, x2: optional extra args */ -lib.simpleMap = function(array, func, x1, x2) { +lib.simpleMap = function(array, func, x1, x2, opts) { var len = array.length; var out = new Array(len); - for(var i = 0; i < len; i++) out[i] = func(array[i], x1, x2); + for(var i = 0; i < len; i++) out[i] = func(array[i], x1, x2, opts); return out; }; diff --git a/src/plots/cartesian/axes.js b/src/plots/cartesian/axes.js index 5a25212bb41..d17e33c6945 100644 --- a/src/plots/cartesian/axes.js +++ b/src/plots/cartesian/axes.js @@ -509,8 +509,8 @@ function autoShiftMonthBins(binStart, data, dtick, dataMin, calendar) { // ---------------------------------------------------- // ensure we have tick0, dtick, and tick rounding calculated -axes.prepTicks = function(ax) { - var rng = Lib.simpleMap(ax.range, ax.r2l); +axes.prepTicks = function(ax, opts) { + var rng = Lib.simpleMap(ax.range, ax.r2l, undefined, undefined, opts); // calculate max number of (auto) ticks to display based on plot size if(ax.tickmode === 'auto' || !ax.dtick) { @@ -563,16 +563,16 @@ axes.prepTicks = function(ax) { // if ticks are set to automatic, determine the right values (tick0,dtick) // in any case, set tickround to # of digits to round tick labels to, // or codes to this effect for log and date scales -axes.calcTicks = function calcTicks(ax) { - axes.prepTicks(ax); - var rng = Lib.simpleMap(ax.range, ax.r2l); +axes.calcTicks = function calcTicks(ax, opts) { + axes.prepTicks(ax, opts); + var rng = Lib.simpleMap(ax.range, ax.r2l, undefined, undefined, opts); // now that we've figured out the auto values for formatting // in case we're missing some ticktext, we can break out for array ticks if(ax.tickmode === 'array') return arrayTicks(ax); // find the first tick - ax._tmin = axes.tickFirst(ax); + ax._tmin = axes.tickFirst(ax, opts); // add a tiny bit so we get ticks which may have rounded out var exRng = expandRange(rng); @@ -962,9 +962,9 @@ axes.tickIncrement = function(x, dtick, axrev, calendar) { }; // calculate the first tick on an axis -axes.tickFirst = function(ax) { +axes.tickFirst = function(ax, opts) { var r2l = ax.r2l || Number; - var rng = Lib.simpleMap(ax.range, r2l); + var rng = Lib.simpleMap(ax.range, r2l, undefined, undefined, opts); var axrev = rng[1] < rng[0]; var sRound = axrev ? Math.floor : Math.ceil; // add a tiny extra bit to make sure we get ticks diff --git a/src/plots/gl3d/layout/tick_marks.js b/src/plots/gl3d/layout/tick_marks.js index 5cbbcbd775f..737cf17c32d 100644 --- a/src/plots/gl3d/layout/tick_marks.js +++ b/src/plots/gl3d/layout/tick_marks.js @@ -69,7 +69,7 @@ function computeTickMarks(scene) { var nticks = axes.nticks || Lib.constrain((axes._length / 40), 4, 9); Axes.autoTicks(axes, Math.abs(axes.range[1] - axes.range[0]) / nticks); } - var dataTicks = Axes.calcTicks(axes); + var dataTicks = Axes.calcTicks(axes, { msUTC: true }); for(var j = 0; j < dataTicks.length; ++j) { dataTicks[j].x = dataTicks[j].x * scene.dataScale[i]; diff --git a/test/image/baselines/gl3d_ticks-milliseconds.png b/test/image/baselines/gl3d_ticks-milliseconds.png new file mode 100644 index 0000000000000000000000000000000000000000..6e62532bfc668f10e50fd82ff98f14762f4e3e2d GIT binary patch literal 17452 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