diff --git a/src/plots/cartesian/axes.js b/src/plots/cartesian/axes.js index 62aedb1d05f..5a25212bb41 100644 --- a/src/plots/cartesian/axes.js +++ b/src/plots/cartesian/axes.js @@ -56,6 +56,15 @@ var autorange = require('./autorange'); axes.getAutoRange = autorange.getAutoRange; axes.findExtremes = autorange.findExtremes; +var epsilon = 0.0001; +function expandRange(range) { + var delta = (range[1] - range[0]) * epsilon; + return [ + range[0] - delta, + range[1] + delta + ]; +} + /* * find the list of possible axes to reference with an xref or yref attribute * and coerce it to that list @@ -566,8 +575,9 @@ axes.calcTicks = function calcTicks(ax) { ax._tmin = axes.tickFirst(ax); // add a tiny bit so we get ticks which may have rounded out - var startTick = rng[0] * 1.0001 - rng[1] * 0.0001; - var endTick = rng[1] * 1.0001 - rng[0] * 0.0001; + var exRng = expandRange(rng); + var startTick = exRng[0]; + var endTick = exRng[1]; // check for reversed axis var axrev = (rng[1] < rng[0]); @@ -612,26 +622,15 @@ axes.calcTicks = function calcTicks(ax) { if(ax.rangebreaks) { // replace ticks inside breaks that would get a tick - if(ax.tickmode === 'auto') { - for(var t = 0; t < tickVals.length; t++) { - var value = tickVals[t].value; - if(ax.maskBreaks(value) === BADNUM) { - // find which break we are in - for(var k = 0; k < ax._rangebreaks.length; k++) { - var brk = ax._rangebreaks[k]; - if(value >= brk.min && value < brk.max) { - tickVals[t].value = brk.max; // replace with break end - break; - } - } - } - } - } - - // reduce ticks + // and reduce ticks var len = tickVals.length; - if(len > 2) { - var tf2 = 2 * (ax.tickfont ? ax.tickfont.size : 12); + if(len) { + var tf = 0; + if(ax.tickmode === 'auto') { + tf = + (ax._id.charAt(0) === 'y' ? 2 : 6) * + (ax.tickfont ? ax.tickfont.size : 12); + } var newTickVals = []; var prevPos; @@ -639,12 +638,26 @@ axes.calcTicks = function calcTicks(ax) { var dir = axrev ? 1 : -1; var first = axrev ? 0 : len - 1; var last = axrev ? len - 1 : 0; - for(var q = first; dir * q <= dir * last; q += dir) { // apply reverse loop to pick greater values in breaks first - var pos = ax.c2p(tickVals[q].value); + for(var q = first; dir * q <= dir * last; q += dir) { + var tickVal = tickVals[q]; + if(ax.maskBreaks(tickVal.value) === BADNUM) { + tickVal.value = moveOutsideBreak(tickVal.value, ax); + + if(ax._rl && ( + ax._rl[0] === tickVal.value || + ax._rl[1] === tickVal.value + )) continue; + } - if(prevPos === undefined || Math.abs(pos - prevPos) > tf2) { + var pos = ax.c2p(tickVal.value); + + if(pos === prevPos) { + if(newTickVals[newTickVals.length - 1].value < tickVal.value) { + newTickVals[newTickVals.length - 1] = tickVal; + } + } else if(prevPos === undefined || Math.abs(pos - prevPos) > tf) { prevPos = pos; - newTickVals.push(tickVals[q]); + newTickVals.push(tickVal); } } tickVals = newTickVals.reverse(); @@ -691,10 +704,9 @@ function arrayTicks(ax) { var text = ax.ticktext; var ticksOut = new Array(vals.length); var rng = Lib.simpleMap(ax.range, ax.r2l); - var r0expanded = rng[0] * 1.0001 - rng[1] * 0.0001; - var r1expanded = rng[1] * 1.0001 - rng[0] * 0.0001; - var tickMin = Math.min(r0expanded, r1expanded); - var tickMax = Math.max(r0expanded, r1expanded); + var exRng = expandRange(rng); + var tickMin = Math.min(exRng[0], exRng[1]); + var tickMax = Math.max(exRng[0], exRng[1]); var j = 0; // without a text array, just format the given values as any other ticks @@ -785,8 +797,7 @@ axes.autoTicks = function(ax, roughDTick) { roughDTick /= ONEAVGMONTH; ax.dtick = 'M' + roundDTick(roughDTick, 1, roundBase24); } else if(roughX2 > ONEDAY) { - ax.dtick = roundDTick(roughDTick, ONEDAY, ax._hasDayOfWeekBreaks ? [1, 7, 14] : roundDays); - + ax.dtick = roundDTick(roughDTick, ONEDAY, ax._hasDayOfWeekBreaks ? [1, 2, 7, 14] : roundDays); // get week ticks on sunday // this will also move the base tick off 2000-01-01 if dtick is // 2 or 3 days... but that's a weird enough case that we'll ignore it. @@ -934,18 +945,20 @@ axes.tickIncrement = function(x, dtick, axrev, calendar) { if(tType === 'M') return Lib.incrementMonth(x, dtSigned, calendar); // Log scales: Linear, Digits - else if(tType === 'L') return Math.log(Math.pow(10, x) + dtSigned) / Math.LN10; + if(tType === 'L') return Math.log(Math.pow(10, x) + dtSigned) / Math.LN10; // log10 of 2,5,10, or all digits (logs just have to be // close enough to round) - else if(tType === 'D') { + if(tType === 'D') { var tickset = (dtick === 'D2') ? roundLog2 : roundLog1; var x2 = x + axSign * 0.01; var frac = Lib.roundUp(Lib.mod(x2, 1), tickset, axrev); return Math.floor(x2) + Math.log(d3.round(Math.pow(10, frac), 1)) / Math.LN10; - } else throw 'unrecognized dtick ' + String(dtick); + } + + throw 'unrecognized dtick ' + String(dtick); }; // calculate the first tick on an axis @@ -956,7 +969,7 @@ axes.tickFirst = function(ax) { var sRound = axrev ? Math.floor : Math.ceil; // add a tiny extra bit to make sure we get ticks // that may have been rounded out - var r0 = rng[0] * 1.0001 - rng[1] * 0.0001; + var r0 = expandRange(rng)[0]; var dtick = ax.dtick; var tick0 = r2l(ax.tick0); @@ -3158,3 +3171,14 @@ function swapAxisAttrs(layout, key, xFullAxes, yFullAxes, dfltTitle) { function isAngular(ax) { return ax._id === 'angularaxis'; } + +function moveOutsideBreak(v, ax) { + var len = ax._rangebreaks.length; + for(var k = 0; k < len; k++) { + var brk = ax._rangebreaks[k]; + if(v >= brk.min && v < brk.max) { + return brk.max; + } + } + return v; +} diff --git a/src/plots/cartesian/set_convert.js b/src/plots/cartesian/set_convert.js index 920c06eaf6c..d9d1c8384cd 100644 --- a/src/plots/cartesian/set_convert.js +++ b/src/plots/cartesian/set_convert.js @@ -686,9 +686,7 @@ module.exports = function setConvert(ax, fullLayout) { var isNewBreak = true; for(var j = 0; j < rangebreaksOut.length; j++) { var brkj = rangebreaksOut[j]; - if(min > brkj.max || max < brkj.min) { - // potentially a new break - } else { + if(min < brkj.max && max >= brkj.min) { if(min < brkj.min) { brkj.min = min; } diff --git a/test/image/baselines/axes_breaks-candlestick2.png b/test/image/baselines/axes_breaks-candlestick2.png index 326bf1dd071..e93fee533ae 100644 Binary files a/test/image/baselines/axes_breaks-candlestick2.png and b/test/image/baselines/axes_breaks-candlestick2.png differ diff --git a/test/image/baselines/axes_breaks-dtick_auto.png b/test/image/baselines/axes_breaks-dtick_auto.png new file mode 100644 index 00000000000..18808479908 Binary files /dev/null and b/test/image/baselines/axes_breaks-dtick_auto.png differ diff --git a/test/image/baselines/axes_breaks-dtick_hourly.png b/test/image/baselines/axes_breaks-dtick_hourly.png new file mode 100644 index 00000000000..fc1b38379e3 Binary files /dev/null and b/test/image/baselines/axes_breaks-dtick_hourly.png differ diff --git a/test/image/baselines/axes_breaks-finance.png b/test/image/baselines/axes_breaks-finance.png index 2d6d56d9859..dffbeceebe9 100644 Binary files a/test/image/baselines/axes_breaks-finance.png and b/test/image/baselines/axes_breaks-finance.png differ diff --git a/test/image/baselines/axes_breaks-night_autorange-reversed.png b/test/image/baselines/axes_breaks-night_autorange-reversed.png index 8de472e9a5b..464e78edb37 100644 Binary files a/test/image/baselines/axes_breaks-night_autorange-reversed.png and b/test/image/baselines/axes_breaks-night_autorange-reversed.png differ diff --git a/test/image/baselines/axes_breaks-overlap.png b/test/image/baselines/axes_breaks-overlap.png new file mode 100644 index 00000000000..eed0f683fd7 Binary files /dev/null and b/test/image/baselines/axes_breaks-overlap.png differ diff --git a/test/image/baselines/axes_breaks-rangeslider.png b/test/image/baselines/axes_breaks-rangeslider.png index b606ae82dc2..4b4565951be 100644 Binary files a/test/image/baselines/axes_breaks-rangeslider.png and b/test/image/baselines/axes_breaks-rangeslider.png differ diff --git a/test/image/baselines/axes_breaks-reversed-without-pattern.png b/test/image/baselines/axes_breaks-reversed-without-pattern.png index 010223d9103..497b91fd460 100644 Binary files a/test/image/baselines/axes_breaks-reversed-without-pattern.png and b/test/image/baselines/axes_breaks-reversed-without-pattern.png differ diff --git a/test/image/baselines/axes_breaks-round-weekdays.png b/test/image/baselines/axes_breaks-round-weekdays.png index e24853a9992..9f20ece5dfa 100644 Binary files a/test/image/baselines/axes_breaks-round-weekdays.png and b/test/image/baselines/axes_breaks-round-weekdays.png differ diff --git a/test/image/baselines/axes_breaks-values.png b/test/image/baselines/axes_breaks-values.png index 726043589b7..b3c9e48c6d8 100644 Binary files a/test/image/baselines/axes_breaks-values.png and b/test/image/baselines/axes_breaks-values.png differ diff --git a/test/image/baselines/axes_breaks-weekends-weeknights.png b/test/image/baselines/axes_breaks-weekends-weeknights.png index c0b8991903e..427913aa1f4 100644 Binary files a/test/image/baselines/axes_breaks-weekends-weeknights.png and b/test/image/baselines/axes_breaks-weekends-weeknights.png differ diff --git a/test/image/baselines/axes_breaks.png b/test/image/baselines/axes_breaks.png index 9c05a8f6e7e..722307c1624 100644 Binary files a/test/image/baselines/axes_breaks.png and b/test/image/baselines/axes_breaks.png differ diff --git a/test/image/mocks/axes_breaks-dtick_auto.json b/test/image/mocks/axes_breaks-dtick_auto.json new file mode 100644 index 00000000000..1342f8b6c65 --- /dev/null +++ b/test/image/mocks/axes_breaks-dtick_auto.json @@ -0,0 +1,115 @@ +{ + "data": [ + { + "type": "scatter", + "mode": "markers", + "x": [ + "2020-04-06T09:00:00", + "2020-04-06T10:00:00", + "2020-04-06T11:00:00", + "2020-04-06T12:00:00", + "2020-04-06T13:00:00", + "2020-04-06T14:00:00", + "2020-04-06T15:00:00", + "2020-04-06T16:00:00", + "2020-04-07T09:00:00", + "2020-04-07T10:00:00", + "2020-04-07T11:00:00", + "2020-04-07T12:00:00", + "2020-04-07T13:00:00", + "2020-04-07T14:00:00", + "2020-04-07T15:00:00", + "2020-04-07T16:00:00", + "2020-04-08T09:00:00", + "2020-04-08T10:00:00", + "2020-04-08T11:00:00", + "2020-04-08T12:00:00", + "2020-04-08T13:00:00", + "2020-04-08T14:00:00", + "2020-04-08T15:00:00", + "2020-04-08T16:00:00", + "2020-04-09T09:00:00", + "2020-04-09T10:00:00", + "2020-04-09T11:00:00", + "2020-04-09T12:00:00", + "2020-04-09T13:00:00", + "2020-04-09T14:00:00", + "2020-04-09T15:00:00", + "2020-04-09T16:00:00", + "2020-04-10T09:00:00", + "2020-04-10T10:00:00", + "2020-04-10T11:00:00", + "2020-04-10T12:00:00", + "2020-04-10T13:00:00", + "2020-04-10T14:00:00", + "2020-04-10T15:00:00", + "2020-04-10T16:00:00" + ], + "y": [ + 0.19742877314456364, + 0.1509714558226325, + 0.3730270552929804, + 0.7394093812216096, + 1.2149308862244954, + 1.5707342286171064, + 1.0824483128021085, + 0.9424263772804724, + 1.1724169397045303, + 0.8440466169659708, + 0.8650832231701001, + 0.41942121150935374, + 0.11941773640575382, + -0.3620604691336322, + -0.06836276577621159, + -0.34443807771583146, + -0.49908639701892876, + -0.07100510355333789, + 0.13340929837019488, + -0.33475177209849727, + -0.6700576156005845, + -0.548579214100821, + -0.4713506254966534, + -0.7334578041221448, + -0.299243806197351, + -0.18527785023145504, + -0.14964504720649674, + -0.05973507085192575, + 0.17038695866484388, + -0.01766804585555426, + -0.11944698363946238, + -0.40960323466434023, + -0.7234102287840041, + -0.2790378388000705, + -0.039487043750782935, + -0.04902823513321586, + -0.3216136071598926, + -0.5672571253894997, + -1.009227965065624, + -1.0748113395075032 + ] + } + ], + "layout": { + "width": 800, + "height": 600, + "xaxis": { + "rangebreaks": [ + { + "bounds": [ + 17, + 9 + ], + "pattern": "hour" + } + ], + "title": { + "text": "time" + } + }, + "yaxis": { + "title": { + "text": "values" + } + } + } +} diff --git a/test/image/mocks/axes_breaks-dtick_hourly.json b/test/image/mocks/axes_breaks-dtick_hourly.json new file mode 100644 index 00000000000..ca001b774ae --- /dev/null +++ b/test/image/mocks/axes_breaks-dtick_hourly.json @@ -0,0 +1,116 @@ +{ + "data": [ + { + "type": "scatter", + "mode": "markers", + "x": [ + "2020-04-06T09:00:00", + "2020-04-06T10:00:00", + "2020-04-06T11:00:00", + "2020-04-06T12:00:00", + "2020-04-06T13:00:00", + "2020-04-06T14:00:00", + "2020-04-06T15:00:00", + "2020-04-06T16:00:00", + "2020-04-07T09:00:00", + "2020-04-07T10:00:00", + "2020-04-07T11:00:00", + "2020-04-07T12:00:00", + "2020-04-07T13:00:00", + "2020-04-07T14:00:00", + "2020-04-07T15:00:00", + "2020-04-07T16:00:00", + "2020-04-08T09:00:00", + "2020-04-08T10:00:00", + "2020-04-08T11:00:00", + "2020-04-08T12:00:00", + "2020-04-08T13:00:00", + "2020-04-08T14:00:00", + "2020-04-08T15:00:00", + "2020-04-08T16:00:00", + "2020-04-09T09:00:00", + "2020-04-09T10:00:00", + "2020-04-09T11:00:00", + "2020-04-09T12:00:00", + "2020-04-09T13:00:00", + "2020-04-09T14:00:00", + "2020-04-09T15:00:00", + "2020-04-09T16:00:00", + "2020-04-10T09:00:00", + "2020-04-10T10:00:00", + "2020-04-10T11:00:00", + "2020-04-10T12:00:00", + "2020-04-10T13:00:00", + "2020-04-10T14:00:00", + "2020-04-10T15:00:00", + "2020-04-10T16:00:00" + ], + "y": [ + 0.19742877314456364, + 0.1509714558226325, + 0.3730270552929804, + 0.7394093812216096, + 1.2149308862244954, + 1.5707342286171064, + 1.0824483128021085, + 0.9424263772804724, + 1.1724169397045303, + 0.8440466169659708, + 0.8650832231701001, + 0.41942121150935374, + 0.11941773640575382, + -0.3620604691336322, + -0.06836276577621159, + -0.34443807771583146, + -0.49908639701892876, + -0.07100510355333789, + 0.13340929837019488, + -0.33475177209849727, + -0.6700576156005845, + -0.548579214100821, + -0.4713506254966534, + -0.7334578041221448, + -0.299243806197351, + -0.18527785023145504, + -0.14964504720649674, + -0.05973507085192575, + 0.17038695866484388, + -0.01766804585555426, + -0.11944698363946238, + -0.40960323466434023, + -0.7234102287840041, + -0.2790378388000705, + -0.039487043750782935, + -0.04902823513321586, + -0.3216136071598926, + -0.5672571253894997, + -1.009227965065624, + -1.0748113395075032 + ] + } + ], + "layout": { + "width": 800, + "height": 600, + "xaxis": { + "dtick": 3600000, + "rangebreaks": [ + { + "bounds": [ + 17, + 9 + ], + "pattern": "hour" + } + ], + "title": { + "text": "time" + } + }, + "yaxis": { + "title": { + "text": "values" + } + } + } +} diff --git a/test/image/mocks/axes_breaks-overlap.json b/test/image/mocks/axes_breaks-overlap.json new file mode 100644 index 00000000000..a0bc9ad5ee2 --- /dev/null +++ b/test/image/mocks/axes_breaks-overlap.json @@ -0,0 +1,207 @@ +{ + "data": [ + { + "x": [ + "2020-05-19", + "2020-05-20", + "2020-05-21", + "2020-05-22", + "2020-05-23", + "2020-05-24", + "2020-05-25", + "2020-05-26", + "2020-05-27", + "2020-05-28" + ] + }, + { + "xaxis": "x2", + "yaxis": "y2", + "x": [ + "2020-05-19", + "2020-05-20", + "2020-05-21", + "2020-05-22", + "2020-05-23", + "2020-05-24", + "2020-05-25", + "2020-05-26", + "2020-05-27", + "2020-05-28" + ] + }, + { + "xaxis": "x3", + "yaxis": "y3", + "y": [ + "2020-05-19", + "2020-05-20", + "2020-05-21", + "2020-05-22", + "2020-05-23", + "2020-05-24", + "2020-05-25", + "2020-05-26", + "2020-05-27", + "2020-05-28" + ] + }, + { + "xaxis": "x4", + "yaxis": "y4", + "y": [ + "2020-05-19", + "2020-05-20", + "2020-05-21", + "2020-05-22", + "2020-05-23", + "2020-05-24", + "2020-05-25", + "2020-05-26", + "2020-05-27", + "2020-05-28" + ] + } + ], + "layout": { + "showlegend": false, + "width": 800, + "height": 800, + "xaxis": { + "rangebreaks": [ + { + "bounds": [ + "sat", + "mon" + ] + }, + { + "values": [ + "2020-05-21", + "2020-05-22" + ] + }, + { + "values": [ + "2020-05-25", + "2020-05-26" + ] + } + ], + "domain": [ + 0, + 0.48 + ] + }, + "xaxis2": { + "rangebreaks": [ + { + "bounds": [ + "sat", + "mon" + ] + }, + { + "values": [ + "2020-05-21", + "2020-05-22" + ] + }, + { + "values": [ + "2020-05-25", + "2020-05-26" + ] + } + ], + "autorange": "reversed", + "anchor": "y2", + "domain": [ + 0.52, + 1 + ] + }, + "xaxis3": { + "anchor": "y3", + "domain": [ + 0, + 0.48 + ] + }, + "xaxis4": { + "anchor": "y4", + "domain": [ + 0.52, + 1 + ] + }, + "yaxis": { + "domain": [ + 0, + 0.48 + ] + }, + "yaxis2": { + "anchor": "x2", + "domain": [ + 0.52, + 1 + ] + }, + "yaxis3": { + "rangebreaks": [ + { + "bounds": [ + "sat", + "mon" + ] + }, + { + "values": [ + "2020-05-21", + "2020-05-22" + ] + }, + { + "values": [ + "2020-05-25", + "2020-05-26" + ] + } + ], + "anchor": "x3", + "domain": [ + 0.52, + 1 + ] + }, + "yaxis4": { + "rangebreaks": [ + { + "bounds": [ + "sat", + "mon" + ] + }, + { + "values": [ + "2020-05-21", + "2020-05-22" + ] + }, + { + "values": [ + "2020-05-25", + "2020-05-26" + ] + } + ], + "autorange": "reversed", + "anchor": "x4", + "domain": [ + 0, + 0.48 + ] + } + } +} diff --git a/test/jasmine/tests/axes_test.js b/test/jasmine/tests/axes_test.js index ed36147de3e..dc12f3e812a 100644 --- a/test/jasmine/tests/axes_test.js +++ b/test/jasmine/tests/axes_test.js @@ -1906,7 +1906,7 @@ describe('Test axes', function() { expect(axIn.tickmode).toBeUndefined(); }); - it(woTemplate + 'should set nticks iff tickmode=auto', function() { + it(woTemplate + 'should set nticks if tickmode=auto', function() { var axIn = {}; var axOut = {}; mockSupplyDefaults(axIn, axOut, 'linear'); @@ -1923,7 +1923,7 @@ describe('Test axes', function() { expect(axOut.nticks).toBe(undefined); }); - it(woTemplate + 'should set tick0 and dtick iff tickmode=linear', function() { + it(woTemplate + 'should set tick0 and dtick if tickmode=linear', function() { var axIn = {tickmode: 'auto', tick0: 1, dtick: 1}; var axOut = {}; mockSupplyDefaults(axIn, axOut, 'linear'); @@ -2040,7 +2040,7 @@ describe('Test axes', function() { }); }); - it(woTemplate + 'should set tickvals and ticktext iff tickmode=array', function() { + it(woTemplate + 'should set tickvals and ticktext if tickmode=array', function() { var axIn = {tickmode: 'auto', tickvals: [1, 2, 3], ticktext: ['4', '5', '6']}; var axOut = {}; mockSupplyDefaults(axIn, axOut, 'linear'); @@ -4977,7 +4977,7 @@ describe('Test axes', function() { .withContext(msg).toEqual(exp.tickVals); } - it('should include requested ticks that fall within rangebreaks', function(done) { + it('should not include requested ticks that fall within rangebreaks', function(done) { Plotly.plot(gd, [{ x: [ '1970-01-01 00:00:00.000', @@ -5016,12 +5016,136 @@ describe('Test axes', function() { }) .then(function() { _assert('with two rangebreaks', { - tickVals: [0, 5, 10, 90, 95, 100, 190, 195, 200] + tickVals: [0, 5, 90, 95, 190, 195, 200] }); }) .catch(failTest) .then(done); }); + + [true, 'reversed'].forEach(function(autorange) { + it('with ' + autorange + ' autorange, should include requested ticks using tick0 and dtick with rangebreaks', function(done) { + var fig = { + data: [{ + x: [ + '1970-01-01 06:00', '1970-01-01 07:00', '1970-01-01 08:00', '1970-01-01 09:00', '1970-01-01 10:00', '1970-01-01 11:00', '1970-01-01 12:00', '1970-01-01 13:00', '1970-01-01 14:00', '1970-01-01 15:00', '1970-01-01 16:00', '1970-01-01 17:00', '1970-01-01 18:00', + '1970-01-02 06:00', '1970-01-02 07:00', '1970-01-02 08:00', '1970-01-02 09:00', '1970-01-02 10:00', '1970-01-02 11:00', '1970-01-02 12:00', '1970-01-02 13:00', '1970-01-02 14:00', '1970-01-02 15:00', '1970-01-02 16:00', '1970-01-02 17:00', '1970-01-02 18:00', + '1970-01-03 06:00', '1970-01-03 07:00', '1970-01-03 08:00', '1970-01-03 09:00', '1970-01-03 10:00', '1970-01-03 11:00', '1970-01-03 12:00', '1970-01-03 13:00', '1970-01-03 14:00', '1970-01-03 15:00', '1970-01-03 16:00', '1970-01-03 17:00', '1970-01-03 18:00', + '1970-01-04 06:00', '1970-01-04 07:00', '1970-01-04 08:00', '1970-01-04 09:00', '1970-01-04 10:00', '1970-01-04 11:00', '1970-01-04 12:00', '1970-01-04 13:00', '1970-01-04 14:00', '1970-01-04 15:00', '1970-01-04 16:00', '1970-01-04 17:00', '1970-01-04 18:00', + '1970-01-05 06:00', '1970-01-05 07:00', '1970-01-05 08:00', '1970-01-05 09:00', '1970-01-05 10:00', '1970-01-05 11:00', '1970-01-05 12:00', '1970-01-05 13:00', '1970-01-05 14:00', '1970-01-05 15:00', '1970-01-05 16:00', '1970-01-05 17:00', '1970-01-05 18:00', + '1970-01-06 06:00', '1970-01-06 07:00', '1970-01-06 08:00', '1970-01-06 09:00', '1970-01-06 10:00', '1970-01-06 11:00', '1970-01-06 12:00', '1970-01-06 13:00', '1970-01-06 14:00', '1970-01-06 15:00', '1970-01-06 16:00', '1970-01-06 17:00', '1970-01-06 18:00', + '1970-01-07 06:00', '1970-01-07 07:00', '1970-01-07 08:00', '1970-01-07 09:00', '1970-01-07 10:00', '1970-01-07 11:00', '1970-01-07 12:00', '1970-01-07 13:00', '1970-01-07 14:00', '1970-01-07 15:00', '1970-01-07 16:00', '1970-01-07 17:00', '1970-01-07 18:00', + '1970-01-08 06:00', '1970-01-08 07:00', '1970-01-08 08:00', '1970-01-08 09:00', '1970-01-08 10:00', '1970-01-08 11:00', '1970-01-08 12:00', '1970-01-08 13:00', '1970-01-08 14:00', '1970-01-08 15:00', '1970-01-08 16:00', '1970-01-08 17:00', '1970-01-08 18:00', + '1970-01-09 06:00', '1970-01-09 07:00', '1970-01-09 08:00', '1970-01-09 09:00', '1970-01-09 10:00', '1970-01-09 11:00', '1970-01-09 12:00', '1970-01-09 13:00', '1970-01-09 14:00', '1970-01-09 15:00', '1970-01-09 16:00', '1970-01-09 17:00', '1970-01-09 18:00', + '1970-01-10 06:00', '1970-01-10 07:00', '1970-01-10 08:00', '1970-01-10 09:00', '1970-01-10 10:00', '1970-01-10 11:00', '1970-01-10 12:00', '1970-01-10 13:00', '1970-01-10 14:00', '1970-01-10 15:00', '1970-01-10 16:00', '1970-01-10 17:00', '1970-01-10 18:00', + '1970-01-11 06:00', '1970-01-11 07:00', '1970-01-11 08:00', '1970-01-11 09:00', '1970-01-11 10:00', '1970-01-11 11:00', '1970-01-11 12:00', '1970-01-11 13:00', '1970-01-11 14:00', '1970-01-11 15:00', '1970-01-11 16:00', '1970-01-11 17:00', '1970-01-11 18:00', + '1970-01-12 06:00', '1970-01-12 07:00', '1970-01-12 08:00', '1970-01-12 09:00', '1970-01-12 10:00', '1970-01-12 11:00', '1970-01-12 12:00', '1970-01-12 13:00', '1970-01-12 14:00', '1970-01-12 15:00', '1970-01-12 16:00', '1970-01-12 17:00', '1970-01-12 18:00', + '1970-01-13 06:00', '1970-01-13 07:00', '1970-01-13 08:00', '1970-01-13 09:00', '1970-01-13 10:00', '1970-01-13 11:00', '1970-01-13 12:00', '1970-01-13 13:00', '1970-01-13 14:00', '1970-01-13 15:00', '1970-01-13 16:00', '1970-01-13 17:00', '1970-01-13 18:00', + '1970-01-14 06:00', '1970-01-14 07:00', '1970-01-14 08:00', '1970-01-14 09:00', '1970-01-14 10:00', '1970-01-14 11:00', '1970-01-14 12:00', '1970-01-14 13:00', '1970-01-14 14:00', '1970-01-14 15:00', '1970-01-14 16:00', '1970-01-14 17:00', '1970-01-14 18:00' + ] + }], + layout: { + width: 1600, + height: 1600 + } + }; + + fig.layout.xaxis = { + autorange: autorange, + tick0: '1970-01-01 08:00', + dtick: 4 * 60 * 60 * 1000, + rangebreaks: [{ + bounds: [ 17, 8 ], + pattern: 'hour' + }, { + bounds: [ 6, 1 ], + pattern: 'day of week' + }] + }; + + Plotly.newPlot(gd, fig) + .then(function() { + _assert('base', { + tickVals: [ + '1970-01-01 08:00', '1970-01-01 12:00', '1970-01-01 16:00', + '1970-01-02 08:00', '1970-01-02 12:00', '1970-01-02 16:00', + '1970-01-05 08:00', '1970-01-05 12:00', '1970-01-05 16:00', + '1970-01-06 08:00', '1970-01-06 12:00', '1970-01-06 16:00', + '1970-01-07 08:00', '1970-01-07 12:00', '1970-01-07 16:00', + '1970-01-08 08:00', '1970-01-08 12:00', '1970-01-08 16:00', + '1970-01-09 08:00', '1970-01-09 12:00', '1970-01-09 16:00', + '1970-01-12 08:00', '1970-01-12 12:00', '1970-01-12 16:00', + '1970-01-13 08:00', '1970-01-13 12:00', '1970-01-13 16:00', + '1970-01-14 08:00', '1970-01-14 12:00', '1970-01-14 16:00' + ].map(Lib.dateTime2ms) + }); + }) + .then(function() { + fig.layout.xaxis = { + autorange: autorange, + tick0: '1970-01-01 08:00', + dtick: 3 * 60 * 60 * 1000, + rangebreaks: [{ + bounds: [ 17, 8 ], + pattern: 'hour' + }, { + bounds: [ 6, 1 ], + pattern: 'day of week' + }] + }; + return Plotly.newPlot(gd, gd.data, gd.layout); + }) + .then(function() { + _assert('3-hour dtick', { + tickVals: [ + '1970-01-01 08:00', '1970-01-01 11:00', '1970-01-01 14:00', + '1970-01-02 08:00', '1970-01-02 11:00', '1970-01-02 14:00', + '1970-01-05 08:00', '1970-01-05 11:00', '1970-01-05 14:00', + '1970-01-06 08:00', '1970-01-06 11:00', '1970-01-06 14:00', + '1970-01-07 08:00', '1970-01-07 11:00', '1970-01-07 14:00', + '1970-01-08 08:00', '1970-01-08 11:00', '1970-01-08 14:00', + '1970-01-09 08:00', '1970-01-09 11:00', '1970-01-09 14:00', + '1970-01-12 08:00', '1970-01-12 11:00', '1970-01-12 14:00', + '1970-01-13 08:00', '1970-01-13 11:00', '1970-01-13 14:00', + '1970-01-14 08:00', '1970-01-14 11:00', '1970-01-14 14:00' + ].map(Lib.dateTime2ms) + }); + }) + .then(function() { + fig.layout.xaxis = { + autorange: autorange, + tick0: '1970-01-01 08:00', + dtick: 2 * 60 * 60 * 1000, + rangebreaks: [{ + bounds: [ 17, 8 ], + pattern: 'hour' + }, { + bounds: [ 6, 1 ], + pattern: 'day of week' + }] + }; + return Plotly.newPlot(gd, gd.data, gd.layout); + }) + .then(function() { + _assert('2-hour dtick', { + tickVals: [ + '1970-01-01 08:00', '1970-01-01 10:00', '1970-01-01 12:00', '1970-01-01 14:00', '1970-01-01 16:00', + '1970-01-02 08:00', '1970-01-02 10:00', '1970-01-02 12:00', '1970-01-02 14:00', '1970-01-02 16:00', + '1970-01-05 08:00', '1970-01-05 10:00', '1970-01-05 12:00', '1970-01-05 14:00', '1970-01-05 16:00', + '1970-01-06 08:00', '1970-01-06 10:00', '1970-01-06 12:00', '1970-01-06 14:00', '1970-01-06 16:00', + '1970-01-07 08:00', '1970-01-07 10:00', '1970-01-07 12:00', '1970-01-07 14:00', '1970-01-07 16:00', + '1970-01-08 08:00', '1970-01-08 10:00', '1970-01-08 12:00', '1970-01-08 14:00', '1970-01-08 16:00', + '1970-01-09 08:00', '1970-01-09 10:00', '1970-01-09 12:00', '1970-01-09 14:00', '1970-01-09 16:00', + '1970-01-12 08:00', '1970-01-12 10:00', '1970-01-12 12:00', '1970-01-12 14:00', '1970-01-12 16:00', + '1970-01-13 08:00', '1970-01-13 10:00', '1970-01-13 12:00', '1970-01-13 14:00', '1970-01-13 16:00', + '1970-01-14 08:00', '1970-01-14 10:00', '1970-01-14 12:00', '1970-01-14 14:00', '1970-01-14 16:00' + ].map(Lib.dateTime2ms) + }); + }) + .catch(failTest) + .then(done); + }); + }); }); it('should set visible:false in scattergl traces on axis with rangebreaks', function(done) { diff --git a/test/jasmine/tests/mock_test.js b/test/jasmine/tests/mock_test.js index 0685d8f6001..1aba1dd0d82 100644 --- a/test/jasmine/tests/mock_test.js +++ b/test/jasmine/tests/mock_test.js @@ -54,12 +54,15 @@ var list = [ 'axes_breaks-candlestick2', 'axes_breaks-contour1d', 'axes_breaks-contour2d', + 'axes_breaks-dtick_auto', + 'axes_breaks-dtick_hourly', 'axes_breaks-finance', 'axes_breaks-gridlines', 'axes_breaks-heatmap1d', 'axes_breaks-heatmap2d', 'axes_breaks-histogram2d', 'axes_breaks-night_autorange-reversed', + 'axes_breaks-overlap', 'axes_breaks-rangeslider', 'axes_breaks-reversed-without-pattern', 'axes_breaks-round-weekdays', @@ -1089,12 +1092,15 @@ figs['axes_breaks-candlestick'] = require('@mocks/axes_breaks-candlestick'); figs['axes_breaks-candlestick2'] = require('@mocks/axes_breaks-candlestick2'); figs['axes_breaks-contour1d'] = require('@mocks/axes_breaks-contour1d'); figs['axes_breaks-contour2d'] = require('@mocks/axes_breaks-contour2d'); +figs['axes_breaks-dtick_auto'] = require('@mocks/axes_breaks-dtick_auto'); +figs['axes_breaks-dtick_hourly'] = require('@mocks/axes_breaks-dtick_hourly'); figs['axes_breaks-finance'] = require('@mocks/axes_breaks-finance'); figs['axes_breaks-gridlines'] = require('@mocks/axes_breaks-gridlines'); figs['axes_breaks-heatmap1d'] = require('@mocks/axes_breaks-heatmap1d'); figs['axes_breaks-heatmap2d'] = require('@mocks/axes_breaks-heatmap2d'); figs['axes_breaks-histogram2d'] = require('@mocks/axes_breaks-histogram2d'); figs['axes_breaks-night_autorange-reversed'] = require('@mocks/axes_breaks-night_autorange-reversed'); +figs['axes_breaks-overlap'] = require('@mocks/axes_breaks-overlap'); figs['axes_breaks-rangeslider'] = require('@mocks/axes_breaks-rangeslider'); figs['axes_breaks-reversed-without-pattern'] = require('@mocks/axes_breaks-reversed-without-pattern'); figs['axes_breaks-round-weekdays'] = require('@mocks/axes_breaks-round-weekdays');