From 9c619b5fae3e8d6cbb24737a6f20c172fd62f356 Mon Sep 17 00:00:00 2001 From: seshan18 Date: Mon, 21 Sep 2026 15:34:13 +0530 Subject: [PATCH] feat: add `minrange` autorange option to enforce a minimum axis span --- src/plots/cartesian/autorange.js | 222 +- .../cartesian/autorange_options_defaults.js | 6 +- src/plots/gl3d/layout/axis_attributes.js | 6 +- src/plots/polar/layout_attributes.js | 28 +- src/types/generated/schema.d.ts | 5 + test/jasmine/tests/axes_test.js | 5153 +++++++++-------- test/plot-schema.json | 42 + 7 files changed, 2780 insertions(+), 2682 deletions(-) diff --git a/src/plots/cartesian/autorange.js b/src/plots/cartesian/autorange.js index 9113cd855d4..0877f2f76ed 100644 --- a/src/plots/cartesian/autorange.js +++ b/src/plots/cartesian/autorange.js @@ -60,19 +60,19 @@ function getAutoRange(gd, ax) { var minArray = extremes.min; var maxArray = extremes.max; - if(minArray.length === 0 || maxArray.length === 0) { + if (minArray.length === 0 || maxArray.length === 0) { return Lib.simpleMap(ax.range, ax.r2l); } var minmin = minArray[0].val; var maxmax = maxArray[0].val; - for(i = 1; i < minArray.length; i++) { - if(minmin !== maxmax) break; + for (i = 1; i < minArray.length; i++) { + if (minmin !== maxmax) break; minmin = Math.min(minmin, minArray[i].val); } - for(i = 1; i < maxArray.length; i++) { - if(minmin !== maxmax) break; + for (i = 1; i < maxArray.length; i++) { + if (minmin !== maxmax) break; maxmax = Math.max(maxmax, maxArray[i].val); } @@ -82,14 +82,14 @@ function getAutoRange(gd, ax) { autorange === 'min reversed' || autorange === 'max reversed'; - if(!axReverse && ax.range) { + if (!axReverse && ax.range) { var rng = Lib.simpleMap(ax.range, ax.r2l); axReverse = rng[1] < rng[0]; } // one-time setting to easily reverse the axis // when plotting from code - if(ax.autorange === 'reversed') { + if (ax.autorange === 'reversed') { ax.autorange = true; } @@ -103,24 +103,24 @@ function getAutoRange(gd, ax) { var mbest = 0; var minpt, maxpt, minbest, maxbest, dp, dv; - for(i = 0; i < minArray.length; i++) { + for (i = 0; i < minArray.length; i++) { minpt = minArray[i]; - for(j = 0; j < maxArray.length; j++) { + for (j = 0; j < maxArray.length; j++) { maxpt = maxArray[j]; dv = maxpt.val - minpt.val - calcBreaksLength(ax, minpt.val, maxpt.val); - if(dv > 0) { + if (dv > 0) { dp = axLen - getPadMin(minpt) - getPadMax(maxpt); - if(dp > minSpan) { - if(dv / dp > mbest) { + if (dp > minSpan) { + if (dv / dp > mbest) { minbest = minpt; maxbest = maxpt; mbest = dv / dp; } - } else if(dv / axLen > mbest) { + } else if (dv / axLen > mbest) { // in case of padding longer than the axis // at least include the unpadded data values. - minbest = {val: minpt.val, nopad: 1}; - maxbest = {val: maxpt.val, nopad: 1}; + minbest = { val: minpt.val, nopad: 1 }; + maxbest = { val: maxpt.val, nopad: 1 }; mbest = dv / axLen; } } @@ -131,11 +131,11 @@ function getAutoRange(gd, ax) { return Math.max(prev, getPadMax(pt)); } - if(minmin === maxmax) { + if (minmin === maxmax) { var lower = minmin - 1; var upper = minmin + 1; - if(toZero) { - if(minmin === 0) { + if (toZero) { + if (minmin === 0) { // The only value we have on this axis is 0, and we want to // autorange so zero is one end. // In principle this could be [0, 1] or [-1, 0] but usually @@ -149,25 +149,25 @@ function getAutoRange(gd, ax) { var rangeEnd = minmin / (1 - Math.min(0.5, maxPad / axLen)); newRange = minmin > 0 ? [0, rangeEnd] : [rangeEnd, 0]; } - } else if(nonNegative) { + } else if (nonNegative) { newRange = [Math.max(0, lower), Math.max(1, upper)]; } else { newRange = [lower, upper]; } } else { - if(toZero) { - if(minbest.val >= 0) { - minbest = {val: 0, nopad: 1}; + if (toZero) { + if (minbest.val >= 0) { + minbest = { val: 0, nopad: 1 }; } - if(maxbest.val <= 0) { - maxbest = {val: 0, nopad: 1}; + if (maxbest.val <= 0) { + maxbest = { val: 0, nopad: 1 }; } - } else if(nonNegative) { - if(minbest.val - mbest * getPadMin(minbest) < 0) { - minbest = {val: 0, nopad: 1}; + } else if (nonNegative) { + if (minbest.val - mbest * getPadMin(minbest) < 0) { + minbest = { val: 0, nopad: 1 }; } - if(maxbest.val <= 0) { - maxbest = {val: 1, nopad: 1}; + if (maxbest.val <= 0) { + maxbest = { val: 1, nopad: 1 }; } } @@ -183,10 +183,10 @@ function getAutoRange(gd, ax) { newRange = applyAutorangeOptions(newRange, ax); - if(ax.limitRange) ax.limitRange(); + if (ax.limitRange) ax.limitRange(); // maintain reversal - if(axReverse) newRange.reverse(); + if (axReverse) newRange.reverse(); return Lib.simpleMap(newRange, ax.l2r || Number); } @@ -194,9 +194,9 @@ function getAutoRange(gd, ax) { // find axis rangebreaks in [v0,v1] and compute its length in value space function calcBreaksLength(ax, v0, v1) { var lBreaks = 0; - if(ax.rangebreaks) { + if (ax.rangebreaks) { var rangebreaksOut = ax.locateBreaks(v0, v1); - for(var i = 0; i < rangebreaksOut.length; i++) { + for (var i = 0; i < rangebreaksOut.length; i++) { var brk = rangebreaksOut[i]; lBreaks += brk.max - brk.min; } @@ -214,33 +214,33 @@ function makePadFn(fullLayout, ax, max) { var anchorAxis = ax._anchorAxis || {}; - if( + if ( (ax.ticklabelposition || '').indexOf('inside') !== -1 || (anchorAxis.ticklabelposition || '').indexOf('inside') !== -1 ) { var axReverse = ax.isReversed(); - if(!axReverse) { + if (!axReverse) { var rng = Lib.simpleMap(ax.range, ax.r2l); axReverse = rng[1] < rng[0]; } - if(axReverse) max = !max; + if (axReverse) max = !max; } var zero = 0; - if(!isLinked(fullLayout, ax._id)) { + if (!isLinked(fullLayout, ax._id)) { zero = padInsideLabelsOnAnchorAxis(fullLayout, ax, max); } extrappad = Math.max(zero, extrappad); // domain-constrained axes: base extrappad on the unconstrained // domain so it's consistent as the domain changes - if((ax.constrain === 'domain') && ax._inputDomain) { + if ((ax.constrain === 'domain') && ax._inputDomain) { extrappad *= (ax._inputDomain[1] - ax._inputDomain[0]) / (ax.domain[1] - ax.domain[0]); } return function getPad(pt) { - if(pt.nopad) return 0; + if (pt.nopad) return 0; return pt.pad + (pt.extrapad ? extrappad : zero); }; } @@ -252,50 +252,50 @@ function padInsideLabelsOnAnchorAxis(fullLayout, ax, max) { var isX = ax._id.charAt(0) === 'x'; - for(var subplot in fullLayout._plots) { + for (var subplot in fullLayout._plots) { var plotinfo = fullLayout._plots[subplot]; - if(ax._id !== plotinfo.xaxis._id && ax._id !== plotinfo.yaxis._id) continue; + if (ax._id !== plotinfo.xaxis._id && ax._id !== plotinfo.yaxis._id) continue; var anchorAxis = (isX ? plotinfo.yaxis : plotinfo.xaxis) || {}; - if((anchorAxis.ticklabelposition || '').indexOf('inside') !== -1) { + if ((anchorAxis.ticklabelposition || '').indexOf('inside') !== -1) { // increase padding to make more room for inside tick labels of the counter axis - if(( + if (( !max && ( anchorAxis.side === 'left' || anchorAxis.side === 'bottom' ) ) || ( - max && ( - anchorAxis.side === 'top' || - anchorAxis.side === 'right' - ) - )) { - if(anchorAxis._vals) { + max && ( + anchorAxis.side === 'top' || + anchorAxis.side === 'right' + ) + )) { + if (anchorAxis._vals) { var rad = Lib.deg2rad(anchorAxis._tickAngles[anchorAxis._id + 'tick'] || 0); var cosA = Math.abs(Math.cos(rad)); var sinA = Math.abs(Math.sin(rad)); // no stashed bounding boxes - stash bounding boxes - if(!anchorAxis._vals[0].bb) { + if (!anchorAxis._vals[0].bb) { var cls = anchorAxis._id + 'tick'; var tickLabels = anchorAxis._selections[cls]; - tickLabels.each(function(d) { + tickLabels.each(function (d) { var thisLabel = d3.select(this); var mathjaxGroup = thisLabel.select('.text-math-group'); - if(mathjaxGroup.empty()) { + if (mathjaxGroup.empty()) { d.bb = Drawing.bBox(thisLabel.node()); } }); } // use bounding boxes - for(var i = 0; i < anchorAxis._vals.length; i++) { + for (var i = 0; i < anchorAxis._vals.length; i++) { var t = anchorAxis._vals[i]; var bb = t.bb; - if(bb) { + if (bb) { var w = 2 * TEXTPAD + bb.width; var h = 2 * TEXTPAD + bb.height; @@ -307,7 +307,7 @@ function padInsideLabelsOnAnchorAxis(fullLayout, ax, max) { } } - if(anchorAxis.ticks === 'inside' && anchorAxis.ticklabelposition === 'inside') { + if (anchorAxis.ticks === 'inside' && anchorAxis.ticklabelposition === 'inside') { pad += anchorAxis.ticklen || 0; } } @@ -326,17 +326,17 @@ function concatExtremes(gd, ax, noMatch) { var i, j, d; function _concat(cont, indices) { - for(i = 0; i < indices.length; i++) { + for (i = 0; i < indices.length; i++) { var item = cont[indices[i]]; var extremes = (item._extremes || {})[axId]; - if(item.visible === true && extremes) { - for(j = 0; j < extremes.min.length; j++) { + if (item.visible === true && extremes) { + for (j = 0; j < extremes.min.length; j++) { d = extremes.min[j]; - collapseMinArray(minArray, d.val, d.pad, {extrapad: d.extrapad}); + collapseMinArray(minArray, d.val, d.pad, { extrapad: d.extrapad }); } - for(j = 0; j < extremes.max.length; j++) { + for (j = 0; j < extremes.max.length; j++) { d = extremes.max[j]; - collapseMaxArray(maxArray, d.val, d.pad, {extrapad: d.extrapad}); + collapseMaxArray(maxArray, d.val, d.pad, { extrapad: d.extrapad }); } } } @@ -347,32 +347,32 @@ function concatExtremes(gd, ax, noMatch) { _concat(fullLayout.shapes || [], ax._shapeIndices || []); // Include the extremes from other matched axes with this one - if(ax._matchGroup && !noMatch) { - for(var axId2 in ax._matchGroup) { - if(axId2 !== ax._id) { + if (ax._matchGroup && !noMatch) { + for (var axId2 in ax._matchGroup) { + if (axId2 !== ax._id) { var ax2 = getFromId(gd, axId2); var extremes2 = concatExtremes(gd, ax2, true); // convert padding on the second axis to the first with lenRatio var lenRatio = ax._length / ax2._length; - for(j = 0; j < extremes2.min.length; j++) { + for (j = 0; j < extremes2.min.length; j++) { d = extremes2.min[j]; - collapseMinArray(minArray, d.val, d.pad * lenRatio, {extrapad: d.extrapad}); + collapseMinArray(minArray, d.val, d.pad * lenRatio, { extrapad: d.extrapad }); } - for(j = 0; j < extremes2.max.length; j++) { + for (j = 0; j < extremes2.max.length; j++) { d = extremes2.max[j]; - collapseMaxArray(maxArray, d.val, d.pad * lenRatio, {extrapad: d.extrapad}); + collapseMaxArray(maxArray, d.val, d.pad * lenRatio, { extrapad: d.extrapad }); } } } } - return {min: minArray, max: maxArray}; + return { min: minArray, max: maxArray }; } function doAutoRange(gd, ax, presetRange) { ax.setScale(); - if(ax.autorange) { + if (ax.autorange) { ax.range = presetRange ? presetRange.slice() : getAutoRange(gd, ax); ax._r = ax.range.slice(); @@ -395,10 +395,10 @@ function doAutoRange(gd, ax, presetRange) { var anchorAx = ax._anchorAxis; - if(anchorAx && anchorAx.rangeslider) { + if (anchorAx && anchorAx.rangeslider) { var axeRangeOpts = anchorAx.rangeslider[ax._name]; - if(axeRangeOpts) { - if(axeRangeOpts.rangemode === 'auto') { + if (axeRangeOpts) { + if (axeRangeOpts.rangemode === 'auto') { axeRangeOpts.range = getAutoRange(gd, ax); } } @@ -448,8 +448,8 @@ function doAutoRange(gd, ax, presetRange) { * - opts {object}: a ref to the passed "options" object */ function findExtremes(ax, data, opts) { - if(!opts) opts = {}; - if(!ax._m) ax.setScale(); + if (!opts) opts = {}; + if (!ax._m) ax.setScale(); var minArray = []; var maxArray = []; @@ -463,12 +463,12 @@ function findExtremes(ax, data, opts) { var i, v, di, dmin, dmax, ppadiplus, ppadiminus, vmin, vmax; function makePadAccessor(item) { - if(Array.isArray(item)) { + if (Array.isArray(item)) { hasArrayOption = true; - return function(i) { return Math.max(Number(item[i]||0), 0); }; + return function (i) { return Math.max(Number(item[i] || 0), 0); }; } else { - var v = Math.max(Number(item||0), 0); - return function() { return v; }; + var v = Math.max(Number(item || 0), 0); + return function () { return v; }; } } @@ -479,24 +479,24 @@ function findExtremes(ax, data, opts) { var vpadplus = makePadAccessor(opts.vpadplus || opts.vpad); var vpadminus = makePadAccessor(opts.vpadminus || opts.vpad); - if(!hasArrayOption) { + if (!hasArrayOption) { // with no arrays other than `data` we don't need to consider // every point, only the extreme data points vmin = Infinity; vmax = -Infinity; - if(isLog) { - for(i = 0; i < len; i++) { + if (isLog) { + for (i = 0; i < len; i++) { v = data[i]; // data is not linearized yet so we still have to filter out negative logs - if(v < vmin && v > 0) vmin = v; - if(v > vmax && v < FP_SAFE) vmax = v; + if (v < vmin && v > 0) vmin = v; + if (v > vmax && v < FP_SAFE) vmax = v; } } else { - for(i = 0; i < len; i++) { + for (i = 0; i < len; i++) { v = data[i]; - if(v < vmin && v > -FP_SAFE) vmin = v; - if(v > vmax && v < FP_SAFE) vmax = v; + if (v < vmin && v > -FP_SAFE) vmin = v; + if (v > vmax && v < FP_SAFE) vmax = v; } } @@ -504,15 +504,15 @@ function findExtremes(ax, data, opts) { len = 2; } - var collapseOpts = {tozero: tozero, extrapad: extrapad}; + var collapseOpts = { tozero: tozero, extrapad: extrapad }; function addItem(i) { di = data[i]; - if(!isNumeric(di)) return; + if (!isNumeric(di)) return; ppadiplus = ppadplus(i); ppadiminus = ppadminus(i); - if(vpadLinearized) { + if (vpadLinearized) { dmin = ax.c2l(di) - vpadminus(i); dmax = ax.c2l(di) + vpadplus(i); } else { @@ -522,20 +522,20 @@ function findExtremes(ax, data, opts) { // more than an order of mag, clip it to one order. This is so // we don't have non-positive errors or absurdly large lower // range due to rounding errors - if(isLog && vmin < vmax / 10) vmin = vmax / 10; + if (isLog && vmin < vmax / 10) vmin = vmax / 10; dmin = ax.c2l(vmin); dmax = ax.c2l(vmax); } - if(tozero) { + if (tozero) { dmin = Math.min(0, dmin); dmax = Math.max(0, dmax); } - if(goodNumber(dmin)) { + if (goodNumber(dmin)) { collapseMinArray(minArray, dmin, ppadiminus, collapseOpts); } - if(goodNumber(dmax)) { + if (goodNumber(dmax)) { collapseMaxArray(maxArray, dmax, ppadiplus, collapseOpts); } } @@ -544,8 +544,8 @@ function findExtremes(ax, data, opts) { // check a few points at both ends first and then sweep // through the middle var iMax = Math.min(6, len); - for(i = 0; i < iMax; i++) addItem(i); - for(i = len - 1; i >= iMax; i--) addItem(i); + for (i = 0; i < iMax; i++) addItem(i); + for (i = len - 1; i >= iMax; i--) addItem(i); return { min: minArray, @@ -604,17 +604,17 @@ function collapseArray(array, newVal, newPad, opts, atLeastAsExtreme) { var extrapad = opts.extrapad; var includeThis = true; - for(var j = 0; j < array.length && includeThis; j++) { + for (var j = 0; j < array.length && includeThis; j++) { var v = array[j]; - if(atLeastAsExtreme(v.val, newVal) && v.pad >= newPad && (v.extrapad || !extrapad)) { + if (atLeastAsExtreme(v.val, newVal) && v.pad >= newPad && (v.extrapad || !extrapad)) { includeThis = false; break; - } else if(atLeastAsExtreme(newVal, v.val) && v.pad <= newPad && (extrapad || !v.extrapad)) { + } else if (atLeastAsExtreme(newVal, v.val) && v.pad <= newPad && (extrapad || !v.extrapad)) { array.splice(j, 1); j--; } } - if(includeThis) { + if (includeThis) { var clipAtZero = (tozero && newVal === 0); array.push({ val: newVal, @@ -635,7 +635,7 @@ function greaterOrEqual(v0, v1) { return v0 >= v1; } function applyAutorangeMinOptions(v, ax) { var autorangeoptions = ax.autorangeoptions; - if( + if ( autorangeoptions && autorangeoptions.minallowed !== undefined && hasValidMinAndMax(ax, autorangeoptions.minallowed, autorangeoptions.maxallowed) @@ -643,7 +643,7 @@ function applyAutorangeMinOptions(v, ax) { return autorangeoptions.minallowed; } - if( + if ( autorangeoptions && autorangeoptions.clipmin !== undefined && hasValidMinAndMax(ax, autorangeoptions.clipmin, autorangeoptions.clipmax) @@ -656,7 +656,7 @@ function applyAutorangeMinOptions(v, ax) { function applyAutorangeMaxOptions(v, ax) { var autorangeoptions = ax.autorangeoptions; - if( + if ( autorangeoptions && autorangeoptions.maxallowed !== undefined && hasValidMinAndMax(ax, autorangeoptions.minallowed, autorangeoptions.maxallowed) @@ -664,7 +664,7 @@ function applyAutorangeMaxOptions(v, ax) { return autorangeoptions.maxallowed; } - if( + if ( autorangeoptions && autorangeoptions.clipmax !== undefined && hasValidMinAndMax(ax, autorangeoptions.clipmin, autorangeoptions.clipmax) @@ -677,7 +677,7 @@ function applyAutorangeMaxOptions(v, ax) { function hasValidMinAndMax(ax, min, max) { // in case both min and max are defined, ensure min < max - if( + if ( min !== undefined && max !== undefined ) { @@ -691,24 +691,24 @@ function hasValidMinAndMax(ax, min, max) { // this function should be (and is) called before reversing the range // so range[0] is the minimum and range[1] is the maximum function applyAutorangeOptions(range, ax) { - if(!ax || !ax.autorangeoptions) return range; + if (!ax || !ax.autorangeoptions) return range; var min = range[0]; var max = range[1]; var include = ax.autorangeoptions.include; - if(include !== undefined) { + if (include !== undefined) { var lMin = ax.d2l(min); var lMax = ax.d2l(max); - if(!Lib.isArrayOrTypedArray(include)) include = [include]; - for(var i = 0; i < include.length; i++) { + if (!Lib.isArrayOrTypedArray(include)) include = [include]; + for (var i = 0; i < include.length; i++) { var v = ax.d2l(include[i]); - if(lMin >= v) { + if (lMin >= v) { lMin = v; min = v; } - if(lMax <= v) { + if (lMax <= v) { lMax = v; max = v; } diff --git a/src/plots/cartesian/autorange_options_defaults.js b/src/plots/cartesian/autorange_options_defaults.js index 8b7367e5ae2..c01d7db4776 100644 --- a/src/plots/cartesian/autorange_options_defaults.js +++ b/src/plots/cartesian/autorange_options_defaults.js @@ -2,7 +2,7 @@ module.exports = function handleAutorangeOptionsDefaults(coerce, autorange, range) { var minRange, maxRange; - if(range) { + if (range) { var isReversed = ( autorange === 'reversed' || autorange === 'min reversed' || @@ -16,8 +16,8 @@ module.exports = function handleAutorangeOptionsDefaults(coerce, autorange, rang var minallowed = coerce('autorangeoptions.minallowed', maxRange === null ? minRange : undefined); var maxallowed = coerce('autorangeoptions.maxallowed', minRange === null ? maxRange : undefined); - if(minallowed === undefined) coerce('autorangeoptions.clipmin'); - if(maxallowed === undefined) coerce('autorangeoptions.clipmax'); + if (minallowed === undefined) coerce('autorangeoptions.clipmin'); + if (maxallowed === undefined) coerce('autorangeoptions.clipmax'); coerce('autorangeoptions.include'); }; diff --git a/src/plots/gl3d/layout/axis_attributes.js b/src/plots/gl3d/layout/axis_attributes.js index b501c570575..01a46e30eb2 100644 --- a/src/plots/gl3d/layout/axis_attributes.js +++ b/src/plots/gl3d/layout/axis_attributes.js @@ -78,8 +78,8 @@ module.exports = overrideAll({ maxallowed: axesAttrs.maxallowed, range: extendFlat({}, axesAttrs.range, { items: [ - {valType: 'any', editType: 'plot', impliedEdits: {'^autorange': false}}, - {valType: 'any', editType: 'plot', impliedEdits: {'^autorange': false}} + { valType: 'any', editType: 'plot', impliedEdits: { '^autorange': false } }, + { valType: 'any', editType: 'plot', impliedEdits: { '^autorange': false } } ], anim: false }), @@ -116,7 +116,7 @@ module.exports = overrideAll({ linewidth: axesAttrs.linewidth, showgrid: axesAttrs.showgrid, gridcolor: extendFlat({}, axesAttrs.gridcolor, // shouldn't this be on-par with 2D? - {dflt: 'rgb(204, 204, 204)'}), + { dflt: 'rgb(204, 204, 204)' }), gridwidth: axesAttrs.gridwidth, zeroline: axesAttrs.zeroline, zerolinecolor: axesAttrs.zerolinecolor, diff --git a/src/plots/polar/layout_attributes.js b/src/plots/polar/layout_attributes.js index 9a1a830185f..db4f64572e0 100644 --- a/src/plots/polar/layout_attributes.js +++ b/src/plots/polar/layout_attributes.js @@ -8,10 +8,10 @@ var overrideAll = require('../../plot_api/edit_types').overrideAll; var axisLineGridAttr = overrideAll({ color: axesAttrs.color, - showline: extendFlat({}, axesAttrs.showline, {dflt: true}), + showline: extendFlat({}, axesAttrs.showline, { dflt: true }), linecolor: axesAttrs.linecolor, linewidth: axesAttrs.linewidth, - showgrid: extendFlat({}, axesAttrs.showgrid, {dflt: true}), + showgrid: extendFlat({}, axesAttrs.showgrid, { dflt: true }), gridcolor: axesAttrs.gridcolor, gridwidth: axesAttrs.gridwidth, griddash: axesAttrs.griddash @@ -53,7 +53,7 @@ var axisTickAttrs = overrideAll({ }, 'plot', 'from-root'); var radialAxisAttrs = { - visible: extendFlat({}, axesAttrs.visible, {dflt: true}), + visible: extendFlat({}, axesAttrs.visible, { dflt: true }), type: extendFlat({}, axesAttrs.type, { values: ['-', 'linear', 'log', 'date', 'category'] }), @@ -67,7 +67,7 @@ var radialAxisAttrs = { include: axesAttrs.autorangeoptions.include, editType: 'plot' }, - autorange: extendFlat({}, axesAttrs.autorange, {editType: 'plot'}), + autorange: extendFlat({}, axesAttrs.autorange, { editType: 'plot' }), rangemode: { valType: 'enumerated', values: ['tozero', 'nonnegative', 'normal'], @@ -82,12 +82,12 @@ var radialAxisAttrs = { 'of the input data (same behavior as for cartesian axes).' ].join(' ') }, - minallowed: extendFlat({}, axesAttrs.minallowed, {editType: 'plot'}), - maxallowed: extendFlat({}, axesAttrs.maxallowed, {editType: 'plot'}), + minallowed: extendFlat({}, axesAttrs.minallowed, { editType: 'plot' }), + maxallowed: extendFlat({}, axesAttrs.maxallowed, { editType: 'plot' }), range: extendFlat({}, axesAttrs.range, { items: [ - {valType: 'any', editType: 'plot', impliedEdits: {'^autorange': false}}, - {valType: 'any', editType: 'plot', impliedEdits: {'^autorange': false}} + { valType: 'any', editType: 'plot', impliedEdits: { '^autorange': false } }, + { valType: 'any', editType: 'plot', impliedEdits: { '^autorange': false } } ], editType: 'plot' }), @@ -124,8 +124,8 @@ var radialAxisAttrs = { title: { // radial title is not gui-editable at the moment, // so it needs dflt: '', similar to carpet axes. - text: extendFlat({}, axesAttrs.title.text, {editType: 'plot', dflt: ''}), - font: extendFlat({}, axesAttrs.title.font, {editType: 'plot'}), + text: extendFlat({}, axesAttrs.title.text, { editType: 'plot', dflt: '' }), + font: extendFlat({}, axesAttrs.title.font, { editType: 'plot' }), // TODO // - might need a 'titleside' and even 'titledirection' down the road @@ -159,7 +159,7 @@ extendFlat( ); var angularAxisAttrs = { - visible: extendFlat({}, axesAttrs.visible, {dflt: true}), + visible: extendFlat({}, axesAttrs.visible, { dflt: true }), type: { valType: 'enumerated', // 'linear' should maybe be called 'angle' or 'angular' here @@ -268,13 +268,13 @@ module.exports = { // y: {}, // zoom: {}, - domain: domainAttrs({name: 'polar', editType: 'plot'}), + domain: domainAttrs({ name: 'polar', editType: 'plot' }), sector: { valType: 'info_array', items: [ - {valType: 'number', editType: 'plot'}, - {valType: 'number', editType: 'plot'} + { valType: 'number', editType: 'plot' }, + { valType: 'number', editType: 'plot' } ], dflt: [0, 360], editType: 'plot', diff --git a/src/types/generated/schema.d.ts b/src/types/generated/schema.d.ts index fda9a6817e9..859f65b12de 100644 --- a/src/types/generated/schema.d.ts +++ b/src/types/generated/schema.d.ts @@ -484,6 +484,11 @@ export namespace _internal { maxallowed?: any; /** Use this value exactly as autorange minimum. */ minallowed?: any; + /** + * Specifies the minimum span of the computed autorange, in linearized units. If the span is smaller than this value, the autorange is expanded symmetrically to match this minimum span. Has no effect when both `autorangeoptions.minallowed` and `autorangeoptions.maxallowed` are provided and valid. Subject to `autorangeoptions.clipmin` and `autorangeoptions.clipmax`. + * Minimum: 0 + */ + minrange?: number; } export interface ErrorY { diff --git a/test/jasmine/tests/axes_test.js b/test/jasmine/tests/axes_test.js index e964c3c33da..c936acda052 100644 --- a/test/jasmine/tests/axes_test.js +++ b/test/jasmine/tests/axes_test.js @@ -13,7 +13,7 @@ var Cartesian = require('../../../src/plots/cartesian'); var Axes = require('../../../src/plots/cartesian/axes'); var Fx = require('../../../src/components/fx'); var supplyLayoutDefaults = require('../../../src/plots/cartesian/layout_defaults'); -const {BADNUM, MINUS_SIGN, ONEDAY, ONEWEEK} = require('../../../src/constants/numerical'); +const { BADNUM, MINUS_SIGN, ONEDAY, ONEWEEK } = require('../../../src/constants/numerical'); var createGraphDiv = require('../assets/create_graph_div'); var destroyGraphDiv = require('../assets/destroy_graph_div'); @@ -22,12 +22,12 @@ var negateIf = require('../assets/negate_if'); var selectButton = require('../assets/modebar_button'); var supplyDefaults = require('../assets/supply_defaults'); -describe('Test axes', function() { +describe('Test axes', function () { 'use strict'; - describe('swap', function() { - it('should swap most attributes and fix placeholder titles', function() { + describe('swap', function () { + it('should swap most attributes and fix placeholder titles', function () { var gd = { - data: [{x: [1, 2, 3], y: [1, 2, 3]}], + data: [{ x: [1, 2, 3], y: [1, 2, 3] }], layout: { xaxis: { title: { @@ -68,11 +68,11 @@ describe('Test axes', function() { expect(gd.layout.yaxis).toEqual(expectedYaxis); }); - it('should not swap noSwapAttrs', function() { + it('should not swap noSwapAttrs', function () { // for reference: // noSwapAttrs = ['anchor', 'domain', 'overlaying', 'position', 'side', 'tickangle']; var gd = { - data: [{x: [1, 2, 3], y: [1, 2, 3]}], + data: [{ x: [1, 2, 3], y: [1, 2, 3] }], layout: { xaxis: { anchor: 'free', @@ -99,11 +99,11 @@ describe('Test axes', function() { expect(gd.layout.yaxis).toEqual(expectedLayoutAfter.yaxis); }); - it('should swap shared attributes, combine linear/log, and move annotations', function() { + it('should swap shared attributes, combine linear/log, and move annotations', function () { var gd = { data: [ - {x: [1, 2, 3], y: [1, 2, 3]}, - {x: [1, 2, 3], y: [1, 2, 3], xaxis: 'x2'} + { x: [1, 2, 3], y: [1, 2, 3] }, + { x: [1, 2, 3], y: [1, 2, 3], xaxis: 'x2' } ], layout: { xaxis: { @@ -132,9 +132,9 @@ describe('Test axes', function() { side: 'right' }, annotations: [ - {x: 2, y: 3}, // xy referenced by default - {x: 3, y: 4, xref: 'x2', yref: 'y'}, - {x: 5, y: 0.5, xref: 'x', yref: 'paper'} // any paper ref -> don't swap + { x: 2, y: 3 }, // xy referenced by default + { x: 3, y: 4, xref: 'x2', yref: 'y' }, + { x: 5, y: 0.5, xref: 'x', yref: 'paper' } // any paper ref -> don't swap ] } }; @@ -166,9 +166,9 @@ describe('Test axes', function() { side: 'right' }; var expectedAnnotations = [ - {x: 3, y: 2}, - {x: 4, y: 3, xref: 'x2', yref: 'y'}, - {x: 5, y: 0.5, xref: 'x', yref: 'paper'} + { x: 3, y: 2 }, + { x: 4, y: 3, xref: 'x2', yref: 'y' }, + { x: 5, y: 0.5, xref: 'x', yref: 'paper' } ]; supplyDefaults(gd); @@ -182,28 +182,28 @@ describe('Test axes', function() { }); }); - describe('supplyLayoutDefaults', function() { + describe('supplyLayoutDefaults', function () { var layoutIn, layoutOut, fullData; - beforeEach(function() { + beforeEach(function () { layoutOut = { autotypenumbers: 'convert types', _has: Plots._hasPlotType, _basePlotModules: [], - _dfltTitle: {x: 'x', y: 'y'}, - _subplots: {cartesian: ['xy'], xaxis: ['x'], yaxis: ['y']}, + _dfltTitle: { x: 'x', y: 'y' }, + _subplots: { cartesian: ['xy'], xaxis: ['x'], yaxis: ['y'] }, _requestRangeslider: {} }; fullData = []; }); - describe('autotype', function() { + describe('autotype', function () { function supplyWithTrace(trace) { var fullTrace = Lib.extendDeep( - {type: 'scatter', xaxis: 'x', yaxis: 'y'}, + { type: 'scatter', xaxis: 'x', yaxis: 'y' }, trace ); - layoutIn = {xaxis: {}, yaxis: {}}; + layoutIn = { xaxis: {}, yaxis: {} }; supplyLayoutDefaults(layoutIn, layoutOut, [fullTrace]); } @@ -212,17 +212,17 @@ describe('Test axes', function() { expect(layoutOut.yaxis.type).toBe(yType, msg); } - it('treats booleans as categories', function() { - supplyWithTrace({x: [0, 1, 2], y: [true, false, true]}); + it('treats booleans as categories', function () { + supplyWithTrace({ x: [0, 1, 2], y: [true, false, true] }); checkTypes('linear', 'category'); }); - it('sees a single "None" or "" as a category', function() { - supplyWithTrace({x: ['None'], y: ['']}); + it('sees a single "None" or "" as a category', function () { + supplyWithTrace({ x: ['None'], y: [''] }); checkTypes('category', 'category'); }); - it('lets a single number beat up to two distinct categories', function() { + it('lets a single number beat up to two distinct categories', function () { supplyWithTrace({ x: ['2.1', 'N/A', '', 'N/A', '', 'N/A', 'N/A', '', '', ''], y: [0, 'None', true, 'None', 'None', 'None', 'None', 'None'] @@ -230,7 +230,7 @@ describe('Test axes', function() { checkTypes('linear', 'linear'); }); - it('turns back to category with >2 per distinct number', function() { + it('turns back to category with >2 per distinct number', function () { supplyWithTrace({ x: [4, 4, 4, 4, 4, 4, 4, 4, 'Yes', 'No', 'Maybe'], y: [1, 2, 1, 2, 1, 2, true, false, '', 'None', 'nan'] @@ -238,7 +238,7 @@ describe('Test axes', function() { checkTypes('category', 'category'); }); - it('works with world calendars', function() { + it('works with world calendars', function () { // these are only valid dates in chinese var intercalary = ['1995-08i-01', '1995-08i-29', '1984-10i-15']; supplyWithTrace({ @@ -248,7 +248,7 @@ describe('Test axes', function() { checkTypes('date', 'category'); }); - it('requires >twice as many distinct dates as numbers', function() { + it('requires >twice as many distinct dates as numbers', function () { supplyWithTrace({ x: ['2000-01-01', '2000-01-02', '2000-01-03', 1, 1.2], y: ['2000-01', '2000-02', '2000-03', '2000-04', 1.1] @@ -262,7 +262,7 @@ describe('Test axes', function() { checkTypes('date', 'linear'); }); - it('counts ambiguous dates as both dates and numbers', function() { + it('counts ambiguous dates as both dates and numbers', function () { supplyWithTrace({ x: ['2000', '2000-01', '2000-02'], // 3 dates, 1 number y: ['2000', '2001', '2000-01'] // 3 dates, 2 numbers @@ -270,7 +270,7 @@ describe('Test axes', function() { checkTypes('date', 'linear'); }); - it('2d coordinate array are considered *multicategory*', function() { + it('2d coordinate array are considered *multicategory*', function () { supplyWithTrace({ x: [ [2018, 2018, 2017, 2017], @@ -333,8 +333,8 @@ describe('Test axes', function() { }); }); - describe('autotype disable/enable converting numeric strings', function() { - it('should disable converting numeric strings using axis.autotypenumbers', function() { + describe('autotype disable/enable converting numeric strings', function () { + it('should disable converting numeric strings using axis.autotypenumbers', function () { layoutIn = { xaxis: {}, yaxis: { autotypenumbers: 'strict' } @@ -354,7 +354,7 @@ describe('Test axes', function() { expect(layoutOut.yaxis.type).toBe('category'); }); - it('should enable converting numeric strings using axis.autotypenumbers and inherit defaults from layout.autotypenumbers', function() { + it('should enable converting numeric strings using axis.autotypenumbers and inherit defaults from layout.autotypenumbers', function () { layoutOut.autotypenumbers = 'strict'; layoutIn = { @@ -376,7 +376,7 @@ describe('Test axes', function() { expect(layoutOut.yaxis.type).toBe('category'); }); - it('should autotype date having more dates with & without strict autotypenumbers', function() { + it('should autotype date having more dates with & without strict autotypenumbers', function () { layoutIn = { xaxis: {}, yaxis: { autotypenumbers: 'strict' } @@ -418,7 +418,7 @@ describe('Test axes', function() { }); }); - it('should set undefined linewidth/linecolor if linewidth, linecolor or showline is not supplied', function() { + it('should set undefined linewidth/linecolor if linewidth, linecolor or showline is not supplied', function () { layoutIn = { xaxis: {}, yaxis: {} @@ -430,16 +430,16 @@ describe('Test axes', function() { expect(layoutOut.yaxis.linecolor).toBe(undefined); }); - it('should set default linewidth and linecolor if showline is true', function() { + it('should set default linewidth and linecolor if showline is true', function () { layoutIn = { - xaxis: {showline: true} + xaxis: { showline: true } }; supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut.xaxis.linewidth).toBe(1); expect(layoutOut.xaxis.linecolor).toBe(Color.defaultLine); }); - it('should set linewidth to default if linecolor is supplied and valid', function() { + it('should set linewidth to default if linecolor is supplied and valid', function () { layoutIn = { xaxis: { linecolor: 'black' } }; @@ -448,7 +448,7 @@ describe('Test axes', function() { expect(layoutOut.xaxis.linewidth).toBe(1); }); - it('should set linecolor to default if linewidth is supplied and valid', function() { + it('should set linecolor to default if linewidth is supplied and valid', function () { layoutIn = { yaxis: { linewidth: 2 } }; @@ -457,7 +457,7 @@ describe('Test axes', function() { expect(layoutOut.yaxis.linecolor).toBe(Color.defaultLine); }); - it('should set default gridwidth and gridcolor', function() { + it('should set default gridwidth and gridcolor', function () { layoutIn = { xaxis: {}, yaxis: {} @@ -470,16 +470,16 @@ describe('Test axes', function() { expect(Color.rgbaString(layoutOut.yaxis.gridcolor)).toBe(lightLine); }); - it('should set gridcolor/gridwidth to undefined if showgrid is false', function() { + it('should set gridcolor/gridwidth to undefined if showgrid is false', function () { layoutIn = { - yaxis: {showgrid: false} + yaxis: { showgrid: false } }; supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut.yaxis.gridwidth).toBe(undefined); expect(layoutOut.yaxis.gridcolor).toBe(undefined); }); - it('should set default zerolinecolor/zerolinewidth', function() { + it('should set default zerolinecolor/zerolinewidth', function () { layoutIn = { xaxis: {}, yaxis: {} @@ -491,16 +491,16 @@ describe('Test axes', function() { expect(layoutOut.yaxis.zerolinecolor).toBe(Color.defaultLine); }); - it('should set zerolinecolor/zerolinewidth to undefined if zeroline is false', function() { + it('should set zerolinecolor/zerolinewidth to undefined if zeroline is false', function () { layoutIn = { - xaxis: {zeroline: false} + xaxis: { zeroline: false } }; supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut.xaxis.zerolinewidth).toBe(undefined); expect(layoutOut.xaxis.zerolinecolor).toBe(undefined); }); - it('should use \'axis.color\' as default for \'axis.title.font.color\'', function() { + it('should use \'axis.color\' as default for \'axis.title.font.color\'', function () { layoutIn = { xaxis: { color: 'red' }, yaxis: {}, @@ -517,7 +517,7 @@ describe('Test axes', function() { expect(layoutOut.yaxis2.title.font.color).toEqual('yellow'); }); - it('should use \'axis.color\' as default for \'axis.linecolor\'', function() { + it('should use \'axis.color\' as default for \'axis.linecolor\'', function () { layoutIn = { xaxis: { showline: true, color: 'red' }, yaxis: { linecolor: 'blue' }, @@ -532,7 +532,7 @@ describe('Test axes', function() { expect(layoutOut.yaxis2.linecolor).toEqual('#444'); }); - it('should use \'axis.color\' as default for \'axis.zerolinecolor\'', function() { + it('should use \'axis.color\' as default for \'axis.zerolinecolor\'', function () { layoutIn = { xaxis: { zeroline: true, color: 'red' }, yaxis: { zerolinecolor: 'blue' }, @@ -547,7 +547,7 @@ describe('Test axes', function() { expect(layoutOut.yaxis2.zerolinecolor).toEqual('#444'); }); - it('should use combo of \'axis.color\', bgcolor and lightFraction as default for \'axis.gridcolor\'', function() { + it('should use combo of \'axis.color\', bgcolor and lightFraction as default for \'axis.gridcolor\'', function () { layoutIn = { paper_bgcolor: 'green', plot_bgcolor: 'yellow', @@ -584,7 +584,7 @@ describe('Test axes', function() { expect(layoutOut.xaxis.gridcolor).toEqual('rgba(255, 247, 0, 0.95)'); }); - it('should default to a dark color for tickfont when plotting background is light', function() { + it('should default to a dark color for tickfont when plotting background is light', function () { layoutIn = { plot_bgcolor: 'lightblue', xaxis: { @@ -597,7 +597,7 @@ describe('Test axes', function() { expect(layoutOut.xaxis.tickfont.color).toEqual('rgb(68, 68, 68)'); }); - it('should default to a light color for tickfont when plotting background is dark', function() { + it('should default to a light color for tickfont when plotting background is dark', function () { layoutIn = { plot_bgcolor: 'darkblue', xaxis: { @@ -610,21 +610,21 @@ describe('Test axes', function() { expect(layoutOut.xaxis.tickfont.color).toEqual('rgb(255, 255, 255)'); }); - it('should not coerce ticklabelposition on *multicategory* axes for now', function() { + it('should not coerce ticklabelposition on *multicategory* axes for now', function () { layoutIn = { - xaxis: {type: 'multicategory'}, - yaxis: {type: 'multicategory'} + xaxis: { type: 'multicategory' }, + yaxis: { type: 'multicategory' } }; supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut.xaxis.ticklabelposition).toBeUndefined(); expect(layoutOut.yaxis.ticklabelposition).toBeUndefined(); }); - ['category', 'linear', 'date'].forEach(function(type) { - it('should coerce ticklabelposition on *' + type + '* axes', function() { + ['category', 'linear', 'date'].forEach(function (type) { + it('should coerce ticklabelposition on *' + type + '* axes', function () { layoutIn = { - xaxis: {type: type}, - yaxis: {type: type} + xaxis: { type: type }, + yaxis: { type: type } }; supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut.xaxis.ticklabelposition).toBe('outside'); @@ -632,11 +632,11 @@ describe('Test axes', function() { }); }); - ['category', 'linear', 'date'].forEach(function(type) { - it('should be able to set ticklabelposition to *inside* on *' + type + '* axes', function() { + ['category', 'linear', 'date'].forEach(function (type) { + it('should be able to set ticklabelposition to *inside* on *' + type + '* axes', function () { layoutIn = { - xaxis: {type: type, ticklabelposition: 'inside'}, - yaxis: {type: type, ticklabelposition: 'inside'} + xaxis: { type: type, ticklabelposition: 'inside' }, + yaxis: { type: type, ticklabelposition: 'inside' } }; supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut.xaxis.ticklabelposition).toBe('inside'); @@ -644,12 +644,12 @@ describe('Test axes', function() { }); }); - ['inside left', 'inside right', 'outside left', 'outside right'].forEach(function(ticklabelposition) { - ['category', 'linear', 'date'].forEach(function(type) { - it('should be able to set ticklabelposition to *' + ticklabelposition + '* on xaxis for *' + type + '* axes', function() { + ['inside left', 'inside right', 'outside left', 'outside right'].forEach(function (ticklabelposition) { + ['category', 'linear', 'date'].forEach(function (type) { + it('should be able to set ticklabelposition to *' + ticklabelposition + '* on xaxis for *' + type + '* axes', function () { layoutIn = { - xaxis: {type: type, ticklabelposition: ticklabelposition}, - yaxis: {type: type, ticklabelposition: ticklabelposition} + xaxis: { type: type, ticklabelposition: ticklabelposition }, + yaxis: { type: type, ticklabelposition: ticklabelposition } }; supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut.xaxis.ticklabelposition).toBe(ticklabelposition); @@ -658,12 +658,12 @@ describe('Test axes', function() { }); }); - ['inside top', 'inside bottom', 'outside top', 'outside bottom'].forEach(function(ticklabelposition) { - ['category', 'linear', 'date'].forEach(function(type) { - it('should be able to set ticklabelposition to *' + ticklabelposition + '* on yaxis for *' + type + '* axes', function() { + ['inside top', 'inside bottom', 'outside top', 'outside bottom'].forEach(function (ticklabelposition) { + ['category', 'linear', 'date'].forEach(function (type) { + it('should be able to set ticklabelposition to *' + ticklabelposition + '* on yaxis for *' + type + '* axes', function () { layoutIn = { - xaxis: {type: type, ticklabelposition: ticklabelposition}, - yaxis: {type: type, ticklabelposition: ticklabelposition} + xaxis: { type: type, ticklabelposition: ticklabelposition }, + yaxis: { type: type, ticklabelposition: ticklabelposition } }; supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut.xaxis.ticklabelposition).toBe('outside', ticklabelposition + ' is not a valid input on yaxis'); @@ -675,11 +675,11 @@ describe('Test axes', function() { [ 'inside left', 'inside right', 'outside left', 'outside right', 'inside top', 'inside bottom', 'outside top', 'outside bottom' - ].forEach(function(ticklabelposition) { - it('should not be able to set ticklabelposition to *' + ticklabelposition + '* when ticklabelmode is *period*', function() { + ].forEach(function (ticklabelposition) { + it('should not be able to set ticklabelposition to *' + ticklabelposition + '* when ticklabelmode is *period*', function () { layoutIn = { - xaxis: {type: 'date', ticklabelmode: 'period', ticklabelposition: ticklabelposition}, - yaxis: {type: 'date', ticklabelmode: 'period', ticklabelposition: ticklabelposition} + xaxis: { type: 'date', ticklabelmode: 'period', ticklabelposition: ticklabelposition }, + yaxis: { type: 'date', ticklabelmode: 'period', ticklabelposition: ticklabelposition } }; supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut.xaxis.ticklabelposition).toBe('outside', ticklabelposition + ' is not a valid input with period mode'); @@ -687,22 +687,22 @@ describe('Test axes', function() { }); }); - it('should be able to set ticklabelposition to *inside* on yaxis when ticklabelmode is *period*', function() { + it('should be able to set ticklabelposition to *inside* on yaxis when ticklabelmode is *period*', function () { layoutIn = { - xaxis: {type: 'date', ticklabelmode: 'period', ticklabelposition: 'inside'}, - yaxis: {type: 'date', ticklabelmode: 'period', ticklabelposition: 'inside'} + xaxis: { type: 'date', ticklabelmode: 'period', ticklabelposition: 'inside' }, + yaxis: { type: 'date', ticklabelmode: 'period', ticklabelposition: 'inside' } }; supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut.xaxis.ticklabelposition).toBe('inside'); expect(layoutOut.yaxis.ticklabelposition).toBe('inside'); }); - it('should inherit calendar from the layout', function() { + it('should inherit calendar from the layout', function () { layoutOut.calendar = 'nepali'; layoutIn = { calendar: 'nepali', - xaxis: {type: 'date'}, - yaxis: {type: 'date'} + xaxis: { type: 'date' }, + yaxis: { type: 'date' } }; supplyLayoutDefaults(layoutIn, layoutOut, fullData); @@ -711,12 +711,12 @@ describe('Test axes', function() { expect(layoutOut.yaxis.calendar).toBe('nepali'); }); - it('should allow its own calendar', function() { + it('should allow its own calendar', function () { layoutOut.calendar = 'nepali'; layoutIn = { calendar: 'nepali', - xaxis: {type: 'date', calendar: 'coptic'}, - yaxis: {type: 'date', calendar: 'thai'} + xaxis: { type: 'date', calendar: 'coptic' }, + yaxis: { type: 'date', calendar: 'thai' } }; supplyLayoutDefaults(layoutIn, layoutOut, fullData); @@ -725,7 +725,7 @@ describe('Test axes', function() { expect(layoutOut.yaxis.calendar).toBe('thai'); }); - it('should set autorange to true when input range is invalid', function() { + it('should set autorange to true when input range is invalid', function () { layoutIn = { xaxis: { range: 'not-gonna-work' }, xaxis2: { range: [1] }, @@ -747,12 +747,12 @@ describe('Test axes', function() { supplyLayoutDefaults(layoutIn, layoutOut, fullData); - Axes.list({ _fullLayout: layoutOut }).forEach(function(ax) { + Axes.list({ _fullLayout: layoutOut }).forEach(function (ax) { expect(ax.autorange).toBe(true, ax._name); }); }); - it('should set autorange to false when input range is valid', function() { + it('should set autorange to false when input range is valid', function () { layoutIn = { xaxis: { range: [1, 2] }, xaxis2: { range: [-2, 1] }, @@ -764,12 +764,12 @@ describe('Test axes', function() { supplyLayoutDefaults(layoutIn, layoutOut, fullData); - Axes.list({ _fullLayout: layoutOut }).forEach(function(ax) { + Axes.list({ _fullLayout: layoutOut }).forEach(function (ax) { expect(ax.autorange).toBe(false, ax._name); }); }); - it('should set autorange to true when range[0] and range[1] are set to null', function() { + it('should set autorange to true when range[0] and range[1] are set to null', function () { layoutIn = { xaxis: { range: [null, null] } }; @@ -779,7 +779,7 @@ describe('Test axes', function() { expect(layoutOut.xaxis.autorange).toBe(true); }); - it('should set autorange to min when range[0] is set to null', function() { + it('should set autorange to min when range[0] is set to null', function () { layoutIn = { xaxis: { range: [null, 1] } }; @@ -789,7 +789,7 @@ describe('Test axes', function() { expect(layoutOut.xaxis.autorange).toBe('min'); }); - it('should set autorange to max when range[1] is set to null', function() { + it('should set autorange to max when range[1] is set to null', function () { layoutIn = { xaxis: { range: [1, null] } }; @@ -799,12 +799,12 @@ describe('Test axes', function() { expect(layoutOut.xaxis.autorange).toBe('max'); }); - it('only allows rangemode with linear axes', function() { + it('only allows rangemode with linear axes', function () { layoutIn = { - xaxis: {type: 'log', rangemode: 'tozero'}, - yaxis: {type: 'date', rangemode: 'tozero'}, - xaxis2: {type: 'category', rangemode: 'tozero'}, - yaxis2: {type: 'linear', rangemode: 'tozero'} + xaxis: { type: 'log', rangemode: 'tozero' }, + yaxis: { type: 'date', rangemode: 'tozero' }, + xaxis2: { type: 'category', rangemode: 'tozero' }, + yaxis2: { type: 'linear', rangemode: 'tozero' } }; layoutOut._subplots.cartesian.push('x2y2'); layoutOut._subplots.yaxis.push('x2', 'y2'); @@ -817,18 +817,18 @@ describe('Test axes', function() { expect(layoutOut.yaxis2.rangemode).toBe('tozero'); }); - it('finds scaling groups and calculates relative scales', function() { + it('finds scaling groups and calculates relative scales', function () { layoutIn = { // first group: linked in series, scales compound xaxis: {}, - yaxis: {scaleanchor: 'x', scaleratio: 2}, - xaxis2: {scaleanchor: 'y', scaleratio: 3}, - yaxis2: {scaleanchor: 'x2', scaleratio: 5}, + yaxis: { scaleanchor: 'x', scaleratio: 2 }, + xaxis2: { scaleanchor: 'y', scaleratio: 3 }, + yaxis2: { scaleanchor: 'x2', scaleratio: 5 }, // second group: linked in parallel, scales don't compound yaxis3: {}, - xaxis3: {scaleanchor: 'y3'}, // default scaleratio: 1 - xaxis4: {scaleanchor: 'y3', scaleratio: 7}, - xaxis5: {scaleanchor: 'y3', scaleratio: 9} + xaxis3: { scaleanchor: 'y3' }, // default scaleratio: 1 + xaxis4: { scaleanchor: 'y3', scaleratio: 7 }, + xaxis5: { scaleanchor: 'y3', scaleratio: 9 } }; layoutOut._subplots.cartesian.push('x2y2', 'x3y3', 'x4y3', 'x5y3'); layoutOut._subplots.yaxis.push('x2', 'x3', 'x4', 'x5', 'y2', 'y3'); @@ -836,28 +836,28 @@ describe('Test axes', function() { supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut._axisConstraintGroups).toEqual([ - {x: 1, y: 2, x2: 2 * 3, y2: 2 * 3 * 5}, - {y3: 1, x3: 1, x4: 7, x5: 9} + { x: 1, y: 2, x2: 2 * 3, y2: 2 * 3 * 5 }, + { y3: 1, x3: 1, x4: 7, x5: 9 } ]); }); - it('breaks scaleanchor loops and drops conflicting ratios', function() { + it('breaks scaleanchor loops and drops conflicting ratios', function () { var warnings = []; - spyOn(Lib, 'warn').and.callFake(function(msg) { + spyOn(Lib, 'warn').and.callFake(function (msg) { warnings.push(msg.slice(0, msg.indexOf(' to avoid'))); }); layoutIn = { - xaxis: {scaleanchor: 'y', scaleratio: 2}, - yaxis: {scaleanchor: 'x', scaleratio: 3}, // dropped loop + xaxis: { scaleanchor: 'y', scaleratio: 2 }, + yaxis: { scaleanchor: 'x', scaleratio: 3 }, // dropped loop - xaxis2: {scaleanchor: 'y2', scaleratio: 5}, - yaxis2: {scaleanchor: 'x3', scaleratio: 7}, - xaxis3: {scaleanchor: 'y3', scaleratio: 9}, - yaxis3: {scaleanchor: 'x2', scaleratio: 11}, // dropped loop + xaxis2: { scaleanchor: 'y2', scaleratio: 5 }, + yaxis2: { scaleanchor: 'x3', scaleratio: 7 }, + xaxis3: { scaleanchor: 'y3', scaleratio: 9 }, + yaxis3: { scaleanchor: 'x2', scaleratio: 11 }, // dropped loop - xaxis4: {scaleanchor: 'x', scaleratio: 13}, // x<->x is OK now - yaxis4: {scaleanchor: 'y', scaleratio: 17}, // y<->y is OK now + xaxis4: { scaleanchor: 'x', scaleratio: 13 }, // x<->x is OK now + yaxis4: { scaleanchor: 'y', scaleratio: 17 }, // y<->y is OK now }; layoutOut._subplots.cartesian.push('x2y2', 'x3y3', 'x4y4'); layoutOut._subplots.xaxis.push('x2', 'x3', 'x4'); @@ -866,8 +866,8 @@ describe('Test axes', function() { supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut._axisConstraintGroups).toEqual([ - {x: 2, y: 1, x4: 2 * 13, y4: 17}, - {x2: 5 * 7 * 9, y2: 7 * 9, y3: 1, x3: 9} + { x: 2, y: 1, x4: 2 * 13, y4: 17 }, + { x2: 5 * 7 * 9, y2: 7 * 9, y3: 1, x3: 9 } ]); expect(warnings).toEqual([ @@ -876,16 +876,16 @@ describe('Test axes', function() { ]); }); - it('silently drops invalid scaleanchor values', function() { + it('silently drops invalid scaleanchor values', function () { var warnings = []; - spyOn(Lib, 'warn').and.callFake(function(msg) { + spyOn(Lib, 'warn').and.callFake(function (msg) { warnings.push(msg.slice(0, msg.indexOf(' to avoid'))); }); layoutIn = { - xaxis: {scaleanchor: 'x', scaleratio: 2}, // can't link to itself - this one isn't ignored... - yaxis: {scaleanchor: 'x4', scaleratio: 3}, // doesn't exist - xaxis2: {scaleanchor: 'yaxis', scaleratio: 5} // must be an id, not a name + xaxis: { scaleanchor: 'x', scaleratio: 2 }, // can't link to itself - this one isn't ignored... + yaxis: { scaleanchor: 'x4', scaleratio: 3 }, // doesn't exist + xaxis2: { scaleanchor: 'yaxis', scaleratio: 5 } // must be an id, not a name }; layoutOut._subplots.cartesian.push('x2y'); layoutOut._subplots.yaxis.push('x2'); @@ -895,18 +895,18 @@ describe('Test axes', function() { expect(layoutOut._axisConstraintGroups).toEqual([]); expect(warnings).toEqual(['ignored xaxis.scaleanchor: "x"']); - ['xaxis', 'yaxis', 'xaxis2'].forEach(function(axName) { + ['xaxis', 'yaxis', 'xaxis2'].forEach(function (axName) { expect(layoutOut[axName].scaleanchor).toBeUndefined(axName); expect(layoutOut[axName].scaleratio).toBeUndefined(axName); }); }); - it('will not link axes of different types', function() { + it('will not link axes of different types', function () { layoutIn = { - xaxis: {type: 'linear'}, - yaxis: {type: 'log', scaleanchor: 'x', scaleratio: 2}, - xaxis2: {type: 'date', scaleanchor: 'y', scaleratio: 3}, - yaxis2: {type: 'category', scaleanchor: 'x2', scaleratio: 5} + xaxis: { type: 'linear' }, + yaxis: { type: 'log', scaleanchor: 'x', scaleratio: 2 }, + xaxis2: { type: 'date', scaleanchor: 'y', scaleratio: 3 }, + yaxis2: { type: 'category', scaleanchor: 'x2', scaleratio: 5 } }; layoutOut._subplots.cartesian.push('x2y2'); layoutOut._subplots.yaxis.push('x2', 'y2'); @@ -915,18 +915,18 @@ describe('Test axes', function() { expect(layoutOut._axisConstraintGroups).toEqual([]); - ['xaxis', 'yaxis', 'xaxis2', 'yaxis2'].forEach(function(axName) { + ['xaxis', 'yaxis', 'xaxis2', 'yaxis2'].forEach(function (axName) { expect(layoutOut[axName].scaleanchor).toBeUndefined(axName); expect(layoutOut[axName].scaleratio).toBeUndefined(axName); }); }); - it('will not match axes of different types', function() { + it('will not match axes of different types', function () { layoutIn = { - xaxis: {type: 'linear'}, - yaxis: {type: 'log', matches: 'x'}, - xaxis2: {type: 'date', matches: 'y'}, - yaxis2: {type: 'category', matches: 'x2'} + xaxis: { type: 'linear' }, + yaxis: { type: 'log', matches: 'x' }, + xaxis2: { type: 'date', matches: 'y' }, + yaxis2: { type: 'category', matches: 'x2' } }; layoutOut._subplots.cartesian.push('x2y2'); layoutOut._subplots.yaxis.push('x2', 'y2'); @@ -935,15 +935,15 @@ describe('Test axes', function() { expect(layoutOut._axisMatchGroups).toEqual([]); - ['xaxis', 'yaxis', 'xaxis2', 'yaxis2'].forEach(function(axName) { + ['xaxis', 'yaxis', 'xaxis2', 'yaxis2'].forEach(function (axName) { expect(layoutOut[axName].matches).toBeUndefined(); }); }); - it('disallow constraining AND matching range', function() { + it('disallow constraining AND matching range', function () { layoutIn = { xaxis: {}, - xaxis2: {matches: 'x', scaleanchor: 'x'} + xaxis2: { matches: 'x', scaleanchor: 'x' } }; layoutOut._subplots.cartesian.push('x2y'); layoutOut._subplots.xaxis.push('x2'); @@ -956,19 +956,19 @@ describe('Test axes', function() { expect(layoutOut.xaxis2.constrain).toBe('range'); expect(layoutOut._axisConstraintGroups).toEqual([]); - expect(layoutOut._axisMatchGroups).toEqual([{x: 1, x2: 1}]); + expect(layoutOut._axisMatchGroups).toEqual([{ x: 1, x2: 1 }]); }); - it('combines all chained scaled/matched axes into a group but drops match-only groups from constraintGroups', function() { + it('combines all chained scaled/matched axes into a group but drops match-only groups from constraintGroups', function () { layoutIn = { // this one big group xaxis: {}, - yaxis: {scaleanchor: 'x'}, - xaxis2: {matches: 'x'}, - yaxis2: {matches: 'y'}, + yaxis: { scaleanchor: 'x' }, + xaxis2: { matches: 'x' }, + yaxis2: { matches: 'y' }, // this is another group but only shows up in matchGroups xaxis3: {}, - yaxis3: {matches: 'x3'} + yaxis3: { matches: 'x3' } }; layoutOut._subplots.cartesian.push('x2y2, x3y3'); layoutOut._subplots.xaxis.push('x2', 'x3'); @@ -976,36 +976,36 @@ describe('Test axes', function() { supplyLayoutDefaults(layoutIn, layoutOut, fullData); - expect(layoutOut._axisMatchGroups).toEqual([{x: 1, x2: 1}, {y: 1, y2: 1}, {x3: 1, y3: 1}]); + expect(layoutOut._axisMatchGroups).toEqual([{ x: 1, x2: 1 }, { y: 1, y2: 1 }, { x3: 1, y3: 1 }]); - expect(layoutOut._axisConstraintGroups).toEqual([{x: 1, y: 1, x2: 1, y2: 1}]); + expect(layoutOut._axisConstraintGroups).toEqual([{ x: 1, y: 1, x2: 1, y2: 1 }]); }); - it('includes matches in constraintGroup when combined with scaleanchor', function() { + it('includes matches in constraintGroup when combined with scaleanchor', function () { layoutIn = { xaxis: {}, - yaxis: {matches: 'x'}, - xaxis2: {scaleanchor: 'x'} + yaxis: { matches: 'x' }, + xaxis2: { scaleanchor: 'x' } }; layoutOut._subplots.cartesian.push('x2y'); layoutOut._subplots.xaxis.push('x2'); supplyLayoutDefaults(layoutIn, layoutOut, fullData); - expect(layoutOut._axisMatchGroups).toEqual([{x: 1, y: 1}]); - expect(layoutOut._axisConstraintGroups).toEqual([{x: 1, y: 'y1', x2: 1}]); + expect(layoutOut._axisMatchGroups).toEqual([{ x: 1, y: 1 }]); + expect(layoutOut._axisConstraintGroups).toEqual([{ x: 1, y: 'y1', x2: 1 }]); }); - it('turns all scaled axes fixedrange if any is fixedrange', function() { + it('turns all scaled axes fixedrange if any is fixedrange', function () { // some of these will create warnings... not too important, so not going to test, // just want to keep the output clean // spyOn(Lib, 'warn'); layoutIn = { - xaxis: {fixedrange: true, scaleanchor: 'y', scaleratio: 2}, - yaxis: {scaleanchor: 'x2', scaleratio: 3}, + xaxis: { fixedrange: true, scaleanchor: 'y', scaleratio: 2 }, + yaxis: { scaleanchor: 'x2', scaleratio: 3 }, xaxis2: {}, - yaxis2: {scaleanchor: 'x', scaleratio: 5} + yaxis2: { scaleanchor: 'x', scaleratio: 5 } }; layoutOut._subplots.cartesian.push('x2y2'); layoutOut._subplots.xaxis.push('x2'); @@ -1013,7 +1013,7 @@ describe('Test axes', function() { supplyLayoutDefaults(layoutIn, layoutOut, fullData); - expect(layoutOut._axisConstraintGroups).toEqual([{x2: 1, y: 3, x: 6, y2: 30}]); + expect(layoutOut._axisConstraintGroups).toEqual([{ x2: 1, y: 3, x: 6, y2: 30 }]); expect(layoutOut.xaxis.scaleanchor).toBe('y'); expect(layoutOut.xaxis.scaleratio).toBe(2); @@ -1022,17 +1022,17 @@ describe('Test axes', function() { expect(layoutOut.yaxis2.scaleanchor).toBe('x'); expect(layoutOut.yaxis2.scaleratio).toBe(5); - ['xaxis', 'yaxis', 'yaxis2', 'xaxis2'].forEach(function(axName) { + ['xaxis', 'yaxis', 'yaxis2', 'xaxis2'].forEach(function (axName) { expect(layoutOut[axName].fixedrange).toBe(true, axName); }); }); - it('turns all matching axes fixedrange if any is fixedrange', function() { + it('turns all matching axes fixedrange if any is fixedrange', function () { layoutIn = { - xaxis: {fixedrange: true, matches: 'y'}, - yaxis: {matches: 'x2'}, + xaxis: { fixedrange: true, matches: 'y' }, + yaxis: { matches: 'x2' }, xaxis2: {}, - yaxis2: {matches: 'x'} + yaxis2: { matches: 'x' } }; layoutOut._subplots.cartesian.push('x2y2'); layoutOut._subplots.xaxis.push('x2'); @@ -1040,16 +1040,16 @@ describe('Test axes', function() { supplyLayoutDefaults(layoutIn, layoutOut, fullData); - expect(layoutOut._axisMatchGroups).toEqual([{x: 1, x2: 1, y: 1, y2: 1}]); + expect(layoutOut._axisMatchGroups).toEqual([{ x: 1, x2: 1, y: 1, y2: 1 }]); expect(layoutOut.yaxis.matches).toBe('x2'); - ['xaxis', 'xaxis2', 'yaxis', 'yaxis2'].forEach(function(axName) { + ['xaxis', 'xaxis2', 'yaxis', 'yaxis2'].forEach(function (axName) { negateIf(axName !== 'xaxis2', expect(layoutOut[axName].matches)).toBeUndefined(axName); expect(layoutOut[axName].fixedrange).toBe(true, axName); }); }); - it('should coerce hoverformat even on visible: false axes', function() { + it('should coerce hoverformat even on visible: false axes', function () { layoutIn = { xaxis: { visible: false, @@ -1061,16 +1061,16 @@ describe('Test axes', function() { expect(layoutOut.xaxis.hoverformat).toEqual('g'); }); - it('should find matching groups', function() { + it('should find matching groups', function () { layoutIn = { // both linked to 'base' ax xaxis: {}, - xaxis2: {matches: 'x'}, - xaxis3: {matches: 'x'}, + xaxis2: { matches: 'x' }, + xaxis3: { matches: 'x' }, // cascading links yaxis: {}, - yaxis2: {anchor: 'x2', matches: 'y'}, - yaxis3: {anchor: 'x3', matches: 'y2'}, + yaxis2: { anchor: 'x2', matches: 'y' }, + yaxis3: { anchor: 'x3', matches: 'y2' }, }; layoutOut._subplots.cartesian.push('x2y2', 'x3y3'); layoutOut._subplots.xaxis.push('x2', 'x3'); @@ -1079,20 +1079,20 @@ describe('Test axes', function() { supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut._axisMatchGroups.length).toBe(2); - expect(layoutOut._axisMatchGroups).toContain({x: 1, x2: 1, x3: 1}); - expect(layoutOut._axisMatchGroups).toContain({y: 1, y2: 1, y3: 1}); + expect(layoutOut._axisMatchGroups).toContain({ x: 1, x2: 1, x3: 1 }); + expect(layoutOut._axisMatchGroups).toContain({ y: 1, y2: 1, y3: 1 }); }); - it('should find matching group even when matching a *missing* axis', function() { + it('should find matching group even when matching a *missing* axis', function () { layoutIn = { // N.B. xaxis isn't set - xaxis2: {matches: 'x'}, - xaxis3: {matches: 'x'}, - xaxis4: {matches: 'x'}, + xaxis2: { matches: 'x' }, + xaxis3: { matches: 'x' }, + xaxis4: { matches: 'x' }, // N.B. yaxis isn't set - yaxis2: {matches: 'y'}, - yaxis3: {matches: 'y2'}, - yaxis4: {matches: 'y3'}, + yaxis2: { matches: 'y' }, + yaxis3: { matches: 'y2' }, + yaxis4: { matches: 'y3' }, }; layoutOut._subplots.cartesian = ['x2y2', 'x3y3', 'x4y4']; layoutOut._subplots.xaxis = ['x2', 'x3', 'x4']; @@ -1101,8 +1101,8 @@ describe('Test axes', function() { supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut._axisMatchGroups.length).toBe(2); - expect(layoutOut._axisMatchGroups).toContain({x: 1, x2: 1, x3: 1, x4: 1}); - expect(layoutOut._axisMatchGroups).toContain({y: 1, y2: 1, y3: 1, y4: 1}); + expect(layoutOut._axisMatchGroups).toContain({ x: 1, x2: 1, x3: 1, x4: 1 }); + expect(layoutOut._axisMatchGroups).toContain({ y: 1, y2: 1, y3: 1, y4: 1 }); // should coerce the 'missing' axes expect(layoutIn.xaxis).toBeDefined(); @@ -1111,18 +1111,18 @@ describe('Test axes', function() { expect(layoutOut.yaxis).toBeDefined(); }); - it('should find matching group even when matching a *missing* axis (nested case)', function() { + it('should find matching group even when matching a *missing* axis (nested case)', function () { layoutIn = { // N.B. xaxis isn't set // N.B. xaxis2 is set, but does not correspond to a subplot - xaxis2: {matches: 'x'}, - xaxis3: {matches: 'x2'}, - xaxis4: {matches: 'x3'}, + xaxis2: { matches: 'x' }, + xaxis3: { matches: 'x2' }, + xaxis4: { matches: 'x3' }, // N.B. yaxis isn't set // N.B yaxis2 does not correspond to a subplot and is useless here - yaxis2: {matches: 'y'}, - yaxis3: {matches: 'y'}, - yaxis4: {matches: 'y3'} + yaxis2: { matches: 'y' }, + yaxis3: { matches: 'y' }, + yaxis4: { matches: 'y3' } }; layoutOut._subplots.cartesian = ['x3y3', 'x4y4']; layoutOut._subplots.xaxis = ['x3', 'x4']; @@ -1131,8 +1131,8 @@ describe('Test axes', function() { supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut._axisMatchGroups.length).toBe(2); - expect(layoutOut._axisMatchGroups).toContain({x: 1, x2: 1, x3: 1, x4: 1}); - expect(layoutOut._axisMatchGroups).toContain({y: 1, y3: 1, y4: 1}); + expect(layoutOut._axisMatchGroups).toContain({ x: 1, x2: 1, x3: 1, x4: 1 }); + expect(layoutOut._axisMatchGroups).toContain({ y: 1, y3: 1, y4: 1 }); // should coerce the 'missing' axes expect(layoutIn.xaxis).toBeDefined(); @@ -1141,24 +1141,24 @@ describe('Test axes', function() { expect(layoutOut.yaxis).toBeDefined(); // should coerce useless axes - expect(layoutIn.yaxis2).toEqual({matches: 'y'}); + expect(layoutIn.yaxis2).toEqual({ matches: 'y' }); expect(layoutOut.yaxis2).toBeUndefined(); }); - it('should match set axis range value for matching axes', function() { + it('should match set axis range value for matching axes', function () { layoutIn = { // autorange case xaxis: {}, - xaxis2: {matches: 'x'}, + xaxis2: { matches: 'x' }, // matchee ax has range - yaxis: {range: [0, 1]}, - yaxis2: {matches: 'y'}, + yaxis: { range: [0, 1] }, + yaxis2: { matches: 'y' }, // first explicit range gets copied to both xaxis3: {}, - yaxis3: {range: [-1, 1], matches: 'x3'}, + yaxis3: { range: [-1, 1], matches: 'x3' }, // both ax have range - xaxis4: {range: [0, 2], matches: 'y4'}, - yaxis4: {range: [-1, 3], matches: 'x4'} + xaxis4: { range: [0, 2], matches: 'y4' }, + yaxis4: { range: [-1, 3], matches: 'x4' } }; layoutOut._subplots.cartesian.push('x2y2', 'x3y3', 'x4y4'); layoutOut._subplots.xaxis.push('x2', 'x3', 'x4'); @@ -1167,13 +1167,13 @@ describe('Test axes', function() { supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut._axisMatchGroups.length).toBe(4); - expect(layoutOut._axisMatchGroups).toContain({x: 1, x2: 1}); - expect(layoutOut._axisMatchGroups).toContain({y: 1, y2: 1}); - expect(layoutOut._axisMatchGroups).toContain({x3: 1, y3: 1}); - expect(layoutOut._axisMatchGroups).toContain({x4: 1, y4: 1}); + expect(layoutOut._axisMatchGroups).toContain({ x: 1, x2: 1 }); + expect(layoutOut._axisMatchGroups).toContain({ y: 1, y2: 1 }); + expect(layoutOut._axisMatchGroups).toContain({ x3: 1, y3: 1 }); + expect(layoutOut._axisMatchGroups).toContain({ x4: 1, y4: 1 }); function _assertMatchingAxes(names, autorange, rng) { - names.forEach(function(n) { + names.forEach(function (n) { var ax = layoutOut[n]; expect(ax.autorange).toBe(autorange, n); expect(ax.range[0]).toBe(rng[0], n); @@ -1187,12 +1187,12 @@ describe('Test axes', function() { _assertMatchingAxes(['xaxis4', 'yaxis4'], false, [-1, 3]); }); - it('should match set axis range value for matching axes even when matching a *missing* axis', function() { + it('should match set axis range value for matching axes even when matching a *missing* axis', function () { layoutIn = { // N.B. xaxis is set, but does not correspond to a subplot - xaxis: {range: [0, 1]}, - xaxis2: {matches: 'x'}, - xaxis4: {matches: 'x'} + xaxis: { range: [0, 1] }, + xaxis2: { matches: 'x' }, + xaxis4: { matches: 'x' } }; layoutOut._subplots.cartesian = ['x2y2', 'x4y4']; layoutOut._subplots.xaxis = ['x2', 'x4']; @@ -1201,21 +1201,21 @@ describe('Test axes', function() { supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut._axisMatchGroups.length).toBe(1); - expect(layoutOut._axisMatchGroups).toContain({x: 1, x2: 1, x4: 1}); + expect(layoutOut._axisMatchGroups).toContain({ x: 1, x2: 1, x4: 1 }); expect(layoutOut.xaxis.range).withContext('xaxis.range').toEqual([0, 1]); expect(layoutOut.xaxis2.range).withContext('xaxis2.range').toEqual([0, 1]); expect(layoutOut.xaxis4.range).withContext('xaxis4.range').toEqual([0, 1]); }); - it('should match set axis range value for matching axes even when matching a *missing* axis (nested case)', function() { + it('should match set axis range value for matching axes even when matching a *missing* axis (nested case)', function () { layoutIn = { // N.B. xaxis is set, but does not correspond to a subplot - xaxis: {range: [0, 1]}, + xaxis: { range: [0, 1] }, // N.B. xaxis2 is set, but does not correspond to a subplot - xaxis2: {matches: 'x'}, - xaxis3: {matches: 'x2'}, - xaxis4: {matches: 'x3'} + xaxis2: { matches: 'x' }, + xaxis3: { matches: 'x2' }, + xaxis4: { matches: 'x3' } }; layoutOut._subplots.cartesian = ['x3y3', 'x4y4']; layoutOut._subplots.xaxis = ['x3', 'x4']; @@ -1224,7 +1224,7 @@ describe('Test axes', function() { supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut._axisMatchGroups.length).toBe(1); - expect(layoutOut._axisMatchGroups).toContain({x: 1, x2: 1, x3: 1, x4: 1}); + expect(layoutOut._axisMatchGroups).toContain({ x: 1, x2: 1, x3: 1, x4: 1 }); expect(layoutOut.xaxis.range).withContext('xaxis.range').toEqual([0, 1]); expect(layoutOut.xaxis2.range).withContext('xaxis2.range').toEqual([0, 1]); @@ -1232,10 +1232,10 @@ describe('Test axes', function() { expect(layoutOut.xaxis4.range).withContext('xaxis4.range').toEqual([0, 1]); }); - it('should propagate axis type into *missing* axes', function() { + it('should propagate axis type into *missing* axes', function () { layoutIn = { - xaxis2: {type: 'date', matches: 'x'}, - yaxis: {type: 'category', matches: 'y2'} + xaxis2: { type: 'date', matches: 'x' }, + yaxis: { type: 'category', matches: 'y2' } }; layoutOut._subplots.cartesian = ['x2y']; layoutOut._subplots.xaxis = ['x2']; @@ -1244,8 +1244,8 @@ describe('Test axes', function() { supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut._axisMatchGroups.length).toBe(2); - expect(layoutOut._axisMatchGroups).toContain({x: 1, x2: 1}); - expect(layoutOut._axisMatchGroups).toContain({y: 1, y2: 1}); + expect(layoutOut._axisMatchGroups).toContain({ x: 1, x2: 1 }); + expect(layoutOut._axisMatchGroups).toContain({ y: 1, y2: 1 }); expect(layoutOut.xaxis.type).withContext('xaxis.type').toBe('date'); expect(layoutOut.xaxis2.type).withContext('xaxis2.type').toBe('date'); @@ -1253,12 +1253,12 @@ describe('Test axes', function() { expect(layoutOut.yaxis2.type).withContext('yaxis2.type').toBe('category'); }); - it('should adapt default axis ranges to *rangemode*', function() { + it('should adapt default axis ranges to *rangemode*', function () { layoutIn = { - xaxis: {rangemode: 'tozero'}, - yaxis: {rangemode: 'nonnegative'}, - xaxis2: {rangemode: 'nonnegative'}, - yaxis2: {rangemode: 'tozero'} + xaxis: { rangemode: 'tozero' }, + yaxis: { rangemode: 'nonnegative' }, + xaxis2: { rangemode: 'nonnegative' }, + yaxis2: { rangemode: 'tozero' } }; layoutOut._subplots.cartesian.push('x2y2'); layoutOut._subplots.xaxis.push('x2'); @@ -1272,15 +1272,15 @@ describe('Test axes', function() { expect(layoutOut.yaxis2.range).withContext('yaxis2 range').toEqual([0, 4]); }); - it('should coerce *rangebreaks* container only on a date axis', function() { + it('should coerce *rangebreaks* container only on a date axis', function () { var bounds = ['2020-01-10', '2020-01-11']; layoutIn = { - xaxis: {rangebreaks: [{bounds: bounds}], type: 'date'}, - xaxis2: {rangebreaks: [{bounds: bounds}], type: '-'}, - xaxis3: {rangebreaks: [{bounds: bounds}], type: 'linear'}, - xaxis4: {rangebreaks: [{bounds: bounds}], type: 'log'}, - xaxis5: {rangebreaks: [{bounds: bounds}], type: 'category'}, - xaxis6: {rangebreaks: [{bounds: bounds}], type: 'multicategory'} + xaxis: { rangebreaks: [{ bounds: bounds }], type: 'date' }, + xaxis2: { rangebreaks: [{ bounds: bounds }], type: '-' }, + xaxis3: { rangebreaks: [{ bounds: bounds }], type: 'linear' }, + xaxis4: { rangebreaks: [{ bounds: bounds }], type: 'log' }, + xaxis5: { rangebreaks: [{ bounds: bounds }], type: 'category' }, + xaxis6: { rangebreaks: [{ bounds: bounds }], type: 'multicategory' } }; layoutOut._subplots.xaxis.push('x2', 'x3', 'x4', 'x5', 'x6'); supplyLayoutDefaults(layoutIn, layoutOut, fullData); @@ -1294,12 +1294,12 @@ describe('Test axes', function() { expect(layoutOut.xaxis6.rangebreaks).toBeUndefined(); }); - it('should coerce *rangebreaks* container only when it is a non-empty array', function() { + it('should coerce *rangebreaks* container only when it is a non-empty array', function () { layoutIn = { - xaxis: {type: 'date', rangebreaks: [{bounds: ['2020-01-10', '2020-01-11']}]}, - xaxis2: {type: 'date', rangebreaks: []}, - xaxis3: {type: 'date', rangebreaks: false}, - xaxis4: {type: 'date'} + xaxis: { type: 'date', rangebreaks: [{ bounds: ['2020-01-10', '2020-01-11'] }] }, + xaxis2: { type: 'date', rangebreaks: [] }, + xaxis3: { type: 'date', rangebreaks: false }, + xaxis4: { type: 'date' } }; layoutOut._subplots.xaxis.push('x2', 'x3', 'x4'); supplyLayoutDefaults(layoutIn, layoutOut, fullData); @@ -1311,12 +1311,12 @@ describe('Test axes', function() { expect(layoutOut.xaxis4.rangebreaks).toBeUndefined(); }); - it('should set *rangebreaks* to *enabled:false* when *bounds* have less than 2 items', function() { + it('should set *rangebreaks* to *enabled:false* when *bounds* have less than 2 items', function () { layoutIn = { - xaxis: {type: 'date', rangebreaks: [{bounds: ['2020-01-10']}]}, - xaxis2: {type: 'date', rangebreaks: [{bounds: ['2020-01-10'], values: ['2020-01-11']}]}, - xaxis3: {type: 'date', rangebreaks: [{bounds: ['2020-01-10'], values: {}}]}, - xaxis4: {type: 'date', rangebreaks: [{bounds: ['2020-01-10', '2020-01-11', '2020-01-12']}]} + xaxis: { type: 'date', rangebreaks: [{ bounds: ['2020-01-10'] }] }, + xaxis2: { type: 'date', rangebreaks: [{ bounds: ['2020-01-10'], values: ['2020-01-11'] }] }, + xaxis3: { type: 'date', rangebreaks: [{ bounds: ['2020-01-10'], values: {} }] }, + xaxis4: { type: 'date', rangebreaks: [{ bounds: ['2020-01-10', '2020-01-11', '2020-01-12'] }] } }; layoutOut._subplots.xaxis.push('x2', 'x3', 'x4'); supplyLayoutDefaults(layoutIn, layoutOut, fullData); @@ -1328,12 +1328,12 @@ describe('Test axes', function() { .withContext('valid *bounds*, sliced to length=2').toEqual(['2020-01-10', '2020-01-11']); }); - it('if *rangebreaks* *bounds* are bigger than the set *range*, disable rangebreak', function() { + it('if *rangebreaks* *bounds* are bigger than the set *range*, disable rangebreak', function () { layoutIn = { - xaxis: {type: 'date', range: ['2020-01-10', '2020-01-14'], rangebreaks: [{bounds: ['2020-01-11', '2020-01-12']}]}, - xaxis2: {type: 'date', range: ['2020-01-11', '2020-01-12'], rangebreaks: [{bounds: ['2020-01-10', '2020-01-14']}]}, - xaxis3: {type: 'date', range: ['2020-01-14', '2020-01-10'], rangebreaks: [{bounds: ['2020-01-12', '2020-01-11']}]}, - xaxis4: {type: 'date', range: ['2020-01-12', '2020-01-11'], rangebreaks: [{bounds: ['2020-01-14', '2020-01-10']}]} + xaxis: { type: 'date', range: ['2020-01-10', '2020-01-14'], rangebreaks: [{ bounds: ['2020-01-11', '2020-01-12'] }] }, + xaxis2: { type: 'date', range: ['2020-01-11', '2020-01-12'], rangebreaks: [{ bounds: ['2020-01-10', '2020-01-14'] }] }, + xaxis3: { type: 'date', range: ['2020-01-14', '2020-01-10'], rangebreaks: [{ bounds: ['2020-01-12', '2020-01-11'] }] }, + xaxis4: { type: 'date', range: ['2020-01-12', '2020-01-11'], rangebreaks: [{ bounds: ['2020-01-14', '2020-01-10'] }] } }; layoutOut._subplots.xaxis.push('x2', 'x3', 'x4'); supplyLayoutDefaults(layoutIn, layoutOut, fullData); @@ -1344,12 +1344,12 @@ describe('Test axes', function() { expect(layoutOut.xaxis4.rangebreaks[0].enabled).toBe(false, '*bounds* bigger than set range (reversed)'); }); - it('should coerce *rangebreaks* *bounds* over *values*/*dvalue* if both are present', function() { + it('should coerce *rangebreaks* *bounds* over *values*/*dvalue* if both are present', function () { layoutIn = { - xaxis: {type: 'date', rangebreaks: [{bounds: ['2020-01-10', '2020-01-11']}]}, - xaxis2: {type: 'date', rangebreaks: [{values: ['2020-01-10', '2020-01-12', '2020-01-14'], dvalue: 2}]}, - xaxis3: {type: 'date', rangebreaks: [{bounds: ['2020-01-10', '2020-01-11'], values: ['2020-01-10', '2020-01-12', '2020-01-14'], dvalue: 2}]}, - xaxis4: {type: 'date', rangebreaks: [{bounds: false, values: ['2020-01-10', '2020-01-12', '2020-01-14'], dvalue: 2}]}, + xaxis: { type: 'date', rangebreaks: [{ bounds: ['2020-01-10', '2020-01-11'] }] }, + xaxis2: { type: 'date', rangebreaks: [{ values: ['2020-01-10', '2020-01-12', '2020-01-14'], dvalue: 2 }] }, + xaxis3: { type: 'date', rangebreaks: [{ bounds: ['2020-01-10', '2020-01-11'], values: ['2020-01-10', '2020-01-12', '2020-01-14'], dvalue: 2 }] }, + xaxis4: { type: 'date', rangebreaks: [{ bounds: false, values: ['2020-01-10', '2020-01-12', '2020-01-14'], dvalue: 2 }] }, }; layoutOut._subplots.xaxis.push('x2', 'x3', 'x4'); supplyLayoutDefaults(layoutIn, layoutOut, fullData); @@ -1375,11 +1375,11 @@ describe('Test axes', function() { expect(xaBreak.dvalue).toBe(2, 'valid *dvalue*'); }); - it('should only coerce rangebreaks *pattern* with *bounds*', function() { + it('should only coerce rangebreaks *pattern* with *bounds*', function () { layoutIn = { - xaxis: {type: 'date', rangebreaks: [{bounds: ['2020-01-04', '2020-01-05']}]}, - xaxis2: {type: 'date', rangebreaks: [{bounds: [6, 1], pattern: 'day of week'}]}, - xaxis3: {type: 'date', rangebreaks: [{values: ['2020-01-04', '2020-01-05'], pattern: 'NOP'}]}, + xaxis: { type: 'date', rangebreaks: [{ bounds: ['2020-01-04', '2020-01-05'] }] }, + xaxis2: { type: 'date', rangebreaks: [{ bounds: [6, 1], pattern: 'day of week' }] }, + xaxis3: { type: 'date', rangebreaks: [{ values: ['2020-01-04', '2020-01-05'], pattern: 'NOP' }] }, }; layoutOut._subplots.xaxis.push('x2', 'x3'); supplyLayoutDefaults(layoutIn, layoutOut, fullData); @@ -1389,17 +1389,21 @@ describe('Test axes', function() { expect(layoutOut.xaxis3.rangebreaks[0].pattern).toBe(undefined, 'not coerce, using *values*'); }); - it('should auto default rangebreaks.pattern to *day of week* when *bounds* include a weekday string and convert bounds to integer days', function() { + it('should auto default rangebreaks.pattern to *day of week* when *bounds* include a weekday string and convert bounds to integer days', function () { layoutIn = { - xaxis: {type: 'date', rangebreaks: [ - {bounds: ['Saturday', 'Monday']} - ]}, - xaxis2: {type: 'date', rangebreaks: [ - {bounds: ['sun', 'thu']}, - {bounds: ['mon', 'fri']}, - {bounds: ['tue', 'sat']}, - {bounds: ['wed', '-1']} - ]} + xaxis: { + type: 'date', rangebreaks: [ + { bounds: ['Saturday', 'Monday'] } + ] + }, + xaxis2: { + type: 'date', rangebreaks: [ + { bounds: ['sun', 'thu'] }, + { bounds: ['mon', 'fri'] }, + { bounds: ['tue', 'sat'] }, + { bounds: ['wed', '-1'] } + ] + } }; layoutOut._subplots.xaxis.push('x2'); supplyLayoutDefaults(layoutIn, layoutOut, fullData); @@ -1416,19 +1420,19 @@ describe('Test axes', function() { expect(layoutOut.xaxis2.rangebreaks[3].bounds[1]).toBe('-1', 'string'); }); - it('should validate inputs in respect to *day of week* pattern', function() { + it('should validate inputs in respect to *day of week* pattern', function () { layoutIn = { - xaxis: {type: 'date', rangebreaks: [{pattern: 'day of week', bounds: ['6', '0'] }]}, - xaxis2: {type: 'date', rangebreaks: [{bounds: ['Sunday'] }]}, - xaxis3: {type: 'date', rangebreaks: [{bounds: ['sun', 'mon', 'tue'] }]}, - xaxis4: {type: 'date', rangebreaks: [{pattern: 'day of week', bounds: [1, '-1'] }]}, - xaxis5: {type: 'date', rangebreaks: [{pattern: 'day of week', bounds: [1, '-.25'] }]}, - xaxis6: {type: 'date', rangebreaks: [{pattern: 'day of week', bounds: [1, '7'] }]}, - xaxis7: {type: 'date', rangebreaks: [{pattern: 'day of week', bounds: [1, '6.75'] }]}, - xaxis8: {type: 'date', rangebreaks: [{pattern: 'day of week', bounds: [1, ''] }]}, - xaxis9: {type: 'date', rangebreaks: [{pattern: 'day of week', bounds: [1, null] }]}, - xaxis10: {type: 'date', rangebreaks: [{pattern: 'day of week', bounds: [1, false] }]}, - xaxis11: {type: 'date', rangebreaks: [{pattern: 'day of week', bounds: [1, true] }]} + xaxis: { type: 'date', rangebreaks: [{ pattern: 'day of week', bounds: ['6', '0'] }] }, + xaxis2: { type: 'date', rangebreaks: [{ bounds: ['Sunday'] }] }, + xaxis3: { type: 'date', rangebreaks: [{ bounds: ['sun', 'mon', 'tue'] }] }, + xaxis4: { type: 'date', rangebreaks: [{ pattern: 'day of week', bounds: [1, '-1'] }] }, + xaxis5: { type: 'date', rangebreaks: [{ pattern: 'day of week', bounds: [1, '-.25'] }] }, + xaxis6: { type: 'date', rangebreaks: [{ pattern: 'day of week', bounds: [1, '7'] }] }, + xaxis7: { type: 'date', rangebreaks: [{ pattern: 'day of week', bounds: [1, '6.75'] }] }, + xaxis8: { type: 'date', rangebreaks: [{ pattern: 'day of week', bounds: [1, ''] }] }, + xaxis9: { type: 'date', rangebreaks: [{ pattern: 'day of week', bounds: [1, null] }] }, + xaxis10: { type: 'date', rangebreaks: [{ pattern: 'day of week', bounds: [1, false] }] }, + xaxis11: { type: 'date', rangebreaks: [{ pattern: 'day of week', bounds: [1, true] }] } }; layoutOut._subplots.xaxis.push('x2', 'x3', 'x4', 'x5', 'x6', 'x7', 'x8', 'x9', 'x10', 'x11'); supplyLayoutDefaults(layoutIn, layoutOut, fullData); @@ -1449,19 +1453,19 @@ describe('Test axes', function() { expect(layoutOut.xaxis11.rangebreaks[0].enabled).toBe(false, 'reject true'); }); - it('should validate inputs in respect to *hour* pattern', function() { + it('should validate inputs in respect to *hour* pattern', function () { layoutIn = { - xaxis: {type: 'date', rangebreaks: [{pattern: 'hour', bounds: ['24', '1e-3'] }]}, - xaxis2: {type: 'date', rangebreaks: [{pattern: 'hour', bounds: [1] }]}, - xaxis3: {type: 'date', rangebreaks: [{pattern: 'hour', bounds: [1, 2, 3] }]}, - xaxis4: {type: 'date', rangebreaks: [{pattern: 'hour', bounds: [1, '-1'] }]}, - xaxis5: {type: 'date', rangebreaks: [{pattern: 'hour', bounds: [1, '-.001'] }]}, - xaxis6: {type: 'date', rangebreaks: [{pattern: 'hour', bounds: [1, '24.001'] }]}, - xaxis7: {type: 'date', rangebreaks: [{pattern: 'hour', bounds: [1, '23.999'] }]}, - xaxis8: {type: 'date', rangebreaks: [{pattern: 'day of week', bounds: [1, ''] }]}, - xaxis9: {type: 'date', rangebreaks: [{pattern: 'day of week', bounds: [1, null] }]}, - xaxis10: {type: 'date', rangebreaks: [{pattern: 'day of week', bounds: [1, false] }]}, - xaxis11: {type: 'date', rangebreaks: [{pattern: 'day of week', bounds: [1, true] }]} + xaxis: { type: 'date', rangebreaks: [{ pattern: 'hour', bounds: ['24', '1e-3'] }] }, + xaxis2: { type: 'date', rangebreaks: [{ pattern: 'hour', bounds: [1] }] }, + xaxis3: { type: 'date', rangebreaks: [{ pattern: 'hour', bounds: [1, 2, 3] }] }, + xaxis4: { type: 'date', rangebreaks: [{ pattern: 'hour', bounds: [1, '-1'] }] }, + xaxis5: { type: 'date', rangebreaks: [{ pattern: 'hour', bounds: [1, '-.001'] }] }, + xaxis6: { type: 'date', rangebreaks: [{ pattern: 'hour', bounds: [1, '24.001'] }] }, + xaxis7: { type: 'date', rangebreaks: [{ pattern: 'hour', bounds: [1, '23.999'] }] }, + xaxis8: { type: 'date', rangebreaks: [{ pattern: 'day of week', bounds: [1, ''] }] }, + xaxis9: { type: 'date', rangebreaks: [{ pattern: 'day of week', bounds: [1, null] }] }, + xaxis10: { type: 'date', rangebreaks: [{ pattern: 'day of week', bounds: [1, false] }] }, + xaxis11: { type: 'date', rangebreaks: [{ pattern: 'day of week', bounds: [1, true] }] } }; layoutOut._subplots.xaxis.push('x2', 'x3', 'x4', 'x5', 'x6', 'x7', 'x8', 'x9', 'x10', 'x11'); supplyLayoutDefaults(layoutIn, layoutOut, fullData); @@ -1482,10 +1486,10 @@ describe('Test axes', function() { expect(layoutOut.xaxis11.rangebreaks[0].enabled).toBe(false, 'reject true'); }); - it('should coerce autoshift and shift only if anchor is *free*', function() { + it('should coerce autoshift and shift only if anchor is *free*', function () { layoutIn = { xaxis: {}, - yaxis: {anchor: 'free'} + yaxis: { anchor: 'free' } }; supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut.yaxis.autoshift).toBe(false); @@ -1502,29 +1506,29 @@ describe('Test axes', function() { expect(layoutOut.yaxis.shift).toBeUndefined(); }); - it('should set automargin to *true* when shift is *true*', function() { + it('should set automargin to *true* when shift is *true*', function () { layoutIn = { xaxis: {}, - yaxis: {autoshift: true, anchor: 'free'} + yaxis: { autoshift: true, anchor: 'free' } }; supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut.yaxis.automargin).toBe(true); }); - it('should set automargin to *false* when shift is numeric', function() { + it('should set automargin to *false* when shift is numeric', function () { layoutIn = { xaxis: {}, - yaxis: {shift: 100, anchor: 'free'} + yaxis: { shift: 100, anchor: 'free' } }; supplyLayoutDefaults(layoutIn, layoutOut, fullData); expect(layoutOut.yaxis.automargin).toBe(false); }); - it('should set default axis position if shift is *true* according to overlaying domain', function() { + it('should set default axis position if shift is *true* according to overlaying domain', function () { layoutIn = { - xaxis: {domain: [0.2, 0.5]}, + xaxis: { domain: [0.2, 0.5] }, yaxis: {}, - yaxis2: {autoshift: true, anchor: 'free', overlaying: 'y'} + yaxis2: { autoshift: true, anchor: 'free', overlaying: 'y' } }; layoutOut._subplots.cartesian.push('xy2'); @@ -1543,16 +1547,16 @@ describe('Test axes', function() { }); }); - describe('autorange relayout', function() { + describe('autorange relayout', function () { var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); afterEach(destroyGraphDiv); - it('can relayout autorange', function(done) { + it('can relayout autorange', function (done) { Plotly.newPlot(gd, { data: [{ x: [0, 1], @@ -1574,24 +1578,24 @@ describe('Test axes', function() { autorange: true, } } - }).then(function() { + }).then(function () { expect(gd._fullLayout.xaxis.range).toEqual([-1, 6]); expect(gd._fullLayout.yaxis.range).toBeCloseToArray([-0.07, 1.07]); return Plotly.relayout(gd, 'yaxis.autorange', false); - }).then(function() { + }).then(function () { expect(gd._fullLayout.yaxis.autorange).toBe(false); expect(gd._fullLayout.yaxis.range).toBeCloseToArray([-0.07, 1.07]); return Plotly.relayout(gd, 'xaxis.autorange', true); - }).then(function() { + }).then(function () { expect(gd._fullLayout.xaxis.autorange).toBe(true); expect(gd._fullLayout.xaxis.range).toBeCloseToArray([-0.07, 1.07]); }) - .then(done, done.fail); + .then(done, done.fail); }); - it('can relayout one partial range without affecting other subplots', function(done) { + it('can relayout one partial range without affecting other subplots', function (done) { var rangeX2; var rangeX3; var rangeX4; @@ -1666,7 +1670,7 @@ describe('Test axes', function() { side: 'right', } } - }).then(function() { + }).then(function () { rangeX2 = gd._fullLayout.xaxis2.range.slice(); rangeX3 = gd._fullLayout.xaxis3.range.slice(); rangeX4 = gd._fullLayout.xaxis4.range.slice(); @@ -1676,7 +1680,7 @@ describe('Test axes', function() { autorangeX4 = gd._fullLayout.xaxis4.autorange; return Plotly.relayout(gd, 'xaxis.range', [1, 2]); - }).then(function() { + }).then(function () { expect(gd._fullLayout.xaxis2.range).toEqual(rangeX2); expect(gd._fullLayout.xaxis3.range).toEqual(rangeX3); expect(gd._fullLayout.xaxis4.range).toEqual(rangeX4); @@ -1685,10 +1689,10 @@ describe('Test axes', function() { expect(gd._fullLayout.xaxis3.autorange).toEqual(autorangeX3); expect(gd._fullLayout.xaxis4.autorange).toEqual(autorangeX4); }) - .then(done, done.fail); + .then(done, done.fail); }); - it('should make room for the inside labels of the counter axes', function(done) { + it('should make room for the inside labels of the counter axes', function (done) { Plotly.newPlot(gd, { data: [{ x: [1, 2, 3], @@ -1702,53 +1706,54 @@ describe('Test axes', function() { yaxis: { ticklabelposition: 'inside' }, xaxis: { range: [1.5, 2.5] } } - }).then(function() { + }).then(function () { expect(gd._fullLayout.xaxis.range).toEqual([1.5, 2.5]); return Plotly.relayout(gd, 'xaxis.autorange', true); - }).then(function() { + }).then(function () { expect(gd._fullLayout.xaxis.range).toBeCloseToArray([0.37, 3.22], 1); }) - .then(done, done.fail); + .then(done, done.fail); }); }); - describe('insiderange relayout', function() { + describe('insiderange relayout', function () { var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); afterEach(destroyGraphDiv); - it('can relayout insiderange', function(done) { + it('can relayout insiderange', function (done) { Plotly.newPlot(gd, [{ - y: [1, 3, 2, 4]} + y: [1, 3, 2, 4] + } ], { - xaxis: {insiderange: [0, 2]}, - yaxis: {ticklabelposition: 'inside'}, + xaxis: { insiderange: [0, 2] }, + yaxis: { ticklabelposition: 'inside' }, plot_bgcolor: 'lightgray', width: 600, height: 600 - }).then(function() { + }).then(function () { expect(gd._fullLayout.xaxis.range).toBeCloseToArray([-0.12, 2]); return Plotly.relayout(gd, { 'xaxis.insiderange': [1, 3] }); - }).then(function() { + }).then(function () { expect(gd._fullLayout.xaxis.range).toBeCloseToArray([0.879, 3]); }).then(done, done.fail); }); }); - describe('minallowed / maxallowed', function() { + describe('minallowed / maxallowed', function () { // regression test for https://github.com/plotly/plotly.js/issues/7717 var gd; - beforeEach(function() { gd = createGraphDiv(); }); + beforeEach(function () { gd = createGraphDiv(); }); afterEach(destroyGraphDiv); function expectForward(done, minallowed) { @@ -1757,45 +1762,45 @@ describe('Test axes', function() { y: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }], { xaxis: { minallowed: minallowed } - }).then(function() { + }).then(function () { var r = gd._fullLayout.xaxis.range; expect(r[0]).toBeLessThan(r[1], 'axis should not be reversed for minallowed=' + minallowed); expect(r[0]).toBe(minallowed, 'axis min should be pinned at minallowed'); }).then(done, done.fail); } - it('does not reverse axis when minallowed exceeds default range max', function(done) { + it('does not reverse axis when minallowed exceeds default range max', function (done) { expectForward(done, 7); }); - it('does not reverse axis when minallowed equals default range max', function(done) { + it('does not reverse axis when minallowed equals default range max', function (done) { expectForward(done, 6); }); - it('does not reverse axis when minallowed is well above default range max', function(done) { + it('does not reverse axis when minallowed is well above default range max', function (done) { expectForward(done, 100); }); - it('keeps explicit autorange:reversed even when minallowed is set', function(done) { + it('keeps explicit autorange:reversed even when minallowed is set', function (done) { Plotly.newPlot(gd, [{ x: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], y: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }], { xaxis: { autorange: 'reversed', minallowed: 7 } - }).then(function() { + }).then(function () { var r = gd._fullLayout.xaxis.range; expect(r[0]).toBeGreaterThan(r[1], 'axis should remain reversed'); expect(r[1]).toBe(7, 'min slot (range[1] when reversed) should be minallowed'); }).then(done, done.fail); }); - it('does not reverse axis when maxallowed is below default range min', function(done) { + it('does not reverse axis when maxallowed is below default range min', function (done) { Plotly.newPlot(gd, [{ x: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], y: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }], { xaxis: { maxallowed: -2 } - }).then(function() { + }).then(function () { var r = gd._fullLayout.xaxis.range; expect(r[0]).toBeLessThan(r[1], 'axis should not be reversed'); expect(r[1]).toBe(-2, 'axis max should be pinned at maxallowed'); @@ -1803,44 +1808,44 @@ describe('Test axes', function() { }); }); - describe('constraints relayout', function() { + describe('constraints relayout', function () { var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); afterEach(destroyGraphDiv); - it('updates ranges when adding, removing, or changing a constraint', function(done) { + it('updates ranges when adding, removing, or changing a constraint', function (done) { Plotly.newPlot(gd, - [{z: [[0, 1], [2, 3]], type: 'heatmap'}], + [{ z: [[0, 1], [2, 3]], type: 'heatmap' }], // plot area is 200x100 px - {width: 400, height: 300, margin: {l: 100, r: 100, t: 100, b: 100}} + { width: 400, height: 300, margin: { l: 100, r: 100, t: 100, b: 100 } } ) - .then(function() { - expect(gd.layout.xaxis.range).toBeCloseToArray([-0.5, 1.5], 5); - expect(gd.layout.yaxis.range).toBeCloseToArray([-0.5, 1.5], 5); + .then(function () { + expect(gd.layout.xaxis.range).toBeCloseToArray([-0.5, 1.5], 5); + expect(gd.layout.yaxis.range).toBeCloseToArray([-0.5, 1.5], 5); - return Plotly.relayout(gd, {'xaxis.scaleanchor': 'y'}); - }) - .then(function() { - expect(gd.layout.xaxis.range).toBeCloseToArray([-1.5, 2.5], 5); - expect(gd.layout.yaxis.range).toBeCloseToArray([-0.5, 1.5], 5); + return Plotly.relayout(gd, { 'xaxis.scaleanchor': 'y' }); + }) + .then(function () { + expect(gd.layout.xaxis.range).toBeCloseToArray([-1.5, 2.5], 5); + expect(gd.layout.yaxis.range).toBeCloseToArray([-0.5, 1.5], 5); - return Plotly.relayout(gd, {'xaxis.scaleratio': 10}); - }) - .then(function() { - expect(gd.layout.xaxis.range).toBeCloseToArray([-0.5, 1.5], 5); - expect(gd.layout.yaxis.range).toBeCloseToArray([-4.5, 5.5], 5); + return Plotly.relayout(gd, { 'xaxis.scaleratio': 10 }); + }) + .then(function () { + expect(gd.layout.xaxis.range).toBeCloseToArray([-0.5, 1.5], 5); + expect(gd.layout.yaxis.range).toBeCloseToArray([-4.5, 5.5], 5); - return Plotly.relayout(gd, {'xaxis.scaleanchor': null}); - }) - .then(function() { - expect(gd.layout.xaxis.range).toBeCloseToArray([-0.5, 1.5], 5); - expect(gd.layout.yaxis.range).toBeCloseToArray([-0.5, 1.5], 5); - }) - .then(done, done.fail); + return Plotly.relayout(gd, { 'xaxis.scaleanchor': null }); + }) + .then(function () { + expect(gd.layout.xaxis.range).toBeCloseToArray([-0.5, 1.5], 5); + expect(gd.layout.yaxis.range).toBeCloseToArray([-0.5, 1.5], 5); + }) + .then(done, done.fail); }); function assertRangeDomain(axName, range, domainIn, domainOut, msg) { @@ -1867,255 +1872,255 @@ describe('Test axes', function() { 'input range, ' + msg + ': ' + ax.range); } - it('can change axis domain on call to react when template is present', function(done) { + it('can change axis domain on call to react when template is present', function (done) { Plotly.newPlot(gd, - [{z: [[0, 1], [2, 3]], type: 'heatmap'}], - { template: {}, xaxis: { domain: [0,1], scaleanchor: 'y' } } + [{ z: [[0, 1], [2, 3]], type: 'heatmap' }], + { template: {}, xaxis: { domain: [0, 1], scaleanchor: 'y' } } ) - .then(function() { - return Plotly.react(gd, - [{z: [[0, 1], [2, 3]], type: 'heatmap'}], - { template: {}, xaxis: { domain: [0.1, 0.9] } } - ); - }) - .then(function() { - assertRangeDomain('xaxis', [-0.5,1.5], [0.1, 0.9], [0.1, 0.9]); - }) - .then(done, done.fail); + .then(function () { + return Plotly.react(gd, + [{ z: [[0, 1], [2, 3]], type: 'heatmap' }], + { template: {}, xaxis: { domain: [0.1, 0.9] } } + ); + }) + .then(function () { + assertRangeDomain('xaxis', [-0.5, 1.5], [0.1, 0.9], [0.1, 0.9]); + }) + .then(done, done.fail); }); - it('can change per-axis constrain:domain/range and constraintoward', function(done) { + it('can change per-axis constrain:domain/range and constraintoward', function (done) { Plotly.newPlot(gd, // start with a heatmap as it has no padding so calculations are easy - [{z: [[0, 1], [2, 3]], type: 'heatmap'}], + [{ z: [[0, 1], [2, 3]], type: 'heatmap' }], // plot area is 200x100 px { width: 400, height: 300, - margin: {l: 100, r: 100, t: 100, b: 100}, - xaxis: {constrain: 'domain'}, - yaxis: {constraintoward: 'top', scaleanchor: 'x'} + margin: { l: 100, r: 100, t: 100, b: 100 }, + xaxis: { constrain: 'domain' }, + yaxis: { constraintoward: 'top', scaleanchor: 'x' } } ) - .then(function() { - // x axis is constrained, but by domain rather than by range - assertRangeDomain('xaxis', [-0.5, 1.5], [0, 1], [0.25, 0.75]); - assertRangeDomain('yaxis', [-0.5, 1.5], [0, 1], [0, 1]); - - return Plotly.relayout(gd, { - 'xaxis.constraintoward': 'right', - 'xaxis.domain': [0.05, 0.95], - // no effect for now, y is not constrained - 'yaxis.constraintoward': 'bottom', - 'yaxis.constrain': 'domain' - }); - }) - .then(function() { - // debatable I guess... you asked for an explicit domain but got a - // smaller one due to the constraint, which is not how it works - // if you ask for a new range (in that case you get exactly that - // range and other axes adjust to accommodate that) but my rationale - // is that modifying domain is usually done at an earlier stage in - // making the chart so should affect the "envelope", not the more - // dynamic behavior of interaction like when you set a range. - assertRangeDomain('xaxis', [-0.5, 1.5], [0.05, 0.95], [0.45, 0.95]); - assertRangeDomain('yaxis', [-0.5, 1.5], [0, 1], [0, 1]); - - return Plotly.relayout(gd, {'xaxis.constrain': 'range'}); - }) - .then(function() { - assertRangeDomain('xaxis', [-2.1, 1.5], [0.05, 0.95], [0.05, 0.95]); - assertRangeDomain('yaxis', [-0.5, 1.5], [0, 1], [0, 1]); - - return Plotly.relayout(gd, { - 'xaxis.domain': null, - 'xaxis.range[0]': -6.5 - }); - }) - .then(function() { - assertRangeDomain('xaxis', [-6.5, 1.5], [0, 1], [0, 1]); - assertRangeDomain('yaxis', [-0.5, 1.5], [0, 1], [0, 0.5]); + .then(function () { + // x axis is constrained, but by domain rather than by range + assertRangeDomain('xaxis', [-0.5, 1.5], [0, 1], [0.25, 0.75]); + assertRangeDomain('yaxis', [-0.5, 1.5], [0, 1], [0, 1]); + + return Plotly.relayout(gd, { + 'xaxis.constraintoward': 'right', + 'xaxis.domain': [0.05, 0.95], + // no effect for now, y is not constrained + 'yaxis.constraintoward': 'bottom', + 'yaxis.constrain': 'domain' + }); + }) + .then(function () { + // debatable I guess... you asked for an explicit domain but got a + // smaller one due to the constraint, which is not how it works + // if you ask for a new range (in that case you get exactly that + // range and other axes adjust to accommodate that) but my rationale + // is that modifying domain is usually done at an earlier stage in + // making the chart so should affect the "envelope", not the more + // dynamic behavior of interaction like when you set a range. + assertRangeDomain('xaxis', [-0.5, 1.5], [0.05, 0.95], [0.45, 0.95]); + assertRangeDomain('yaxis', [-0.5, 1.5], [0, 1], [0, 1]); + + return Plotly.relayout(gd, { 'xaxis.constrain': 'range' }); + }) + .then(function () { + assertRangeDomain('xaxis', [-2.1, 1.5], [0.05, 0.95], [0.05, 0.95]); + assertRangeDomain('yaxis', [-0.5, 1.5], [0, 1], [0, 1]); - return Plotly.relayout(gd, {'yaxis.constraintoward': 'middle'}); - }) - .then(function() { - assertRangeDomain('yaxis', [-0.5, 1.5], [0, 1], [0.25, 0.75]); + return Plotly.relayout(gd, { + 'xaxis.domain': null, + 'xaxis.range[0]': -6.5 + }); + }) + .then(function () { + assertRangeDomain('xaxis', [-6.5, 1.5], [0, 1], [0, 1]); + assertRangeDomain('yaxis', [-0.5, 1.5], [0, 1], [0, 0.5]); - return Plotly.relayout(gd, {'yaxis.constraintoward': 'top'}); - }) - .then(function() { - assertRangeDomain('yaxis', [-0.5, 1.5], [0, 1], [0.5, 1]); + return Plotly.relayout(gd, { 'yaxis.constraintoward': 'middle' }); + }) + .then(function () { + assertRangeDomain('yaxis', [-0.5, 1.5], [0, 1], [0.25, 0.75]); - return Plotly.relayout(gd, {'yaxis.constrain': 'range'}); - }) - .then(function() { - assertRangeDomain('xaxis', [-6.5, 1.5], [0, 1], [0, 1]); - assertRangeDomain('yaxis', [-2.5, 1.5], [0, 1], [0, 1]); + return Plotly.relayout(gd, { 'yaxis.constraintoward': 'top' }); + }) + .then(function () { + assertRangeDomain('yaxis', [-0.5, 1.5], [0, 1], [0.5, 1]); - return Plotly.relayout(gd, { - 'xaxis.autorange': true, - 'xaxis.constrain': 'domain', - 'xaxis.constraintoward': 'left', - 'yaxis.autorange': true, - 'yaxis.constrain': 'domain' - }); - }) - .then(function() { - assertRangeDomain('xaxis', [-0.5, 1.5], [0, 1], [0, 0.5]); - assertRangeDomain('yaxis', [-0.5, 1.5], [0, 1], [0, 1]); + return Plotly.relayout(gd, { 'yaxis.constrain': 'range' }); + }) + .then(function () { + assertRangeDomain('xaxis', [-6.5, 1.5], [0, 1], [0, 1]); + assertRangeDomain('yaxis', [-2.5, 1.5], [0, 1], [0, 1]); + + return Plotly.relayout(gd, { + 'xaxis.autorange': true, + 'xaxis.constrain': 'domain', + 'xaxis.constraintoward': 'left', + 'yaxis.autorange': true, + 'yaxis.constrain': 'domain' + }); + }) + .then(function () { + assertRangeDomain('xaxis', [-0.5, 1.5], [0, 1], [0, 0.5]); + assertRangeDomain('yaxis', [-0.5, 1.5], [0, 1], [0, 1]); - return Plotly.relayout(gd, {'xaxis.range': [-3.5, 4.5]}); - }) - .then(function() { - assertRangeDomain('xaxis', [-3.5, 4.5], [0, 1], [0, 1]); - assertRangeDomain('yaxis', [-0.5, 1.5], [0, 1], [0.5, 1]); + return Plotly.relayout(gd, { 'xaxis.range': [-3.5, 4.5] }); + }) + .then(function () { + assertRangeDomain('xaxis', [-3.5, 4.5], [0, 1], [0, 1]); + assertRangeDomain('yaxis', [-0.5, 1.5], [0, 1], [0.5, 1]); - return Plotly.relayout(gd, {'xaxis.range': [0, 1]}); - }) - .then(function() { - assertRangeDomain('xaxis', [0, 1], [0, 1], [0, 0.25]); - assertRangeDomain('yaxis', [-0.5, 1.5], [0, 1], [0, 1]); - }) - .then(done, done.fail); + return Plotly.relayout(gd, { 'xaxis.range': [0, 1] }); + }) + .then(function () { + assertRangeDomain('xaxis', [0, 1], [0, 1], [0, 0.25]); + assertRangeDomain('yaxis', [-0.5, 1.5], [0, 1], [0, 1]); + }) + .then(done, done.fail); }); - it('autoranges consistently with padding', function(done) { + it('autoranges consistently with padding', function (done) { var xAutoPad = 0.09523809523809526; var xAutorange = [-xAutoPad, 1 + xAutoPad]; var yAutoPad = 0.15476190476190477; var yAutorange = [-yAutoPad, 1 + yAutoPad]; Plotly.newPlot(gd, [ - {y: [0, 1], mode: 'markers', marker: {size: 4}}, - {y: [0, 1], mode: 'markers', marker: {size: 4}, xaxis: 'x2', yaxis: 'y2'} + { y: [0, 1], mode: 'markers', marker: { size: 4 } }, + { y: [0, 1], mode: 'markers', marker: { size: 4 }, xaxis: 'x2', yaxis: 'y2' } ], { - xaxis: {domain: [0, 0.5], constrain: 'domain'}, - yaxis: {constrain: 'domain', scaleanchor: 'x'}, - xaxis2: {domain: [0.5, 1], constrain: 'domain'}, - yaxis2: {constrain: 'domain', scaleanchor: 'x2'}, + xaxis: { domain: [0, 0.5], constrain: 'domain' }, + yaxis: { constrain: 'domain', scaleanchor: 'x' }, + xaxis2: { domain: [0.5, 1], constrain: 'domain' }, + yaxis2: { constrain: 'domain', scaleanchor: 'x2' }, // plot area 200x200px, so y axes should be squished to // (a little over due to autoranging) half their input domain width: 400, height: 400, - margin: {l: 100, r: 100, t: 100, b: 100, p: 0}, + margin: { l: 100, r: 100, t: 100, b: 100, p: 0 }, showlegend: false }) - .then(function() { - assertRangeDomain('xaxis', xAutorange, [0, 0.5], [0, 0.5]); - assertRangeDomain('yaxis', yAutorange, [0, 1], [0.225, 0.775]); - assertRangeDomain('xaxis2', xAutorange, [0.5, 1], [0.5, 1]); - assertRangeDomain('yaxis2', yAutorange, [0, 1], [0.225, 0.775]); + .then(function () { + assertRangeDomain('xaxis', xAutorange, [0, 0.5], [0, 0.5]); + assertRangeDomain('yaxis', yAutorange, [0, 1], [0.225, 0.775]); + assertRangeDomain('xaxis2', xAutorange, [0.5, 1], [0.5, 1]); + assertRangeDomain('yaxis2', yAutorange, [0, 1], [0.225, 0.775]); - return Plotly.relayout(gd, {'xaxis.range': [-1, 2]}); - }) - .then(function() { - assertRangeDomain('xaxis', [-1, 2], [0, 0.5], [0, 0.5]); - assertRangeDomain('yaxis', [-0.39, 1.39], [0, 1], [0.3516667, 0.6483333]); - assertRangeDomain('xaxis2', xAutorange, [0.5, 1], [0.5, 1]); - assertRangeDomain('yaxis2', yAutorange, [0, 1], [0.225, 0.775]); + return Plotly.relayout(gd, { 'xaxis.range': [-1, 2] }); + }) + .then(function () { + assertRangeDomain('xaxis', [-1, 2], [0, 0.5], [0, 0.5]); + assertRangeDomain('yaxis', [-0.39, 1.39], [0, 1], [0.3516667, 0.6483333]); + assertRangeDomain('xaxis2', xAutorange, [0.5, 1], [0.5, 1]); + assertRangeDomain('yaxis2', yAutorange, [0, 1], [0.225, 0.775]); - return Plotly.relayout(gd, {'xaxis.autorange': true}); - }) - .then(function() { - assertRangeDomain('xaxis', xAutorange, [0, 0.5], [0, 0.5]); - assertRangeDomain('yaxis', yAutorange, [0, 1], [0.225, 0.775]); - assertRangeDomain('xaxis2', xAutorange, [0.5, 1], [0.5, 1]); - assertRangeDomain('yaxis2', yAutorange, [0, 1], [0.225, 0.775]); - }) - .then(done, done.fail); + return Plotly.relayout(gd, { 'xaxis.autorange': true }); + }) + .then(function () { + assertRangeDomain('xaxis', xAutorange, [0, 0.5], [0, 0.5]); + assertRangeDomain('yaxis', yAutorange, [0, 1], [0.225, 0.775]); + assertRangeDomain('xaxis2', xAutorange, [0.5, 1], [0.5, 1]); + assertRangeDomain('yaxis2', yAutorange, [0, 1], [0.225, 0.775]); + }) + .then(done, done.fail); }); - it('can constrain date axes', function(done) { + it('can constrain date axes', function (done) { Plotly.newPlot(gd, [{ x: ['2001-01-01', '2002-01-01'], y: ['2001-01-01', '2002-01-01'], mode: 'markers', - marker: {size: 4} + marker: { size: 4 } }], { - yaxis: {scaleanchor: 'x'}, + yaxis: { scaleanchor: 'x' }, width: 400, height: 300, - margin: {l: 100, r: 100, t: 100, b: 100, p: 0} + margin: { l: 100, r: 100, t: 100, b: 100, p: 0 } }) - .then(function() { - assertRangeDomain('xaxis', ['2000-04-23 23:25:42.8572', '2002-09-10 00:34:17.1428'], [0, 1], [0, 1]); - assertRangeDomain('yaxis', ['2000-11-27 05:42:51.4286', '2002-02-04 18:17:08.5714'], [0, 1], [0, 1]); + .then(function () { + assertRangeDomain('xaxis', ['2000-04-23 23:25:42.8572', '2002-09-10 00:34:17.1428'], [0, 1], [0, 1]); + assertRangeDomain('yaxis', ['2000-11-27 05:42:51.4286', '2002-02-04 18:17:08.5714'], [0, 1], [0, 1]); - return Plotly.relayout(gd, { - 'xaxis.constrain': 'domain', - 'yaxis.constrain': 'domain' - }); - }) - .then(function() { - // you'd have thought the x axis would end up exactly the same total size as y - // (which would be domain [.25, .75]) but it doesn't, because the padding is - // calculated as 5% of the original axis size, not of the constrained size. - assertRangeDomain('xaxis', ['2000-11-05 12:17:08.5714', '2002-02-26 11:42:51.4286'], [0, 1], [0.225, 0.775]); - assertRangeDomain('yaxis', ['2000-11-27 05:42:51.4286', '2002-02-04 18:17:08.5714'], [0, 1], [0, 1]); - }) - .then(done, done.fail); + return Plotly.relayout(gd, { + 'xaxis.constrain': 'domain', + 'yaxis.constrain': 'domain' + }); + }) + .then(function () { + // you'd have thought the x axis would end up exactly the same total size as y + // (which would be domain [.25, .75]) but it doesn't, because the padding is + // calculated as 5% of the original axis size, not of the constrained size. + assertRangeDomain('xaxis', ['2000-11-05 12:17:08.5714', '2002-02-26 11:42:51.4286'], [0, 1], [0.225, 0.775]); + assertRangeDomain('yaxis', ['2000-11-27 05:42:51.4286', '2002-02-04 18:17:08.5714'], [0, 1], [0, 1]); + }) + .then(done, done.fail); }); - it('can constrain category axes', function(done) { + it('can constrain category axes', function (done) { Plotly.newPlot(gd, [{ x: ['a', 'b'], y: ['c', 'd'], mode: 'markers', - marker: {size: 4} + marker: { size: 4 } }], { - yaxis: {scaleanchor: 'x'}, + yaxis: { scaleanchor: 'x' }, width: 300, height: 400, - margin: {l: 100, r: 100, t: 100, b: 100, p: 0} + margin: { l: 100, r: 100, t: 100, b: 100, p: 0 } }) - .then(function() { - assertRangeDomain('xaxis', [-0.095238095, 1.095238095], [0, 1], [0, 1]); - assertRangeDomain('yaxis', [-0.69047619, 1.69047619], [0, 1], [0, 1]); + .then(function () { + assertRangeDomain('xaxis', [-0.095238095, 1.095238095], [0, 1], [0, 1]); + assertRangeDomain('yaxis', [-0.69047619, 1.69047619], [0, 1], [0, 1]); - return Plotly.relayout(gd, { - 'xaxis.constrain': 'domain', - 'yaxis.constrain': 'domain' - }); - }) - .then(function() { - assertRangeDomain('xaxis', [-0.095238095, 1.095238095], [0, 1], [0, 1]); - assertRangeDomain('yaxis', [-0.1547619, 1.1547619], [0, 1], [0.225, 0.775]); - }) - .then(done, done.fail); + return Plotly.relayout(gd, { + 'xaxis.constrain': 'domain', + 'yaxis.constrain': 'domain' + }); + }) + .then(function () { + assertRangeDomain('xaxis', [-0.095238095, 1.095238095], [0, 1], [0, 1]); + assertRangeDomain('yaxis', [-0.1547619, 1.1547619], [0, 1], [0.225, 0.775]); + }) + .then(done, done.fail); }); - it('can constrain log axes', function(done) { + it('can constrain log axes', function (done) { Plotly.newPlot(gd, [{ x: [1, 10], y: [1, 10], mode: 'markers', - marker: {size: 4} + marker: { size: 4 } }], { - xaxis: {type: 'log'}, - yaxis: {type: 'log', scaleanchor: 'x'}, + xaxis: { type: 'log' }, + yaxis: { type: 'log', scaleanchor: 'x' }, width: 300, height: 400, - margin: {l: 100, r: 100, t: 100, b: 100, p: 0} + margin: { l: 100, r: 100, t: 100, b: 100, p: 0 } }) - .then(function() { - assertRangeDomain('xaxis', [-0.095238095, 1.095238095], [0, 1], [0, 1]); - assertRangeDomain('yaxis', [-0.69047619, 1.69047619], [0, 1], [0, 1]); + .then(function () { + assertRangeDomain('xaxis', [-0.095238095, 1.095238095], [0, 1], [0, 1]); + assertRangeDomain('yaxis', [-0.69047619, 1.69047619], [0, 1], [0, 1]); - return Plotly.relayout(gd, { - 'xaxis.constrain': 'domain', - 'yaxis.constrain': 'domain' - }); - }) - .then(function() { - assertRangeDomain('xaxis', [-0.095238095, 1.095238095], [0, 1], [0, 1]); - assertRangeDomain('yaxis', [-0.1547619, 1.1547619], [0, 1], [0.225, 0.775]); - }) - .then(done, done.fail); + return Plotly.relayout(gd, { + 'xaxis.constrain': 'domain', + 'yaxis.constrain': 'domain' + }); + }) + .then(function () { + assertRangeDomain('xaxis', [-0.095238095, 1.095238095], [0, 1], [0, 1]); + assertRangeDomain('yaxis', [-0.1547619, 1.1547619], [0, 1], [0.225, 0.775]); + }) + .then(done, done.fail); }); - it('can react from different layout *grid* settings', function(done) { - var fig1 = function() { + it('can react from different layout *grid* settings', function (done) { + var fig1 = function () { return { - data: [{}, {xaxis: 'x2'}, {xaxis: 'x3'}, {xaxis: 'x4'}], + data: [{}, { xaxis: 'x2' }, { xaxis: 'x3' }, { xaxis: 'x4' }], layout: { grid: { xaxes: ['x', 'x2', 'x3', 'x4'], @@ -2125,16 +2130,16 @@ describe('Test axes', function() { xside: 'bottom', yside: 'left' }, - xaxis2: {scaleanchor: 'x'}, - xaxis3: {scaleanchor: 'x'}, - xaxis4: {scaleanchor: 'x'} + xaxis2: { scaleanchor: 'x' }, + xaxis3: { scaleanchor: 'x' }, + xaxis4: { scaleanchor: 'x' } } }; }; - var fig2 = function() { + var fig2 = function () { return { - data: [{}, {xaxis: 'x2'}, {xaxis: 'x3'}, {xaxis: 'x4'}], + data: [{}, { xaxis: 'x2' }, { xaxis: 'x3' }, { xaxis: 'x4' }], layout: { grid: { xaxes: ['x', 'x2'], @@ -2144,7 +2149,7 @@ describe('Test axes', function() { xside: 'bottom', yside: 'left' }, - xaxis2: {scaleanchor: 'x'} + xaxis2: { scaleanchor: 'x' } } }; }; @@ -2152,45 +2157,45 @@ describe('Test axes', function() { var rng = [-1, 6]; Plotly.newPlot(gd, fig1()) - .then(function() { - var msg = 'fig1'; - assertRangeDomain('xaxis', rng, [0, 0.230769], [0, 0.230769], msg); - assertRangeDomain('xaxis2', rng, [0.256410, 0.487179], [0.256410, 0.487179], msg); - assertRangeDomain('xaxis3', rng, [0.512820, 0.743589], [0.512820, 0.743589], msg); - }) - .then(function() { return Plotly.react(gd, fig2()); }) - .then(function() { - var msg = 'fig2'; - assertRangeDomain('xaxis', rng, [0, 0.473684], [0, 0.473684], msg); - assertRangeDomain('xaxis2', rng, [0.526315, 1], [0.526315, 1], msg); - }) - .then(function() { return Plotly.react(gd, fig1()); }) - .then(function() { - var msg = 'back to fig1'; - assertRangeDomain('xaxis', rng, [0, 0.230769], [0, 0.230769], msg); - assertRangeDomain('xaxis2', rng, [0.256410, 0.487179], [0.256410, 0.487179], msg); - assertRangeDomain('xaxis3', rng, [0.512820, 0.743589], [0.512820, 0.743589], msg); - }) - .then(done, done.fail); + .then(function () { + var msg = 'fig1'; + assertRangeDomain('xaxis', rng, [0, 0.230769], [0, 0.230769], msg); + assertRangeDomain('xaxis2', rng, [0.256410, 0.487179], [0.256410, 0.487179], msg); + assertRangeDomain('xaxis3', rng, [0.512820, 0.743589], [0.512820, 0.743589], msg); + }) + .then(function () { return Plotly.react(gd, fig2()); }) + .then(function () { + var msg = 'fig2'; + assertRangeDomain('xaxis', rng, [0, 0.473684], [0, 0.473684], msg); + assertRangeDomain('xaxis2', rng, [0.526315, 1], [0.526315, 1], msg); + }) + .then(function () { return Plotly.react(gd, fig1()); }) + .then(function () { + var msg = 'back to fig1'; + assertRangeDomain('xaxis', rng, [0, 0.230769], [0, 0.230769], msg); + assertRangeDomain('xaxis2', rng, [0.256410, 0.487179], [0.256410, 0.487179], msg); + assertRangeDomain('xaxis3', rng, [0.512820, 0.743589], [0.512820, 0.743589], msg); + }) + .then(done, done.fail); }); }); - describe('matching axes relayout calls', function() { + describe('matching axes relayout calls', function () { var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); afterEach(destroyGraphDiv); function assertRanges(msg, exp) { - exp.forEach(function(expi) { + exp.forEach(function (expi) { var axNames = expi[0]; var rng = expi[1]; var autorng = expi[2]; - axNames.forEach(function(n) { + axNames.forEach(function (n) { var msgi = n + ' - ' + msg; expect(gd._fullLayout[n].range).toBeCloseToArray(rng, 1.5, msgi + ' |range'); expect(gd._fullLayout[n].autorange).toBe(autorng, msgi + ' |autorange'); @@ -2198,243 +2203,243 @@ describe('Test axes', function() { }); } - it('should auto-range according to all matching trace data', function(done) { + it('should auto-range according to all matching trace data', function (done) { Plotly.newPlot(gd, [ { y: [1, 2, 1] }, { y: [2, 1, 2, 3], xaxis: 'x2' }, { y: [0, 1], xaxis: 'x3' } ], { - xaxis: {domain: [0, 0.2]}, - xaxis2: {matches: 'x', domain: [0.3, 0.6]}, - xaxis3: {matches: 'x', domain: [0.65, 1]}, + xaxis: { domain: [0, 0.2] }, + xaxis2: { matches: 'x', domain: [0.3, 0.6] }, + xaxis3: { matches: 'x', domain: [0.65, 1] }, width: 800, height: 500, }) - .then(function() { - assertRanges('base (autoranged)', [ - [['xaxis', 'xaxis2', 'xaxis3'], [-0.285, 3.245], true], - [['yaxis'], [-0.211, 3.211], true] - ]); - }) - .then(function() { return Plotly.relayout(gd, 'xaxis.range', [-1, 4]); }) - .then(function() { - assertRanges('set range', [ - [['xaxis', 'xaxis2', 'xaxis3'], [-1, 4], false], - [['yaxis'], [-0.211, 3.211], true] - ]); - }) - .then(function() { return Plotly.relayout(gd, 'xaxis2.autorange', true); }) - .then(function() { - assertRanges('back to autorange', [ - [['xaxis', 'xaxis2', 'xaxis3'], [-0.285, 3.245], true], - [['yaxis'], [-0.211, 3.211], true] - ]); - }) - .then(done, done.fail); + .then(function () { + assertRanges('base (autoranged)', [ + [['xaxis', 'xaxis2', 'xaxis3'], [-0.285, 3.245], true], + [['yaxis'], [-0.211, 3.211], true] + ]); + }) + .then(function () { return Plotly.relayout(gd, 'xaxis.range', [-1, 4]); }) + .then(function () { + assertRanges('set range', [ + [['xaxis', 'xaxis2', 'xaxis3'], [-1, 4], false], + [['yaxis'], [-0.211, 3.211], true] + ]); + }) + .then(function () { return Plotly.relayout(gd, 'xaxis2.autorange', true); }) + .then(function () { + assertRanges('back to autorange', [ + [['xaxis', 'xaxis2', 'xaxis3'], [-0.285, 3.245], true], + [['yaxis'], [-0.211, 3.211], true] + ]); + }) + .then(done, done.fail); }); }); - describe('categoryorder', function() { + describe('categoryorder', function () { var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); afterEach(destroyGraphDiv); - describe('setting, or not setting categoryorder if it is not explicitly declared', function() { - it('should set categoryorder to default if categoryorder and categoryarray are not supplied', function(done) { - Plotly.newPlot(gd, [{x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14]}], {xaxis: {type: 'category'}}) - .then(function() { - expect(gd._fullLayout.xaxis.categoryorder).toBe('trace'); - expect(gd._fullLayout.xaxis.categorarray).toBe(undefined); - }) - .then(done, done.fail); + describe('setting, or not setting categoryorder if it is not explicitly declared', function () { + it('should set categoryorder to default if categoryorder and categoryarray are not supplied', function (done) { + Plotly.newPlot(gd, [{ x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14] }], { xaxis: { type: 'category' } }) + .then(function () { + expect(gd._fullLayout.xaxis.categoryorder).toBe('trace'); + expect(gd._fullLayout.xaxis.categorarray).toBe(undefined); + }) + .then(done, done.fail); }); - it('should set categoryorder to default even if type is not set to category explicitly', function(done) { - Plotly.newPlot(gd, [{x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14]}]) - .then(function() { - expect(gd._fullLayout.xaxis.categoryorder).toBe('trace'); - expect(gd._fullLayout.xaxis.categorarray).toBe(undefined); - }) - .then(done, done.fail); + it('should set categoryorder to default even if type is not set to category explicitly', function (done) { + Plotly.newPlot(gd, [{ x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14] }]) + .then(function () { + expect(gd._fullLayout.xaxis.categoryorder).toBe('trace'); + expect(gd._fullLayout.xaxis.categorarray).toBe(undefined); + }) + .then(done, done.fail); }); - it('should NOT set categoryorder to default if type is not category', function(done) { - Plotly.newPlot(gd, [{x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14]}]) - .then(function() { - expect(gd._fullLayout.yaxis.categoryorder).toBe(undefined); - expect(gd._fullLayout.xaxis.categorarray).toBe(undefined); - }) - .then(done, done.fail); + it('should NOT set categoryorder to default if type is not category', function (done) { + Plotly.newPlot(gd, [{ x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14] }]) + .then(function () { + expect(gd._fullLayout.yaxis.categoryorder).toBe(undefined); + expect(gd._fullLayout.xaxis.categorarray).toBe(undefined); + }) + .then(done, done.fail); }); - it('should set categoryorder to default if type is overridden to be category', function(done) { - Plotly.newPlot(gd, [{x: [1, 2, 3, 4, 5], y: [15, 11, 12, 13, 14]}], {yaxis: {type: 'category'}}) - .then(function() { - expect(gd._fullLayout.xaxis.categoryorder).toBe(undefined); - expect(gd._fullLayout.yaxis.categorarray).toBe(undefined); - expect(gd._fullLayout.yaxis.categoryorder).toBe('trace'); - expect(gd._fullLayout.yaxis.categorarray).toBe(undefined); - }) - .then(done, done.fail); + it('should set categoryorder to default if type is overridden to be category', function (done) { + Plotly.newPlot(gd, [{ x: [1, 2, 3, 4, 5], y: [15, 11, 12, 13, 14] }], { yaxis: { type: 'category' } }) + .then(function () { + expect(gd._fullLayout.xaxis.categoryorder).toBe(undefined); + expect(gd._fullLayout.yaxis.categorarray).toBe(undefined); + expect(gd._fullLayout.yaxis.categoryorder).toBe('trace'); + expect(gd._fullLayout.yaxis.categorarray).toBe(undefined); + }) + .then(done, done.fail); }); }); - describe('setting categoryorder to "array"', function() { - it('should leave categoryorder on "array" if it is supplied', function(done) { - Plotly.newPlot(gd, [{x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14]}], { - xaxis: {type: 'category', categoryorder: 'array', categoryarray: ['b', 'a', 'd', 'e', 'c']} - }) - .then(function() { - expect(gd._fullLayout.xaxis.categoryorder).toBe('array'); - expect(gd._fullLayout.xaxis.categoryarray).toEqual(['b', 'a', 'd', 'e', 'c']); + describe('setting categoryorder to "array"', function () { + it('should leave categoryorder on "array" if it is supplied', function (done) { + Plotly.newPlot(gd, [{ x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14] }], { + xaxis: { type: 'category', categoryorder: 'array', categoryarray: ['b', 'a', 'd', 'e', 'c'] } }) - .then(done, done.fail); + .then(function () { + expect(gd._fullLayout.xaxis.categoryorder).toBe('array'); + expect(gd._fullLayout.xaxis.categoryarray).toEqual(['b', 'a', 'd', 'e', 'c']); + }) + .then(done, done.fail); }); - it('should switch categoryorder on "array" if it is not supplied but categoryarray is supplied', function(done) { - Plotly.newPlot(gd, [{x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14]}], { - xaxis: {type: 'category', categoryarray: ['b', 'a', 'd', 'e', 'c']} - }) - .then(function() { - expect(gd._fullLayout.xaxis.categoryorder).toBe('array'); - expect(gd._fullLayout.xaxis.categoryarray).toEqual(['b', 'a', 'd', 'e', 'c']); + it('should switch categoryorder on "array" if it is not supplied but categoryarray is supplied', function (done) { + Plotly.newPlot(gd, [{ x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14] }], { + xaxis: { type: 'category', categoryarray: ['b', 'a', 'd', 'e', 'c'] } }) - .then(done, done.fail); + .then(function () { + expect(gd._fullLayout.xaxis.categoryorder).toBe('array'); + expect(gd._fullLayout.xaxis.categoryarray).toEqual(['b', 'a', 'd', 'e', 'c']); + }) + .then(done, done.fail); }); - it('should revert categoryorder to "trace" if "array" is supplied but there is no list', function(done) { - Plotly.newPlot(gd, [{x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14]}], { - xaxis: {type: 'category', categoryorder: 'array'} - }) - .then(function() { - expect(gd._fullLayout.xaxis.categoryorder).toBe('trace'); - expect(gd._fullLayout.xaxis.categorarray).toBe(undefined); + it('should revert categoryorder to "trace" if "array" is supplied but there is no list', function (done) { + Plotly.newPlot(gd, [{ x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14] }], { + xaxis: { type: 'category', categoryorder: 'array' } }) - .then(done, done.fail); + .then(function () { + expect(gd._fullLayout.xaxis.categoryorder).toBe('trace'); + expect(gd._fullLayout.xaxis.categorarray).toBe(undefined); + }) + .then(done, done.fail); }); }); - describe('do not set categoryorder to "array" if list exists but empty', function() { - it('should switch categoryorder to default if list is not supplied', function(done) { - Plotly.newPlot(gd, [{x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14]}], { - xaxis: {type: 'category', categoryorder: 'array', categoryarray: []} - }) - .then(function() { - expect(gd._fullLayout.xaxis.categoryorder).toBe('trace'); - expect(gd._fullLayout.xaxis.categoryarray).toEqual([]); + describe('do not set categoryorder to "array" if list exists but empty', function () { + it('should switch categoryorder to default if list is not supplied', function (done) { + Plotly.newPlot(gd, [{ x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14] }], { + xaxis: { type: 'category', categoryorder: 'array', categoryarray: [] } }) - .then(done, done.fail); + .then(function () { + expect(gd._fullLayout.xaxis.categoryorder).toBe('trace'); + expect(gd._fullLayout.xaxis.categoryarray).toEqual([]); + }) + .then(done, done.fail); }); - it('should not switch categoryorder on "array" if categoryarray is supplied but empty', function(done) { - Plotly.newPlot(gd, [{x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14]}], { - xaxis: {type: 'category', categoryarray: []} - }) - .then(function() { - expect(gd._fullLayout.xaxis.categoryorder).toBe('trace'); - expect(gd._fullLayout.xaxis.categoryarray).toEqual(undefined); + it('should not switch categoryorder on "array" if categoryarray is supplied but empty', function (done) { + Plotly.newPlot(gd, [{ x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14] }], { + xaxis: { type: 'category', categoryarray: [] } }) - .then(done, done.fail); + .then(function () { + expect(gd._fullLayout.xaxis.categoryorder).toBe('trace'); + expect(gd._fullLayout.xaxis.categoryarray).toEqual(undefined); + }) + .then(done, done.fail); }); }); - describe('do NOT set categoryorder to "array" if it has some other proper value', function() { - it('should use specified categoryorder if it is supplied even if categoryarray exists', function(done) { - Plotly.newPlot(gd, [{x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14]}], { - xaxis: {type: 'category', categoryorder: 'trace', categoryarray: ['b', 'a', 'd', 'e', 'c']} - }) - .then(function() { - expect(gd._fullLayout.xaxis.categoryorder).toBe('trace'); - expect(gd._fullLayout.xaxis.categoryarray).toBe(undefined); + describe('do NOT set categoryorder to "array" if it has some other proper value', function () { + it('should use specified categoryorder if it is supplied even if categoryarray exists', function (done) { + Plotly.newPlot(gd, [{ x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14] }], { + xaxis: { type: 'category', categoryorder: 'trace', categoryarray: ['b', 'a', 'd', 'e', 'c'] } }) - .then(done, done.fail); + .then(function () { + expect(gd._fullLayout.xaxis.categoryorder).toBe('trace'); + expect(gd._fullLayout.xaxis.categoryarray).toBe(undefined); + }) + .then(done, done.fail); }); - it('should use specified categoryorder if it is supplied even if categoryarray exists', function(done) { - Plotly.newPlot(gd, [{x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14]}], { - xaxis: {type: 'category', categoryorder: 'category ascending', categoryarray: ['b', 'a', 'd', 'e', 'c']} - }) - .then(function() { - expect(gd._fullLayout.xaxis.categoryorder).toBe('category ascending'); - expect(gd._fullLayout.xaxis.categoryarray).toBe(undefined); + it('should use specified categoryorder if it is supplied even if categoryarray exists', function (done) { + Plotly.newPlot(gd, [{ x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14] }], { + xaxis: { type: 'category', categoryorder: 'category ascending', categoryarray: ['b', 'a', 'd', 'e', 'c'] } }) - .then(done, done.fail); + .then(function () { + expect(gd._fullLayout.xaxis.categoryorder).toBe('category ascending'); + expect(gd._fullLayout.xaxis.categoryarray).toBe(undefined); + }) + .then(done, done.fail); }); - it('should use specified categoryorder if it is supplied even if categoryarray exists', function(done) { - Plotly.newPlot(gd, [{x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14]}], { - xaxis: {type: 'category', categoryorder: 'category descending', categoryarray: ['b', 'a', 'd', 'e', 'c']} - }) - .then(function() { - expect(gd._fullLayout.xaxis.categoryorder).toBe('category descending'); - expect(gd._fullLayout.xaxis.categoryarray).toBe(undefined); + it('should use specified categoryorder if it is supplied even if categoryarray exists', function (done) { + Plotly.newPlot(gd, [{ x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14] }], { + xaxis: { type: 'category', categoryorder: 'category descending', categoryarray: ['b', 'a', 'd', 'e', 'c'] } }) - .then(done, done.fail); + .then(function () { + expect(gd._fullLayout.xaxis.categoryorder).toBe('category descending'); + expect(gd._fullLayout.xaxis.categoryarray).toBe(undefined); + }) + .then(done, done.fail); }); }); - describe('setting categoryorder to the default if the value is unexpected', function() { - it('should switch categoryorder to "trace" if mode is supplied but invalid', function(done) { - Plotly.newPlot(gd, [{x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14]}], { - xaxis: {type: 'category', categoryorder: 'invalid value'} - }) - .then(function() { - expect(gd._fullLayout.xaxis.categoryorder).toBe('trace'); - expect(gd._fullLayout.xaxis.categoryarray).toBe(undefined); + describe('setting categoryorder to the default if the value is unexpected', function () { + it('should switch categoryorder to "trace" if mode is supplied but invalid', function (done) { + Plotly.newPlot(gd, [{ x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14] }], { + xaxis: { type: 'category', categoryorder: 'invalid value' } }) - .then(done, done.fail); + .then(function () { + expect(gd._fullLayout.xaxis.categoryorder).toBe('trace'); + expect(gd._fullLayout.xaxis.categoryarray).toBe(undefined); + }) + .then(done, done.fail); }); - it('should switch categoryorder to "array" if mode is supplied but invalid and list is supplied', function(done) { - Plotly.newPlot(gd, [{x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14]}], { - xaxis: {type: 'category', categoryorder: 'invalid value', categoryarray: ['b', 'a', 'd', 'e', 'c']} - }) - .then(function() { - expect(gd._fullLayout.xaxis.categoryorder).toBe('array'); - expect(gd._fullLayout.xaxis.categoryarray).toEqual(['b', 'a', 'd', 'e', 'c']); + it('should switch categoryorder to "array" if mode is supplied but invalid and list is supplied', function (done) { + Plotly.newPlot(gd, [{ x: ['c', 'a', 'e', 'b', 'd'], y: [15, 11, 12, 13, 14] }], { + xaxis: { type: 'category', categoryorder: 'invalid value', categoryarray: ['b', 'a', 'd', 'e', 'c'] } }) - .then(done, done.fail); + .then(function () { + expect(gd._fullLayout.xaxis.categoryorder).toBe('array'); + expect(gd._fullLayout.xaxis.categoryarray).toEqual(['b', 'a', 'd', 'e', 'c']); + }) + .then(done, done.fail); }); }); }); - describe('bar category autorange', function() { + describe('bar category autorange', function () { var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); afterEach(destroyGraphDiv); - describe('a category has the same value of one of the auto range computed extreme', function() { - it('should compute the right range for X axis', function(done) { - Plotly.newPlot(gd, [{x: ['0', '-0.5', '3.5', 'Not Known'], y: [ '1.0', '1.0', '2.0', '1.0'], type: 'bar'}], { - xaxis: {type: 'category', autorange: true} - }) - .then(function() { - expect(gd._fullLayout.xaxis._rl).toEqual([-0.5, 3.5]); + describe('a category has the same value of one of the auto range computed extreme', function () { + it('should compute the right range for X axis', function (done) { + Plotly.newPlot(gd, [{ x: ['0', '-0.5', '3.5', 'Not Known'], y: ['1.0', '1.0', '2.0', '1.0'], type: 'bar' }], { + xaxis: { type: 'category', autorange: true } }) - .then(done, done.fail); + .then(function () { + expect(gd._fullLayout.xaxis._rl).toEqual([-0.5, 3.5]); + }) + .then(done, done.fail); }); }); }); - describe('handleTickDefaults', function() { + describe('handleTickDefaults', function () { var data = [{ x: [1, 2, 3], y: [3, 4, 5] }]; var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); afterEach(destroyGraphDiv); - it('should set defaults on bad inputs', function(done) { + it('should set defaults on bad inputs', function (done) { var layout = { yaxis: { ticklen: 'invalid', @@ -2447,30 +2452,30 @@ describe('Test axes', function() { }; Plotly.newPlot(gd, data, layout) - .then(function() { - var yaxis = gd._fullLayout.yaxis; - expect(yaxis.ticklen).toBe(5); - expect(yaxis.tickwidth).toBe(1); - expect(yaxis.tickcolor).toBe('#444'); - expect(yaxis.ticks).toBe('outside'); - expect(yaxis.showticklabels).toBe(true); - expect(yaxis.tickfont).toEqual({ - family: '"Open Sans", verdana, arial, sans-serif', - size: 12, - color: '#444', - weight: 'normal', - style: 'normal', - variant: 'normal', - textcase: 'normal', - lineposition: 'none', - shadow: 'none', - }); - expect(yaxis.tickangle).toBe('auto'); - }) - .then(done, done.fail); + .then(function () { + var yaxis = gd._fullLayout.yaxis; + expect(yaxis.ticklen).toBe(5); + expect(yaxis.tickwidth).toBe(1); + expect(yaxis.tickcolor).toBe('#444'); + expect(yaxis.ticks).toBe('outside'); + expect(yaxis.showticklabels).toBe(true); + expect(yaxis.tickfont).toEqual({ + family: '"Open Sans", verdana, arial, sans-serif', + size: 12, + color: '#444', + weight: 'normal', + style: 'normal', + variant: 'normal', + textcase: 'normal', + lineposition: 'none', + shadow: 'none', + }); + expect(yaxis.tickangle).toBe('auto'); + }) + .then(done, done.fail); }); - it('should use valid inputs', function(done) { + it('should use valid inputs', function (done) { var layout = { yaxis: { ticklen: 10, @@ -2493,30 +2498,30 @@ describe('Test axes', function() { }; Plotly.newPlot(gd, data, layout) - .then(function() { - var yaxis = gd._fullLayout.yaxis; - expect(yaxis.ticklen).toBe(10); - expect(yaxis.tickwidth).toBe(5); - expect(yaxis.tickcolor).toBe('#F00'); - expect(yaxis.ticks).toBe('outside'); - expect(yaxis.showticklabels).toBe(true); - expect(yaxis.tickfont).toEqual({ - family: 'Garamond', - size: 72, - color: '#0FF', - weight: 'normal', - style: 'normal', - variant: 'normal', - textcase: 'normal', - lineposition: 'none', - shadow: 'none', - }); - expect(yaxis.tickangle).toBe(-20); - }) - .then(done, done.fail); + .then(function () { + var yaxis = gd._fullLayout.yaxis; + expect(yaxis.ticklen).toBe(10); + expect(yaxis.tickwidth).toBe(5); + expect(yaxis.tickcolor).toBe('#F00'); + expect(yaxis.ticks).toBe('outside'); + expect(yaxis.showticklabels).toBe(true); + expect(yaxis.tickfont).toEqual({ + family: 'Garamond', + size: 72, + color: '#0FF', + weight: 'normal', + style: 'normal', + variant: 'normal', + textcase: 'normal', + lineposition: 'none', + shadow: 'none', + }); + expect(yaxis.tickangle).toBe(-20); + }) + .then(done, done.fail); }); - it('should conditionally coerce based on showticklabels', function(done) { + it('should conditionally coerce based on showticklabels', function (done) { var layout = { yaxis: { showticklabels: false, @@ -2525,19 +2530,19 @@ describe('Test axes', function() { }; Plotly.newPlot(gd, data, layout) - .then(function() { - var yaxis = gd._fullLayout.yaxis; - expect(yaxis.tickangle).toBeUndefined(); - }) - .then(done, done.fail); + .then(function () { + var yaxis = gd._fullLayout.yaxis; + expect(yaxis.tickangle).toBeUndefined(); + }) + .then(done, done.fail); }); }); - describe('handleTickValueDefaults', function() { + describe('handleTickValueDefaults', function () { var viaTemplate; function mockSupplyDefaults(axIn, axOut, axType) { - if(viaTemplate) { + if (viaTemplate) { axOut._template = axIn; axIn = {}; } @@ -2552,10 +2557,10 @@ describe('Test axes', function() { [ '(without template) ', '(with template) ' - ].forEach(function(woTemplate, index) { + ].forEach(function (woTemplate, index) { viaTemplate = index === 1; - it(woTemplate + 'should set default tickmode correctly', function() { + it(woTemplate + 'should set default tickmode correctly', function () { var axIn = {}; var axOut = {}; mockSupplyDefaults(axIn, axOut, 'linear'); @@ -2563,25 +2568,25 @@ describe('Test axes', function() { // and not push it back to axIn (which we used to do) expect(axIn.tickmode).toBeUndefined(); - axIn = {tickmode: 'array', tickvals: 'stuff'}; + axIn = { tickmode: 'array', tickvals: 'stuff' }; axOut = {}; mockSupplyDefaults(axIn, axOut, 'linear'); expect(axOut.tickmode).toBe('auto'); expect(axIn.tickmode).toBe('array'); - axIn = {tickvals: [1, 2, 3]}; + axIn = { tickvals: [1, 2, 3] }; axOut = {}; mockSupplyDefaults(axIn, axOut, 'date'); expect(axOut.tickmode).toBe('array'); expect(axIn.tickmode).toBeUndefined(); - axIn = {tickmode: 'array', tickvals: [1, 2, 3]}; + axIn = { tickmode: 'array', tickvals: [1, 2, 3] }; axOut = {}; mockSupplyDefaults(axIn, axOut, 'date'); expect(axOut.tickmode).toBe('array'); expect(axIn.tickmode).toBe('array'); - axIn = {tickvals: [1, 2, 3]}; + axIn = { tickvals: [1, 2, 3] }; axOut = {}; mockSupplyDefaults(axIn, axOut, 'linear'); expect(axOut.tickmode).toBe('array'); @@ -2590,88 +2595,88 @@ describe('Test axes', function() { var arr = new Float32Array(2); arr[0] = 0; arr[1] = 1; - axIn = {tickvals: arr}; + axIn = { tickvals: arr }; axOut = {}; mockSupplyDefaults(axIn, axOut, 'linear'); expect(axOut.tickmode).toBe('array'); expect(axIn.tickmode).toBeUndefined(); - axIn = {dtick: 1}; + axIn = { dtick: 1 }; axOut = {}; mockSupplyDefaults(axIn, axOut, 'linear'); expect(axOut.tickmode).toBe('linear'); expect(axIn.tickmode).toBeUndefined(); }); - it(woTemplate + 'should set nticks if tickmode=auto', function() { + it(woTemplate + 'should set nticks if tickmode=auto', function () { var axIn = {}; var axOut = {}; mockSupplyDefaults(axIn, axOut, 'linear'); expect(axOut.nticks).toBe(0); - axIn = {tickmode: 'auto', nticks: 5}; + axIn = { tickmode: 'auto', nticks: 5 }; axOut = {}; mockSupplyDefaults(axIn, axOut, 'linear'); expect(axOut.nticks).toBe(5); - axIn = {tickmode: 'linear', nticks: 15}; + axIn = { tickmode: 'linear', nticks: 15 }; axOut = {}; mockSupplyDefaults(axIn, axOut, 'linear'); expect(axOut.nticks).toBe(undefined); }); - it(woTemplate + 'should set tick0 and dtick if tickmode=linear', function() { - var axIn = {tickmode: 'auto', tick0: 1, dtick: 1}; + 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'); expect(axOut.tick0).toBe(undefined); expect(axOut.dtick).toBe(undefined); - axIn = {tickvals: [1, 2, 3], tick0: 1, dtick: 1}; + axIn = { tickvals: [1, 2, 3], tick0: 1, dtick: 1 }; axOut = {}; mockSupplyDefaults(axIn, axOut, 'linear'); expect(axOut.tick0).toBe(undefined); expect(axOut.dtick).toBe(undefined); - axIn = {tick0: 2.71, dtick: 0.00828}; + axIn = { tick0: 2.71, dtick: 0.00828 }; axOut = {}; mockSupplyDefaults(axIn, axOut, 'linear'); expect(axOut.tick0).toBe(2.71); expect(axOut.dtick).toBe(0.00828); - axIn = {tickmode: 'linear', tick0: 3.14, dtick: 0.00159}; + axIn = { tickmode: 'linear', tick0: 3.14, dtick: 0.00159 }; axOut = {}; mockSupplyDefaults(axIn, axOut, 'linear'); expect(axOut.tick0).toBe(3.14); expect(axOut.dtick).toBe(0.00159); }); - it(woTemplate + 'should handle tick0 and dtick for date axes', function() { + it(woTemplate + 'should handle tick0 and dtick for date axes', function () { var someMs = 123456789; var someMsDate = Lib.ms2DateTimeLocal(someMs); var oneDay = 24 * 3600 * 1000; - var axIn = {tick0: someMs, dtick: String(3 * oneDay)}; + var axIn = { tick0: someMs, dtick: String(3 * oneDay) }; var axOut = {}; mockSupplyDefaults(axIn, axOut, 'date'); expect(axOut.tick0).toBe(someMsDate); expect(axOut.dtick).toBe(3 * oneDay); var someDate = '2011-12-15 13:45:56'; - axIn = {tick0: someDate, dtick: 'M15'}; + axIn = { tick0: someDate, dtick: 'M15' }; axOut = {}; mockSupplyDefaults(axIn, axOut, 'date'); expect(axOut.tick0).toBe(someDate); expect(axOut.dtick).toBe('M15'); // dtick without tick0: get the right default - axIn = {dtick: 'M12'}; + axIn = { dtick: 'M12' }; axOut = {}; mockSupplyDefaults(axIn, axOut, 'date'); expect(axOut.tick0).toBe('2000-01-01'); expect(axOut.dtick).toBe('M12'); var errors = []; - spyOn(Loggers, 'error').and.callFake(function(msg) { + spyOn(Loggers, 'error').and.callFake(function (msg) { errors.push(msg); }); @@ -2682,8 +2687,8 @@ describe('Test axes', function() { ['', 'M0.5'], ['', 'M-1'], ['', '2000-01-01'] - ].forEach(function(v, i) { - axIn = {tick0: v[0], dtick: v[1]}; + ].forEach(function (v, i) { + axIn = { tick0: v[0], dtick: v[1] }; axOut = {}; mockSupplyDefaults(axIn, axOut, 'date'); expect(axOut.tick0).toBe('2000-01-01'); @@ -2692,15 +2697,15 @@ describe('Test axes', function() { }); }); - it(woTemplate + 'should handle tick0 and dtick for log axes', function() { - var axIn = {tick0: '0.2', dtick: 0.3}; + it(woTemplate + 'should handle tick0 and dtick for log axes', function () { + var axIn = { tick0: '0.2', dtick: 0.3 }; var axOut = {}; mockSupplyDefaults(axIn, axOut, 'log'); expect(axOut.tick0).toBe(0.2); expect(axOut.dtick).toBe(0.3); - ['D1', 'D2'].forEach(function(v) { - axIn = {tick0: -1, dtick: v}; + ['D1', 'D2'].forEach(function (v) { + axIn = { tick0: -1, dtick: v }; axOut = {}; mockSupplyDefaults(axIn, axOut, 'log'); // tick0 gets ignored for D @@ -2713,8 +2718,8 @@ describe('Test axes', function() { ['0.2', 'L0.3'], [-1, 3], ['0.1234', '0.69238473'] - ].forEach(function(v) { - axIn = {tick0: v[0], dtick: v[1]}; + ].forEach(function (v) { + axIn = { tick0: v[0], dtick: v[1] }; axOut = {}; mockSupplyDefaults(axIn, axOut, 'log'); expect(axOut.tick0).toBe(Number(v[0])); @@ -2728,8 +2733,8 @@ describe('Test axes', function() { ['', 'D0'], ['2011-01-01', 'L0'], ['', 'L-1'] - ].forEach(function(v) { - axIn = {tick0: v[0], dtick: v[1]}; + ].forEach(function (v) { + axIn = { tick0: v[0], dtick: v[1] }; axOut = {}; mockSupplyDefaults(axIn, axOut, 'log'); expect(axOut.tick0).toBe(0); @@ -2737,22 +2742,22 @@ describe('Test axes', function() { }); }); - it(woTemplate + 'should set tickvals and ticktext if tickmode=array', function() { - var axIn = {tickmode: 'auto', tickvals: [1, 2, 3], ticktext: ['4', '5', '6']}; + 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'); expect(axOut.tickvals).toBe(undefined); expect(axOut.ticktext).toBe(undefined); - axIn = {tickvals: [2, 4, 6, 8], ticktext: ['who', 'do', 'we', 'appreciate']}; + axIn = { tickvals: [2, 4, 6, 8], ticktext: ['who', 'do', 'we', 'appreciate'] }; axOut = {}; mockSupplyDefaults(axIn, axOut, 'linear'); expect(axOut.tickvals).toEqual([2, 4, 6, 8]); expect(axOut.ticktext).toEqual(['who', 'do', 'we', 'appreciate']); }); - it(woTemplate + 'should not coerce ticktext/tickvals on multicategory axes', function() { - var axIn = {tickvals: [1, 2, 3], ticktext: ['4', '5', '6']}; + it(woTemplate + 'should not coerce ticktext/tickvals on multicategory axes', function () { + var axIn = { tickvals: [1, 2, 3], ticktext: ['4', '5', '6'] }; var axOut = {}; mockSupplyDefaults(axIn, axOut, 'multicategory'); expect(axOut.tickvals).toBe(undefined); @@ -2761,24 +2766,24 @@ describe('Test axes', function() { }); }); - describe('saveRangeInitial', function() { + describe('saveRangeInitial', function () { var saveRangeInitial = Axes.saveRangeInitial; var gd, hasOneAxisChanged; - beforeEach(function() { + beforeEach(function () { gd = { _fullLayout: { xaxis: { range: [0, 0.5] }, yaxis: { range: [0, 0.5] }, xaxis2: { range: [0.5, 1] }, yaxis2: { range: [0.5, 1] }, - _subplots: {xaxis: ['x', 'x2'], yaxis: ['y', 'y2'], cartesian: ['xy', 'x2y2']} + _subplots: { xaxis: ['x', 'x2'], yaxis: ['y', 'y2'], cartesian: ['xy', 'x2y2'] } } }; }); - it('should save range when autosize turned off and rangeInitials are not defined', function() { - ['xaxis', 'yaxis', 'xaxis2', 'yaxis2'].forEach(function(ax) { + it('should save range when autosize turned off and rangeInitials are not defined', function () { + ['xaxis', 'yaxis', 'xaxis2', 'yaxis2'].forEach(function (ax) { gd._fullLayout[ax].autorange = false; }); @@ -2798,8 +2803,8 @@ describe('Test axes', function() { expect(gd._fullLayout.yaxis2._rangeInitial1).toEqual(1); }); - it('should not overwrite saved range if rangeInitials are defined', function() { - ['xaxis', 'yaxis', 'xaxis2', 'yaxis2'].forEach(function(ax) { + it('should not overwrite saved range if rangeInitials are defined', function () { + ['xaxis', 'yaxis', 'xaxis2', 'yaxis2'].forEach(function (ax) { gd._fullLayout[ax]._rangeInitial0 = gd._fullLayout[ax].range[0]; gd._fullLayout[ax]._rangeInitial1 = gd._fullLayout[ax].range[1]; gd._fullLayout[ax].range = [0, 1]; @@ -2822,8 +2827,8 @@ describe('Test axes', function() { expect(gd._fullLayout.yaxis2._rangeInitial1).toEqual(1); }); - it('should save range when overwrite option is on and range has changed', function() { - ['xaxis', 'yaxis', 'xaxis2', 'yaxis2'].forEach(function(ax) { + it('should save range when overwrite option is on and range has changed', function () { + ['xaxis', 'yaxis', 'xaxis2', 'yaxis2'].forEach(function (ax) { gd._fullLayout[ax]._rangeInitial0 = gd._fullLayout[ax].range[0]; gd._fullLayout[ax]._rangeInitial1 = gd._fullLayout[ax].range[1]; }); @@ -2846,20 +2851,20 @@ describe('Test axes', function() { }); }); - describe('list', function() { + describe('list', function () { var listFunc = Axes.list; var gd; - it('returns empty array when no fullLayout is present', function() { + it('returns empty array when no fullLayout is present', function () { gd = {}; expect(listFunc(gd)).toEqual([]); }); - it('returns array of axes in fullLayout', function() { + it('returns array of axes in fullLayout', function () { gd = { _fullLayout: { - _subplots: {xaxis: ['x'], yaxis: ['y', 'y2']}, + _subplots: { xaxis: ['x'], yaxis: ['y', 'y2'] }, xaxis: { _id: 'x' }, yaxis: { _id: 'y' }, yaxis2: { _id: 'y2' } @@ -2870,10 +2875,10 @@ describe('Test axes', function() { .toEqual([{ _id: 'x' }, { _id: 'y' }, { _id: 'y2' }]); }); - it('returns array of axes, including the ones in scenes', function() { + it('returns array of axes, including the ones in scenes', function () { gd = { _fullLayout: { - _subplots: {xaxis: [], yaxis: [], gl3d: ['scene', 'scene2']}, + _subplots: { xaxis: [], yaxis: [], gl3d: ['scene', 'scene2'] }, scene: { xaxis: { _id: 'x' }, yaxis: { _id: 'y' }, @@ -2894,10 +2899,10 @@ describe('Test axes', function() { ]); }); - it('returns array of axes, excluding the ones in scenes with only2d option', function() { + it('returns array of axes, excluding the ones in scenes with only2d option', function () { gd = { _fullLayout: { - _subplots: {xaxis: ['x2'], yaxis: ['y2'], gl3d: ['scene']}, + _subplots: { xaxis: ['x2'], yaxis: ['y2'], gl3d: ['scene'] }, scene: { xaxis: { _id: 'x' }, yaxis: { _id: 'y' }, @@ -2912,10 +2917,10 @@ describe('Test axes', function() { .toEqual([{ _id: 'x2' }, { _id: 'y2' }]); }); - it('returns array of axes, of particular ax letter with axLetter option', function() { + it('returns array of axes, of particular ax letter with axLetter option', function () { gd = { _fullLayout: { - _subplots: {xaxis: ['x2'], yaxis: ['y2'], gl3d: ['scene']}, + _subplots: { xaxis: ['x2'], yaxis: ['y2'], gl3d: ['scene'] }, scene: { xaxis: { _id: 'x', _thisIs3d: true }, yaxis: { _id: 'y' }, @@ -2931,7 +2936,7 @@ describe('Test axes', function() { }); }); - describe('getSubplots', function() { + describe('getSubplots', function () { var getSubplots = Axes.getSubplots; var gd = { _fullLayout: { @@ -2942,18 +2947,18 @@ describe('Test axes', function() { } }; - it('returns only what was prepopulated in fullLayout._subplots', function() { + it('returns only what was prepopulated in fullLayout._subplots', function () { expect(getSubplots(gd)) .toEqual(['xy', 'x2y2']); }); - it('returns list of subplots ids of particular axis with ax option', function() { + it('returns list of subplots ids of particular axis with ax option', function () { expect(getSubplots(gd, { _id: 'x' })) .toEqual(['xy']); }); }); - describe('getAutoRange', function() { + describe('getAutoRange', function () { var getAutoRange = Axes.getAutoRange; var gd, ax; @@ -2964,7 +2969,7 @@ describe('Test axes', function() { visible: true, xaxis: 'x', _extremes: { - x: {min: min, max: max} + x: { min: min, max: max } } }], _fullLayout: {} @@ -2980,32 +2985,32 @@ describe('Test axes', function() { }; } - it('returns reasonable range without explicit rangemode or autorange', function() { + it('returns reasonable range without explicit rangemode or autorange', function () { gd = mockGd([ // add in an extrapad to verify that it gets used on _min // with a _length of 100, extrapad increases pad by 5 - {val: 1, pad: 15, extrapad: true}, - {val: 3, pad: 0}, - {val: 2, pad: 10} + { val: 1, pad: 15, extrapad: true }, + { val: 3, pad: 0 }, + { val: 2, pad: 10 } ], [ - {val: 6, pad: 10}, - {val: 7, pad: 0}, - {val: 5, pad: 20} + { val: 6, pad: 10 }, + { val: 7, pad: 0 }, + { val: 5, pad: 20 } ]); ax = mockAx(); expect(getAutoRange(gd, ax)).toEqual([-0.5, 7]); }); - it('reverses axes', function() { + it('reverses axes', function () { gd = mockGd([ - {val: 1, pad: 20}, - {val: 3, pad: 0}, - {val: 2, pad: 10} + { val: 1, pad: 20 }, + { val: 3, pad: 0 }, + { val: 2, pad: 10 } ], [ - {val: 6, pad: 10}, - {val: 7, pad: 0}, - {val: 5, pad: 20} + { val: 6, pad: 10 }, + { val: 7, pad: 0 }, + { val: 5, pad: 20 } ]); ax = mockAx(); ax.autorange = 'reversed'; @@ -3014,11 +3019,11 @@ describe('Test axes', function() { expect(getAutoRange(gd, ax)).toEqual([7, -0.5]); }); - it('expands empty range', function() { + it('expands empty range', function () { gd = mockGd([ - {val: 2, pad: 0} + { val: 2, pad: 0 } ], [ - {val: 2, pad: 0} + { val: 2, pad: 0 } ]); ax = mockAx(); ax.rangemode = 'normal'; @@ -3026,15 +3031,15 @@ describe('Test axes', function() { expect(getAutoRange(gd, ax)).toEqual([1, 3]); }); - it('returns a lower bound of 0 on rangemode tozero with positive points', function() { + it('returns a lower bound of 0 on rangemode tozero with positive points', function () { gd = mockGd([ - {val: 1, pad: 20}, - {val: 3, pad: 0}, - {val: 2, pad: 10} + { val: 1, pad: 20 }, + { val: 3, pad: 0 }, + { val: 2, pad: 10 } ], [ - {val: 6, pad: 10}, - {val: 7, pad: 0}, - {val: 5, pad: 20} + { val: 6, pad: 10 }, + { val: 7, pad: 0 }, + { val: 5, pad: 20 } ]); ax = mockAx(); ax.rangemode = 'tozero'; @@ -3042,15 +3047,15 @@ describe('Test axes', function() { expect(getAutoRange(gd, ax)).toEqual([0, 7]); }); - it('returns an upper bound of 0 on rangemode tozero with negative points', function() { + it('returns an upper bound of 0 on rangemode tozero with negative points', function () { gd = mockGd([ - {val: -10, pad: 20}, - {val: -8, pad: 0}, - {val: -9, pad: 10} + { val: -10, pad: 20 }, + { val: -8, pad: 0 }, + { val: -9, pad: 10 } ], [ - {val: -5, pad: 20}, - {val: -4, pad: 0}, - {val: -6, pad: 10}, + { val: -5, pad: 20 }, + { val: -4, pad: 0 }, + { val: -6, pad: 10 }, ]); ax = mockAx(); ax.rangemode = 'tozero'; @@ -3058,15 +3063,15 @@ describe('Test axes', function() { expect(getAutoRange(gd, ax)).toEqual([-12.5, 0]); }); - it('returns a positive and negative range on rangemode tozero with positive and negative points', function() { + it('returns a positive and negative range on rangemode tozero with positive and negative points', function () { gd = mockGd([ - {val: -10, pad: 20}, - {val: -8, pad: 0}, - {val: -9, pad: 10} + { val: -10, pad: 20 }, + { val: -8, pad: 0 }, + { val: -9, pad: 10 } ], [ - {val: 6, pad: 10}, - {val: 7, pad: 0}, - {val: 5, pad: 20} + { val: 6, pad: 10 }, + { val: 7, pad: 0 }, + { val: 5, pad: 20 } ]); ax = mockAx(); ax.rangemode = 'tozero'; @@ -3074,16 +3079,16 @@ describe('Test axes', function() { expect(getAutoRange(gd, ax)).toEqual([-15, 10]); }); - it('reverses range after applying rangemode tozero', function() { + it('reverses range after applying rangemode tozero', function () { gd = mockGd([ - {val: 1, pad: 20}, - {val: 3, pad: 0}, - {val: 2, pad: 10} + { val: 1, pad: 20 }, + { val: 3, pad: 0 }, + { val: 2, pad: 10 } ], [ // add in an extrapad to verify that it gets used on _max - {val: 6, pad: 15, extrapad: true}, - {val: 7, pad: 0}, - {val: 5, pad: 10} + { val: 6, pad: 15, extrapad: true }, + { val: 7, pad: 0 }, + { val: 5, pad: 10 } ]); ax = mockAx(); ax.autorange = 'reversed'; @@ -3092,11 +3097,11 @@ describe('Test axes', function() { expect(getAutoRange(gd, ax)).toEqual([7.5, 0]); }); - it('expands empty positive range to include 0 with rangemode tozero', function() { + it('expands empty positive range to include 0 with rangemode tozero', function () { gd = mockGd([ - {val: 5, pad: 0} + { val: 5, pad: 0 } ], [ - {val: 5, pad: 0} + { val: 5, pad: 0 } ]); ax = mockAx(); ax.rangemode = 'tozero'; @@ -3104,11 +3109,11 @@ describe('Test axes', function() { expect(getAutoRange(gd, ax)).toEqual([0, 5]); }); - it('expands empty negative range to something including 0 with rangemode tozero', function() { + it('expands empty negative range to something including 0 with rangemode tozero', function () { gd = mockGd([ - {val: -5, pad: 0} + { val: -5, pad: 0 } ], [ - {val: -5, pad: 0} + { val: -5, pad: 0 } ]); ax = mockAx(); ax.rangemode = 'tozero'; @@ -3116,11 +3121,11 @@ describe('Test axes', function() { expect(getAutoRange(gd, ax)).toEqual([-5, 0]); }); - it('pads an empty range, but not past center, with rangemode tozero', function() { + it('pads an empty range, but not past center, with rangemode tozero', function () { gd = mockGd([ - {val: 5, pad: 50} // this min pad gets ignored + { val: 5, pad: 50 } // this min pad gets ignored ], [ - {val: 5, pad: 20} + { val: 5, pad: 20 } ]); ax = mockAx(); ax.rangemode = 'tozero'; @@ -3128,9 +3133,9 @@ describe('Test axes', function() { expect(getAutoRange(gd, ax)).toBeCloseToArray([0, 6.25], 0.01); gd = mockGd([ - {val: -5, pad: 80} + { val: -5, pad: 80 } ], [ - {val: -5, pad: 0} + { val: -5, pad: 0 } ]); ax = mockAx(); ax.rangemode = 'tozero'; @@ -3138,11 +3143,11 @@ describe('Test axes', function() { expect(getAutoRange(gd, ax)).toBeCloseToArray([-10, 0], 0.01); }); - it('shows the data even if it cannot show the padding', function() { + it('shows the data even if it cannot show the padding', function () { gd = mockGd([ - {val: 0, pad: 44} + { val: 0, pad: 44 } ], [ - {val: 1, pad: 44} + { val: 1, pad: 44 } ]); ax = mockAx(); @@ -3151,9 +3156,9 @@ describe('Test axes', function() { expect(getAutoRange(gd, ax)).toBeCloseToArray([-3.67, 4.67]); gd = mockGd([ - {val: 0, pad: 46} + { val: 0, pad: 46 } ], [ - {val: 1, pad: 46} + { val: 1, pad: 46 } ]); ax = mockAx(); @@ -3162,9 +3167,9 @@ describe('Test axes', function() { expect(getAutoRange(gd, ax)).toEqual([0, 1]); gd = mockGd([ - {val: 0, pad: 400} + { val: 0, pad: 400 } ], [ - {val: 1, pad: 0} + { val: 1, pad: 0 } ]); ax = mockAx(); @@ -3172,15 +3177,15 @@ describe('Test axes', function() { expect(getAutoRange(gd, ax)).toEqual([0, 1]); }); - it('never returns a negative range when rangemode nonnegative is set with positive and negative points', function() { + it('never returns a negative range when rangemode nonnegative is set with positive and negative points', function () { gd = mockGd([ - {val: -10, pad: 20}, - {val: -8, pad: 0}, - {val: -9, pad: 10} + { val: -10, pad: 20 }, + { val: -8, pad: 0 }, + { val: -9, pad: 10 } ], [ - {val: 6, pad: 20}, - {val: 7, pad: 0}, - {val: 5, pad: 10} + { val: 6, pad: 20 }, + { val: 7, pad: 0 }, + { val: 5, pad: 10 } ]); ax = mockAx(); ax.rangemode = 'nonnegative'; @@ -3188,15 +3193,15 @@ describe('Test axes', function() { expect(getAutoRange(gd, ax)).toEqual([0, 7.5]); }); - it('never returns a negative range when rangemode nonnegative is set with only negative points', function() { + it('never returns a negative range when rangemode nonnegative is set with only negative points', function () { gd = mockGd([ - {val: -10, pad: 20}, - {val: -8, pad: 0}, - {val: -9, pad: 10} + { val: -10, pad: 20 }, + { val: -8, pad: 0 }, + { val: -9, pad: 10 } ], [ - {val: -5, pad: 20}, - {val: -4, pad: 0}, - {val: -6, pad: 10} + { val: -5, pad: 20 }, + { val: -4, pad: 0 }, + { val: -6, pad: 10 } ]); ax = mockAx(); ax.rangemode = 'nonnegative'; @@ -3204,15 +3209,15 @@ describe('Test axes', function() { expect(getAutoRange(gd, ax)).toEqual([0, 1]); }); - it('never returns a negative range when rangemode nonnegative is set with only nonpositive points', function() { + it('never returns a negative range when rangemode nonnegative is set with only nonpositive points', function () { gd = mockGd([ - {val: -10, pad: 20}, - {val: -8, pad: 0}, - {val: -9, pad: 10} + { val: -10, pad: 20 }, + { val: -8, pad: 0 }, + { val: -9, pad: 10 } ], [ - {val: -5, pad: 20}, - {val: 0, pad: 0}, - {val: -6, pad: 10} + { val: -5, pad: 20 }, + { val: 0, pad: 0 }, + { val: -6, pad: 10 } ]); ax = mockAx(); ax.rangemode = 'nonnegative'; @@ -3220,20 +3225,20 @@ describe('Test axes', function() { expect(getAutoRange(gd, ax)).toEqual([0, 1]); }); - it('expands empty range to something nonnegative with rangemode nonnegative', function() { + it('expands empty range to something nonnegative with rangemode nonnegative', function () { [ [-5, [0, 1]], [0, [0, 1]], [0.5, [0, 1.5]], [1, [0, 2]], [5, [4, 6]] - ].forEach(function(testCase) { + ].forEach(function (testCase) { var val = testCase[0]; var expected = testCase[1]; gd = mockGd([ - {val: val, pad: 0} + { val: val, pad: 0 } ], [ - {val: val, pad: 0} + { val: val, pad: 0 } ]); ax = mockAx(); ax.rangemode = 'nonnegative'; @@ -3243,7 +3248,7 @@ describe('Test axes', function() { }); }); - describe('findExtremes', function() { + describe('findExtremes', function () { var findExtremes = Axes.findExtremes; var ax, data, options, out; @@ -3255,52 +3260,52 @@ describe('Test axes', function() { }; } - it('constructs simple ax._min and ._max correctly', function() { + it('constructs simple ax._min and ._max correctly', function () { ax = getDefaultAx(); data = [1, 4, 7, 2]; out = findExtremes(ax, data); - expect(out.min).toEqual([{val: 1, pad: 0, extrapad: false}]); - expect(out.max).toEqual([{val: 7, pad: 0, extrapad: false}]); + expect(out.min).toEqual([{ val: 1, pad: 0, extrapad: false }]); + expect(out.max).toEqual([{ val: 7, pad: 0, extrapad: false }]); }); - it('calls ax.setScale if necessary', function() { + it('calls ax.setScale if necessary', function () { ax = getDefaultAx(); delete ax._m; - ax.setScale = function() {}; + ax.setScale = function () { }; spyOn(ax, 'setScale'); findExtremes(ax, [1]); expect(ax.setScale).toHaveBeenCalled(); }); - it('handles symmetric pads as numbers', function() { + it('handles symmetric pads as numbers', function () { ax = getDefaultAx(); data = [1, 4, 2, 7]; - options = {vpad: 2, ppad: 10}; + options = { vpad: 2, ppad: 10 }; out = findExtremes(ax, data, options); - expect(out.min).toEqual([{val: -1, pad: 10, extrapad: false}]); - expect(out.max).toEqual([{val: 9, pad: 10, extrapad: false}]); + expect(out.min).toEqual([{ val: -1, pad: 10, extrapad: false }]); + expect(out.max).toEqual([{ val: 9, pad: 10, extrapad: false }]); }); - it('handles symmetric pads as number arrays', function() { + it('handles symmetric pads as number arrays', function () { ax = getDefaultAx(); data = [1, 4, 2, 7]; - options = {vpad: [1, 10, 6, 3], ppad: [0, 15, 20, 10]}; + options = { vpad: [1, 10, 6, 3], ppad: [0, 15, 20, 10] }; out = findExtremes(ax, data, options); expect(out.min).toEqual([ - {val: -6, pad: 15, extrapad: false}, - {val: -4, pad: 20, extrapad: false} + { val: -6, pad: 15, extrapad: false }, + { val: -4, pad: 20, extrapad: false } ]); expect(out.max).toEqual([ - {val: 14, pad: 15, extrapad: false}, - {val: 8, pad: 20, extrapad: false} + { val: 14, pad: 15, extrapad: false }, + { val: 8, pad: 20, extrapad: false } ]); }); - it('handles separate pads as numbers', function() { + it('handles separate pads as numbers', function () { ax = getDefaultAx(); data = [1, 4, 2, 7]; options = { @@ -3311,11 +3316,11 @@ describe('Test axes', function() { }; out = findExtremes(ax, data, options); - expect(out.min).toEqual([{val: -4, pad: 10, extrapad: false}]); - expect(out.max).toEqual([{val: 11, pad: 20, extrapad: false}]); + expect(out.min).toEqual([{ val: -4, pad: 10, extrapad: false }]); + expect(out.max).toEqual([{ val: 11, pad: 20, extrapad: false }]); }); - it('handles separate pads as number arrays', function() { + it('handles separate pads as number arrays', function () { ax = getDefaultAx(); data = [1, 4, 2, 7]; options = { @@ -3327,17 +3332,17 @@ describe('Test axes', function() { out = findExtremes(ax, data, options); expect(out.min).toEqual([ - {val: 1, pad: 30, extrapad: false}, - {val: -3, pad: 10, extrapad: false} + { val: 1, pad: 30, extrapad: false }, + { val: -3, pad: 10, extrapad: false } ]); expect(out.max).toEqual([ - {val: 9, pad: 0, extrapad: false}, - {val: 3, pad: 40, extrapad: false}, - {val: 8, pad: 20, extrapad: false} + { val: 9, pad: 0, extrapad: false }, + { val: 3, pad: 40, extrapad: false }, + { val: 8, pad: 20, extrapad: false } ]); }); - it('overrides symmetric pads with separate pads', function() { + it('overrides symmetric pads with separate pads', function () { ax = getDefaultAx(); data = [1, 5]; options = { @@ -3350,51 +3355,51 @@ describe('Test axes', function() { }; out = findExtremes(ax, data, options); - expect(out.min).toEqual([{val: -1, pad: 20, extrapad: false}]); - expect(out.max).toEqual([{val: 9, pad: 40, extrapad: false}]); + expect(out.min).toEqual([{ val: -1, pad: 20, extrapad: false }]); + expect(out.max).toEqual([{ val: 9, pad: 40, extrapad: false }]); }); - it('adds 5% padding if specified by flag', function() { + it('adds 5% padding if specified by flag', function () { ax = getDefaultAx(); data = [1, 5]; - options = {vpad: 1, ppad: 10, padded: true}; + options = { vpad: 1, ppad: 10, padded: true }; out = findExtremes(ax, data, options); - expect(out.min).toEqual([{val: 0, pad: 10, extrapad: true}]); - expect(out.max).toEqual([{val: 6, pad: 10, extrapad: true}]); + expect(out.min).toEqual([{ val: 0, pad: 10, extrapad: true }]); + expect(out.max).toEqual([{ val: 6, pad: 10, extrapad: true }]); }); - it('has lower bound zero with all positive data if tozero is sset', function() { + it('has lower bound zero with all positive data if tozero is sset', function () { ax = getDefaultAx(); data = [2, 5]; - options = {vpad: 1, ppad: 10, tozero: true}; + options = { vpad: 1, ppad: 10, tozero: true }; out = findExtremes(ax, data, options); - expect(out.min).toEqual([{val: 0, pad: 0, extrapad: false}]); - expect(out.max).toEqual([{val: 6, pad: 10, extrapad: false}]); + expect(out.min).toEqual([{ val: 0, pad: 0, extrapad: false }]); + expect(out.max).toEqual([{ val: 6, pad: 10, extrapad: false }]); }); - it('has upper bound zero with all negative data if tozero is set', function() { + it('has upper bound zero with all negative data if tozero is set', function () { ax = getDefaultAx(); data = [-7, -4]; - options = {vpad: 1, ppad: 10, tozero: true}; + options = { vpad: 1, ppad: 10, tozero: true }; out = findExtremes(ax, data, options); - expect(out.min).toEqual([{val: -8, pad: 10, extrapad: false}]); - expect(out.max).toEqual([{val: 0, pad: 0, extrapad: false}]); + expect(out.min).toEqual([{ val: -8, pad: 10, extrapad: false }]); + expect(out.max).toEqual([{ val: 0, pad: 0, extrapad: false }]); }); - it('sets neither bound to zero with positive and negative data if tozero is set', function() { + it('sets neither bound to zero with positive and negative data if tozero is set', function () { ax = getDefaultAx(); data = [-7, 4]; - options = {vpad: 1, ppad: 10, tozero: true}; + options = { vpad: 1, ppad: 10, tozero: true }; out = findExtremes(ax, data, options); - expect(out.min).toEqual([{val: -8, pad: 10, extrapad: false}]); - expect(out.max).toEqual([{val: 5, pad: 10, extrapad: false}]); + expect(out.min).toEqual([{ val: -8, pad: 10, extrapad: false }]); + expect(out.max).toEqual([{ val: 5, pad: 10, extrapad: false }]); }); - it('overrides padded with tozero', function() { + it('overrides padded with tozero', function () { ax = getDefaultAx(); data = [2, 5]; options = { @@ -3405,37 +3410,39 @@ describe('Test axes', function() { }; out = findExtremes(ax, data, options); - expect(out.min).toEqual([{val: 0, pad: 0, extrapad: false}]); - expect(out.max).toEqual([{val: 6, pad: 10, extrapad: true}]); + expect(out.min).toEqual([{ val: 0, pad: 0, extrapad: false }]); + expect(out.max).toEqual([{ val: 6, pad: 10, extrapad: true }]); }); - it('should fail if no data is given', function() { + it('should fail if no data is given', function () { ax = getDefaultAx(); - expect(function() { findExtremes(ax); }).toThrow(); + expect(function () { findExtremes(ax); }).toThrow(); }); - it('should return even if `autorange` is false', function() { + it('should return even if `autorange` is false', function () { ax = getDefaultAx(); ax.autorange = false; ax.rangeslider = { autorange: false }; data = [2, 5]; out = findExtremes(ax, data, {}); - expect(out.min).toEqual([{val: 2, pad: 0, extrapad: false}]); - expect(out.max).toEqual([{val: 5, pad: 0, extrapad: false}]); + expect(out.min).toEqual([{ val: 2, pad: 0, extrapad: false }]); + expect(out.max).toEqual([{ val: 5, pad: 0, extrapad: false }]); }); }); - describe('calcTicks and tickText', function() { + describe('calcTicks and tickText', function () { function mockCalc(ax) { ax.tickfont = {}; - Axes.setConvert(ax, {separators: '.,', _extraFormat: { - year: '%Y', - month: '%b %Y', - dayMonth: '%b %-d', - dayMonthYear: '%b %-d, %Y' - }}); - return Axes.calcTicks(ax).map(function(v) { return v.text; }); + Axes.setConvert(ax, { + separators: '.,', _extraFormat: { + year: '%Y', + month: '%b %Y', + dayMonth: '%b %-d', + dayMonthYear: '%b %-d, %Y' + } + }); + return Axes.calcTicks(ax).map(function (v) { return v.text; }); } function mockHoverText(ax, x) { @@ -3445,13 +3452,13 @@ describe('Test axes', function() { } function checkHovers(ax, specArray) { - specArray.forEach(function(v) { + specArray.forEach(function (v) { expect(mockHoverText(ax, v[0])) .toBe(v[1], ax.dtick + ' - ' + v[0]); }); } - it('reverts to "power" for SI/B exponentformat beyond the prefix range (linear case)', function() { + it('reverts to "power" for SI/B exponentformat beyond the prefix range (linear case)', function () { var textOut = mockCalc({ type: 'linear', tickmode: 'linear', @@ -3557,7 +3564,7 @@ describe('Test axes', function() { expect(textOut).toEqual(['0']); }); - it('reverts to "power" for SI/B exponentformat beyond the prefix range (log case)', function() { + it('reverts to "power" for SI/B exponentformat beyond the prefix range (log case)', function () { var textOut = mockCalc({ type: 'log', tickmode: 'linear', @@ -3601,7 +3608,7 @@ describe('Test axes', function() { ]); }); - it('Does not use SI prefixes for 10^n with |n| < minexponent', function() { + it('Does not use SI prefixes for 10^n with |n| < minexponent', function () { var textOut = mockCalc({ type: 'log', tickmode: 'linear', @@ -3653,8 +3660,8 @@ describe('Test axes', function() { ]); }); - it('supports e/E format on log axes', function() { - ['e', 'E'].forEach(function(e) { + it('supports e/E format on log axes', function () { + ['e', 'E'].forEach(function (e) { var textOut = mockCalc({ type: 'log', tickmode: 'linear', @@ -3682,7 +3689,7 @@ describe('Test axes', function() { }); }); - it('formats tick labels correctly for small numbers in exponential notation', function() { + it('formats tick labels correctly for small numbers in exponential notation', function () { var textOut = mockCalc({ type: 'linear', tickmode: 'linear', @@ -3726,7 +3733,7 @@ describe('Test axes', function() { ]); }); - it('provides a new date suffix whenever the suffix changes', function() { + it('provides a new date suffix whenever the suffix changes', function () { var ax = { type: 'date', tickmode: 'linear', @@ -3793,7 +3800,7 @@ describe('Test axes', function() { .toBe('Feb 4, 2000'); }); - it('should give dates extra precision if tick0 is weird', function() { + it('should give dates extra precision if tick0 is weird', function () { var ax = { type: 'date', tickmode: 'linear', @@ -3818,7 +3825,7 @@ describe('Test axes', function() { .toBe('Feb 4, 2000, 00:00:05'); }); - it('should never give dates more than 100 microsecond precision', function() { + it('should never give dates more than 100 microsecond precision', function () { var ax = { type: 'date', tickmode: 'linear', @@ -3842,7 +3849,7 @@ describe('Test axes', function() { expect(textOut).toEqual(expectedText); }); - it('never gives date dtick < 100 microseconds (autotick case)', function() { + it('never gives date dtick < 100 microseconds (autotick case)', function () { var ax = { type: 'date', tickmode: 'auto', @@ -3855,7 +3862,7 @@ describe('Test axes', function() { expect(textOut).toEqual(expectedText); }); - it('never gives date dtick < 100 microseconds (explicit tick case)', function() { + it('never gives date dtick < 100 microseconds (explicit tick case)', function () { var ax = { type: 'date', tickmode: 'linear', @@ -3869,7 +3876,7 @@ describe('Test axes', function() { expect(textOut).toEqual(expectedText); }); - it('should handle edge cases with dates and tickvals', function() { + it('should handle edge cases with dates and tickvals', function () { var ax = { type: 'date', tickmode: 'array', @@ -3904,8 +3911,8 @@ describe('Test axes', function() { .toBe('Jan 1, 2012, 12:34:56'); }); - it('should handle tickvals edge cases with linear and log axes', function() { - ['linear', 'log'].forEach(function(axType) { + it('should handle tickvals edge cases with linear and log axes', function () { + ['linear', 'log'].forEach(function (axType) { var ax = { type: axType, tickmode: 'array', @@ -3931,11 +3938,11 @@ describe('Test axes', function() { }); }); - it('should handle tickvals edge cases with category axes', function() { + it('should handle tickvals edge cases with category axes', function () { var ax = { type: 'category', _categories: ['a', 'b', 'c', 'd'], - _categoriesMap: {a: 0, b: 1, c: 2, d: 3}, + _categoriesMap: { a: 0, b: 1, c: 2, d: 3 }, tickmode: 'array', tickvals: ['a', 1, 1.5, 'c', 2.7, 3, 'e', 4, 5, -2], ticktext: ['A!', 'B?', 'B->C'], @@ -3952,7 +3959,7 @@ describe('Test axes', function() { 'd', // non-integer position, no text: use closest category 'd', // integer position, no text: use category '' // 4: number with no close category: leave blank - // but still include it so we get a tick mark & grid + // but still include it so we get a tick mark & grid // 'e', 5, -2: bad category and numbers out of range: omitted ]; expect(textOut).toEqual(expectedText); @@ -3964,11 +3971,11 @@ describe('Test axes', function() { expect(ax._categories).toEqual(['a', 'b', 'c', 'd']); }); - it('notices when all categories are off the edge', function() { + it('notices when all categories are off the edge', function () { var ax = { type: 'category', _categories: ['a', 'b', 'c', 'd'], - _categoriesMap: {a: 0, b: 1, c: 2, d: 3}, + _categoriesMap: { a: 0, b: 1, c: 2, d: 3 }, tickmode: 'linear', tick0: 0, dtick: 1, @@ -3981,13 +3988,13 @@ describe('Test axes', function() { ax.range = [3.5, -0.5]; expect(mockCalc(ax)).toEqual(['d', 'c', 'b', 'a']); - [[-5, -1], [-1, -5], [5, 10], [10, 5]].forEach(function(rng) { + [[-5, -1], [-1, -5], [5, 10], [10, 5]].forEach(function (rng) { ax.range = rng; expect(mockCalc(ax).length).toBe(0, rng); }); }); - it('should always start at year for date axis hover', function() { + it('should always start at year for date axis hover', function () { var ax = { type: 'date', tickmode: 'linear', @@ -4073,7 +4080,7 @@ describe('Test axes', function() { ]); }); - it('avoids infinite loops due to rounding errors', function() { + it('avoids infinite loops due to rounding errors', function () { var textOut = mockCalc({ type: 'linear', tickmode: 'linear', @@ -4086,7 +4093,7 @@ describe('Test axes', function() { expect(textOut.length).toBe(0); }); - it('truncates at the greater of 1001 ticks or one per pixel', function() { + it('truncates at the greater of 1001 ticks or one per pixel', function () { var ax = { type: 'linear', tickmode: 'linear', @@ -4103,7 +4110,7 @@ describe('Test axes', function() { expect(mockCalc(ax).length).toBe(10001); }); - it('never hides the exponent when in hover mode', function() { + it('never hides the exponent when in hover mode', function () { var ax = { type: 'linear', tickmode: 'linear', @@ -4121,7 +4128,7 @@ describe('Test axes', function() { }); }); - describe('autoBin', function() { + describe('autoBin', function () { function _autoBin(x, ax, nbins) { ax._categories = []; ax._categoriesMap = {}; @@ -4132,7 +4139,7 @@ describe('Test axes', function() { return Axes.autoBin(d, ax, nbins, false, 'gregorian'); } - it('should auto bin categories', function() { + it('should auto bin categories', function () { var out = _autoBin( ['apples', 'oranges', 'bananas'], { type: 'category' } @@ -4146,7 +4153,7 @@ describe('Test axes', function() { }); }); - it('should not error out for categories on linear axis', function() { + it('should not error out for categories on linear axis', function () { var out = _autoBin( ['apples', 'oranges', 'bananas'], { type: 'linear' } @@ -4160,7 +4167,7 @@ describe('Test axes', function() { }); }); - it('should not error out for categories on log axis', function() { + it('should not error out for categories on log axis', function () { var out = _autoBin( ['apples', 'oranges', 'bananas'], { type: 'log' } @@ -4174,7 +4181,7 @@ describe('Test axes', function() { }); }); - it('should not error out for categories on date axis', function() { + it('should not error out for categories on date axis', function () { var out = _autoBin( ['apples', 'oranges', 'bananas'], { type: 'date' } @@ -4188,7 +4195,7 @@ describe('Test axes', function() { }); }); - it('should auto bin linear data', function() { + it('should auto bin linear data', function () { var out = _autoBin( [1, 1, 2, 2, 3, 3, 4, 4], { type: 'linear' } @@ -4202,7 +4209,7 @@ describe('Test axes', function() { }); }); - it('should auto bin linear data with nbins constraint', function() { + it('should auto bin linear data with nbins constraint', function () { var out = _autoBin( [1, 1, 2, 2, 3, 3, 4, 4], { type: 'linear' }, @@ -4221,27 +4228,27 @@ describe('Test axes', function() { }); }); - describe('makeCalcdata', function() { + describe('makeCalcdata', function () { var ax; function _makeCalcdata(trace, axLetter, axType) { - ax = {type: axType}; + ax = { type: axType }; Axes.setConvert(ax); ax._categories = []; ax._traceIndices = [0]; - if(axType === 'multicategory') ax.setupMultiCategory([trace]); + if (axType === 'multicategory') ax.setupMultiCategory([trace]); return ax.makeCalcdata(trace, axLetter); } - describe('should convert items', function() { - it('- linear case', function() { + describe('should convert items', function () { + it('- linear case', function () { var out = _makeCalcdata({ x: ['1', NaN, null, 2], }, 'x', 'linear'); expect(out).toEqual([1, BADNUM, BADNUM, 2]); }); - it('- date case', function() { + it('- date case', function () { var msLocal = new Date(2000, 0, 1).getTime(); var msUTC = 946684800000; var out = _makeCalcdata({ @@ -4256,7 +4263,7 @@ describe('Test axes', function() { expect(out2).toEqual([msUTC, msUTC, msUTC + 0.1, msUTC + 0.5, msUTC + 0.9, msUTC + 1, msUTC + 1]); }); - it('- category case', function() { + it('- category case', function () { var out = _makeCalcdata({ x: ['a', 'b', null, 4], }, 'x', 'category'); @@ -4265,15 +4272,15 @@ describe('Test axes', function() { }); }); - describe('should fill item to other coordinate length if not present', function() { - it('- base case', function() { + describe('should fill item to other coordinate length if not present', function () { + it('- base case', function () { var out = _makeCalcdata({ y: [1, 2, 1], }, 'x', 'linear'); expect(out).toEqual([0, 1, 2]); }); - it('- x0/dx case', function() { + it('- x0/dx case', function () { var out = _makeCalcdata({ y: [1, 2, 1], x0: 2, @@ -4283,7 +4290,7 @@ describe('Test axes', function() { expect(out).toEqual([2, 12, 22]); }); - it('- other length case', function() { + it('- other length case', function () { var out = _makeCalcdata({ _length: 5, y: [1, 2, 1], @@ -4292,8 +4299,8 @@ describe('Test axes', function() { }); }); - describe('should subarray typed arrays', function() { - it('- same length linear case', function() { + describe('should subarray typed arrays', function () { + it('- same length linear case', function () { var x = new Float32Array([1, 2, 3]); var out = _makeCalcdata({ _length: 3, @@ -4302,7 +4309,7 @@ describe('Test axes', function() { expect(out).toBe(x); }); - it('- same length log case', function() { + it('- same length log case', function () { var x = new Float32Array([1, 2, 3]); var out = _makeCalcdata({ _length: 3, @@ -4311,7 +4318,7 @@ describe('Test axes', function() { expect(out).toBe(x); }); - it('- subarray case', function() { + it('- subarray case', function () { var x = new Float32Array([1, 2, 3]); var out = _makeCalcdata({ _length: 2, @@ -4324,8 +4331,8 @@ describe('Test axes', function() { }); }); - describe('should convert typed arrays to plain array', function() { - it('- on a category axis', function() { + describe('should convert typed arrays to plain array', function () { + it('- on a category axis', function () { var out = _makeCalcdata({ x: new Float32Array([3, 1, 2]), }, 'x', 'category'); @@ -4333,9 +4340,9 @@ describe('Test axes', function() { expect(ax._categories).toEqual(['3', '1', '2']); }); - it('- on a date axis', function() { + it('- on a date axis', function () { var dates = [[2000, 0, 1], [2001, 0, 1], [2002, 0, 1]] - .map(function(d) { return new Date(d[0], d[1], d[2]).getTime(); }); + .map(function (d) { return new Date(d[0], d[1], d[2]).getTime(); }); // We could make this work down the road (in v3), // when address our timezone problems. @@ -4347,48 +4354,48 @@ describe('Test axes', function() { }); }); - describe('should set up category maps correctly for multicategory axes', function() { - it('case 1', function() { + describe('should set up category maps correctly for multicategory axes', function () { + it('case 1', function () { var out = _makeCalcdata({ x: [['1', '1', '2', '2'], ['a', 'b', 'a', 'b']] }, 'x', 'multicategory'); expect(out).toEqual([0, 1, 2, 3]); expect(ax._categories).toEqual([['1', 'a'], ['1', 'b'], ['2', 'a'], ['2', 'b']]); - expect(ax._categoriesMap).toEqual({'1,a': 0, '1,b': 1, '2,a': 2, '2,b': 3}); + expect(ax._categoriesMap).toEqual({ '1,a': 0, '1,b': 1, '2,a': 2, '2,b': 3 }); }); - it('case 2', function() { + it('case 2', function () { var out = _makeCalcdata({ x: [['1', '2', '1', '2'], ['a', 'a', 'b', 'b']] }, 'x', 'multicategory'); expect(out).toEqual([0, 2, 1, 3]); expect(ax._categories).toEqual([['1', 'a'], ['1', 'b'], ['2', 'a'], ['2', 'b']]); - expect(ax._categoriesMap).toEqual({'1,a': 0, '1,b': 1, '2,a': 2, '2,b': 3}); + expect(ax._categoriesMap).toEqual({ '1,a': 0, '1,b': 1, '2,a': 2, '2,b': 3 }); }); - it('case invalid in x[0]', function() { + it('case invalid in x[0]', function () { var out = _makeCalcdata({ x: [['1', '2', null, '2'], ['a', 'a', 'b', 'b']] }, 'x', 'multicategory'); expect(out).toEqual([0, 1, BADNUM, 2]); expect(ax._categories).toEqual([['1', 'a'], ['2', 'a'], ['2', 'b']]); - expect(ax._categoriesMap).toEqual({'1,a': 0, '2,a': 1, '2,b': 2}); + expect(ax._categoriesMap).toEqual({ '1,a': 0, '2,a': 1, '2,b': 2 }); }); - it('case invalid in x[1]', function() { + it('case invalid in x[1]', function () { var out = _makeCalcdata({ x: [['1', '2', '1', '2'], ['a', 'a', null, 'b']] }, 'x', 'multicategory'); expect(out).toEqual([0, 1, BADNUM, 2]); expect(ax._categories).toEqual([['1', 'a'], ['2', 'a'], ['2', 'b']]); - expect(ax._categoriesMap).toEqual({'1,a': 0, '2,a': 1, '2,b': 2}); + expect(ax._categoriesMap).toEqual({ '1,a': 0, '2,a': 1, '2,b': 2 }); }); - it('case 1D coordinate array', function() { + it('case 1D coordinate array', function () { var out = _makeCalcdata({ x: ['a', 'b', 'c'] }, 'x', 'multicategory'); @@ -4398,7 +4405,7 @@ describe('Test axes', function() { expect(ax._categoriesMap).toEqual(undefined); }); - it('case 2D 1-row coordinate array', function() { + it('case 2D 1-row coordinate array', function () { var out = _makeCalcdata({ x: [['a', 'b', 'c']] }, 'x', 'multicategory'); @@ -4408,7 +4415,7 @@ describe('Test axes', function() { expect(ax._categoriesMap).toEqual(undefined); }); - it('case 2D with empty x[0] row coordinate array', function() { + it('case 2D with empty x[0] row coordinate array', function () { var out = _makeCalcdata({ x: [null, ['a', 'b', 'c']] }, 'x', 'multicategory'); @@ -4418,7 +4425,7 @@ describe('Test axes', function() { expect(ax._categoriesMap).toEqual(undefined); }); - it('case with inner typed arrays and set type:multicategory', function() { + it('case with inner typed arrays and set type:multicategory', function () { var out = _makeCalcdata({ x: [ new Float32Array([1, 2, 1, 2]), @@ -4428,15 +4435,15 @@ describe('Test axes', function() { expect(out).toEqual([0, 2, 1, 3]); expect(ax._categories).toEqual([[1, 10], [1, 20], [2, 10], [2, 20]]); - expect(ax._categoriesMap).toEqual({'1,10': 0, '1,20': 1, '2,10': 2, '2,20': 3}); + expect(ax._categoriesMap).toEqual({ '1,10': 0, '1,20': 1, '2,10': 2, '2,20': 3 }); }); }); - describe('2d coordinate array on non-multicategory axes should return BADNUMs', function() { + describe('2d coordinate array on non-multicategory axes should return BADNUMs', function () { var axTypes = ['linear', 'log', 'date']; - axTypes.forEach(function(t) { - it('- case ' + t, function() { + axTypes.forEach(function (t) { + it('- case ' + t, function () { var out = _makeCalcdata({ x: [['1', '1', '2', '2'], ['a', 'b', 'a', 'b']] }, 'x', t); @@ -4444,7 +4451,7 @@ describe('Test axes', function() { }); }); - it('- case category', function() { + it('- case category', function () { var out = _makeCalcdata({ x: [['1', '1', '2', '2'], ['a', 'b', 'a', 'b']] }, 'x', 'category'); @@ -4454,21 +4461,21 @@ describe('Test axes', function() { }); }); - describe('automargin', function() { + describe('automargin', function () { var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); afterEach(destroyGraphDiv); - it('should grow and shrink margins', function(done) { + it('should grow and shrink margins', function (done) { var initialSize; var previousSize; function assertSize(msg, actual, exp) { - for(var k in exp) { + for (var k in exp) { var parts = exp[k].split('|'); var op = parts[0]; @@ -4483,9 +4490,9 @@ describe('Test axes', function() { var val = op === 'initial' ? initialSize[k] : previousSize[k]; var msgk = msg + ' ' + k + (parts[1] ? ' |' + parts[1] : ''); var args = [val]; - if(op === '~=') { + if (op === '~=') { args.push(1.1); - } else if(method === 'toBeCloseTo') { + } else if (method === 'toBeCloseTo') { args.push(3); } args.push(msgk); @@ -4495,8 +4502,8 @@ describe('Test axes', function() { } function check(msg, relayoutObj, exp) { - return function() { - return Plotly.relayout(gd, relayoutObj).then(function() { + return function () { + return Plotly.relayout(gd, relayoutObj).then(function () { var gs = Lib.extendDeep({}, gd._fullLayout._size); assertSize(msg, gs, exp); previousSize = gs; @@ -4520,96 +4527,96 @@ describe('Test axes', function() { 'short label 5', 'loooooong label 5' ] }], { - margin: {l: 0, r: 0, b: 0, t: 0}, + margin: { l: 0, r: 0, b: 0, t: 0 }, width: 600, height: 600 }) - .then(function() { - expect(gd._fullLayout.xaxis._tickAngles.xtick).toBeCloseTo(30, 3); + .then(function () { + expect(gd._fullLayout.xaxis._tickAngles.xtick).toBeCloseTo(30, 3); - var gs = gd._fullLayout._size; - initialSize = Lib.extendDeep({}, gs); - previousSize = Lib.extendDeep({}, gs); - }) - .then(check('automargin y', {'yaxis.automargin': true}, { - t: '=', l: 'grew', - b: '=', r: '=' - })) - .then(check('automargin x', {'xaxis.automargin': true}, { - t: '=', l: '=', - b: 'grew', r: 'grew' - })) - .then(check('move all x label off-screen', {'xaxis.range': [-10, -5]}, { - t: '=', l: '=', - b: 'initial', r: 'initial' - })) - .then(check('move all y label off-screen', {'yaxis.range': [-10, -5]}, { - t: '=', l: 'initial', - b: '=', r: '=' - })) - .then(check('back to label for auto ranges', {'xaxis.autorange': true, 'yaxis.autorange': true}, { - t: '=', l: 'grew', - b: 'grew', r: 'grew' - })) - .then(check('tilt x label to 45 degrees', {'xaxis.tickangle': 45}, { - t: '=', l: '=', - b: 'grew', r: 'shrunk' - })) - .then(check('tilt x labels back to 30 degrees', {'xaxis.tickangle': 30}, { - t: '=', l: '=', - b: 'shrunk', r: 'grew' - })) - .then(check('bump y-axis tick length', {'yaxis.ticklen': 30}, { - t: '=', l: 'grew', - b: '=', r: 'grew| as x ticks got shifted right' - })) - .then(check('add y-axis title', {'yaxis.title.text': 'hello'}, { - t: '=', l: 'grew', - b: '=', r: 'grew| as x ticks got shifted right' - })) - .then(check('size up y-axis title', {'yaxis.title.font.size': 30}, { - t: '=', l: 'grew', - b: '=', r: 'grew| as x ticks got shifted right' - })) - .then(check('tilt y labels up 30 degrees', {'yaxis.tickangle': 30}, { - t: 'grew', l: 'shrunk', - b: '=', r: 'shrunk| as x ticks got shifted left' - })) - .then(check('un-tilt y labels', {'yaxis.tickangle': null}, { - t: 'shrunk', l: 'grew', - b: '=', r: 'grew' - })) - .then(check('unanchor y-axis', {'yaxis.anchor': 'free'}, { - t: '=', l: '~=', - b: '=', r: '=' - })) - .then(check('offset y-axis to the left', {'yaxis.position': 0.1}, { - t: '=', l: 'shrunk| as y-axis shifted right', - b: '=', r: 'shrunk| as y-axis shifted right' - })) - .then(check('re-anchor y-axis', {'yaxis.anchor': 'x'}, { - t: '=', l: 'grew', - b: '=', r: 'grew' - })) - .then(check('flip axis side', {'yaxis.side': 'right', 'xaxis.side': 'top'}, { - t: 'grew', l: 'shrunk', - b: 'shrunk', r: 'grew' - })) - .then(check('tilt x labels vertically', {'xaxis.tickangle': 90}, { - t: 'grew', l: 'shrunk', - b: '=', r: '=' - })) - .then(check('tilt y labels down 30 degrees', {'yaxis.tickangle': 30}, { - t: '=', l: '=', - b: 'grew', r: 'shrunk' - })) - .then(check('turn off automargin', {'xaxis.automargin': false, 'yaxis.automargin': false}, { - t: 'initial', l: 'initial', - b: 'initial', r: 'initial' - })) - .then(done, done.fail); + var gs = gd._fullLayout._size; + initialSize = Lib.extendDeep({}, gs); + previousSize = Lib.extendDeep({}, gs); + }) + .then(check('automargin y', { 'yaxis.automargin': true }, { + t: '=', l: 'grew', + b: '=', r: '=' + })) + .then(check('automargin x', { 'xaxis.automargin': true }, { + t: '=', l: '=', + b: 'grew', r: 'grew' + })) + .then(check('move all x label off-screen', { 'xaxis.range': [-10, -5] }, { + t: '=', l: '=', + b: 'initial', r: 'initial' + })) + .then(check('move all y label off-screen', { 'yaxis.range': [-10, -5] }, { + t: '=', l: 'initial', + b: '=', r: '=' + })) + .then(check('back to label for auto ranges', { 'xaxis.autorange': true, 'yaxis.autorange': true }, { + t: '=', l: 'grew', + b: 'grew', r: 'grew' + })) + .then(check('tilt x label to 45 degrees', { 'xaxis.tickangle': 45 }, { + t: '=', l: '=', + b: 'grew', r: 'shrunk' + })) + .then(check('tilt x labels back to 30 degrees', { 'xaxis.tickangle': 30 }, { + t: '=', l: '=', + b: 'shrunk', r: 'grew' + })) + .then(check('bump y-axis tick length', { 'yaxis.ticklen': 30 }, { + t: '=', l: 'grew', + b: '=', r: 'grew| as x ticks got shifted right' + })) + .then(check('add y-axis title', { 'yaxis.title.text': 'hello' }, { + t: '=', l: 'grew', + b: '=', r: 'grew| as x ticks got shifted right' + })) + .then(check('size up y-axis title', { 'yaxis.title.font.size': 30 }, { + t: '=', l: 'grew', + b: '=', r: 'grew| as x ticks got shifted right' + })) + .then(check('tilt y labels up 30 degrees', { 'yaxis.tickangle': 30 }, { + t: 'grew', l: 'shrunk', + b: '=', r: 'shrunk| as x ticks got shifted left' + })) + .then(check('un-tilt y labels', { 'yaxis.tickangle': null }, { + t: 'shrunk', l: 'grew', + b: '=', r: 'grew' + })) + .then(check('unanchor y-axis', { 'yaxis.anchor': 'free' }, { + t: '=', l: '~=', + b: '=', r: '=' + })) + .then(check('offset y-axis to the left', { 'yaxis.position': 0.1 }, { + t: '=', l: 'shrunk| as y-axis shifted right', + b: '=', r: 'shrunk| as y-axis shifted right' + })) + .then(check('re-anchor y-axis', { 'yaxis.anchor': 'x' }, { + t: '=', l: 'grew', + b: '=', r: 'grew' + })) + .then(check('flip axis side', { 'yaxis.side': 'right', 'xaxis.side': 'top' }, { + t: 'grew', l: 'shrunk', + b: 'shrunk', r: 'grew' + })) + .then(check('tilt x labels vertically', { 'xaxis.tickangle': 90 }, { + t: 'grew', l: 'shrunk', + b: '=', r: '=' + })) + .then(check('tilt y labels down 30 degrees', { 'yaxis.tickangle': 30 }, { + t: '=', l: '=', + b: 'grew', r: 'shrunk' + })) + .then(check('turn off automargin', { 'xaxis.automargin': false, 'yaxis.automargin': false }, { + t: 'initial', l: 'initial', + b: 'initial', r: 'initial' + })) + .then(done, done.fail); }); - it('should not lead to negative plot area heights', function(done) { + it('should not lead to negative plot area heights', function (done) { function _assert(msg, exp) { var gs = gd._fullLayout._size; expect(gs.h).toBeGreaterThan(0, msg + '- positive height'); @@ -4621,34 +4628,34 @@ describe('Test axes', function() { x: ['loooooong label 1', 'loooooong label 2'], y: [1, 2] }], { - xaxis: {automargin: true, tickangle: 90}, + xaxis: { automargin: true, tickangle: 90 }, width: 500, height: 500 }) - .then(function() { - _assert('base', { - bottomLowerBound: 80, - totalHeight: 500 - }); - }) - .then(function() { return Plotly.relayout(gd, 'height', 100); }) - .then(function() { - _assert('after relayout to *small* height', { - bottomLowerBound: 15, - totalHeight: 100 - }); - }) - .then(function() { return Plotly.relayout(gd, 'height', 800); }) - .then(function() { - _assert('after relayout to *big* height', { - bottomLowerBound: 80, - totalHeight: 800 - }); - }) - .then(done, done.fail); + .then(function () { + _assert('base', { + bottomLowerBound: 80, + totalHeight: 500 + }); + }) + .then(function () { return Plotly.relayout(gd, 'height', 100); }) + .then(function () { + _assert('after relayout to *small* height', { + bottomLowerBound: 15, + totalHeight: 100 + }); + }) + .then(function () { return Plotly.relayout(gd, 'height', 800); }) + .then(function () { + _assert('after relayout to *big* height', { + bottomLowerBound: 80, + totalHeight: 800 + }); + }) + .then(done, done.fail); }); - it('should not lead to negative plot area widths', function(done) { + it('should not lead to negative plot area widths', function (done) { function _assert(msg, exp) { var gs = gd._fullLayout._size; expect(gs.w).toBeGreaterThan(0, msg + '- positive width'); @@ -4660,38 +4667,38 @@ describe('Test axes', function() { y: ['loooooong label 1', 'loooooong label 2'], x: [1, 2] }], { - yaxis: {automargin: true}, + yaxis: { automargin: true }, width: 500, height: 500 }) - .then(function() { - _assert('base', { - leftLowerBound: 80, - totalWidth: 500 - }); - }) - .then(function() { return Plotly.relayout(gd, 'width', 100); }) - .then(function() { - _assert('after relayout to *small* width', { - leftLowerBound: 15, - totalWidth: 100 - }); - }) - .then(function() { return Plotly.relayout(gd, 'width', 1000); }) - .then(function() { - _assert('after relayout to *big* width', { - leftLowerBound: 80, - totalWidth: 1000 - }); - }) - .then(done, done.fail); + .then(function () { + _assert('base', { + leftLowerBound: 80, + totalWidth: 500 + }); + }) + .then(function () { return Plotly.relayout(gd, 'width', 100); }) + .then(function () { + _assert('after relayout to *small* width', { + leftLowerBound: 15, + totalWidth: 100 + }); + }) + .then(function () { return Plotly.relayout(gd, 'width', 1000); }) + .then(function () { + _assert('after relayout to *big* width', { + leftLowerBound: 80, + totalWidth: 1000 + }); + }) + .then(done, done.fail); }); - it('should handle partial automargin', function(done) { + it('should handle partial automargin', function (done) { var initialSize; function assertSize(msg, actual, exp) { - for(var k in exp) { + for (var k in exp) { var parts = exp[k].split('|'); var op = parts[0]; @@ -4706,9 +4713,9 @@ describe('Test axes', function() { var val = initialSize[k]; var msgk = msg + ' ' + k + (parts[1] ? ' |' + parts[1] : ''); var args = [val]; - if(op === '~=') { + if (op === '~=') { args.push(1.1); - } else if(method === 'toBeCloseTo') { + } else if (method === 'toBeCloseTo') { args.push(3); } args.push(msgk); @@ -4718,8 +4725,8 @@ describe('Test axes', function() { } function check(msg, relayoutObj, exp) { - return function() { - return Plotly.relayout(gd, relayoutObj).then(function() { + return function () { + return Plotly.relayout(gd, relayoutObj).then(function () { var gs = Lib.extendDeep({}, gd._fullLayout._size); assertSize(msg, gs, exp); }); @@ -4742,87 +4749,87 @@ describe('Test axes', function() { 'short label 5', 'loooooong label 5' ] }], { - margin: {l: 0, r: 0, b: 0, t: 0}, + margin: { l: 0, r: 0, b: 0, t: 0 }, width: 600, height: 600 }) - .then(function() { - expect(gd._fullLayout.xaxis._tickAngles.xtick).toBeCloseTo(30, 3); + .then(function () { + expect(gd._fullLayout.xaxis._tickAngles.xtick).toBeCloseTo(30, 3); - var gs = gd._fullLayout._size; - initialSize = Lib.extendDeep({}, gs); - }) - .then(check('automargin y', {'yaxis.automargin': true, 'yaxis.tickangle': 30, 'yaxis.ticklen': 30}, { - t: 'grew', l: 'grew', - b: '=', r: '=' - })) - .then(check('automargin not left', {'yaxis.automargin': 'right+height'}, { - t: 'grew', l: '=', - b: '=', r: '=' - })) - .then(check('automargin keep left height', {'yaxis.automargin': 'left+height'}, { - t: 'grew', l: 'grew', - b: '=', r: '=' - })) - .then(check('automargin keep bottom right', {'yaxis.automargin': 'bottom+right'}, { - t: '=', l: '=', - b: '=', r: '=' - })) - .then(check('automargin keep height', {'yaxis.automargin': 'height'}, { - t: 'grew', l: '=', - b: '=', r: '=' - })) - .then(check('automargin keep top', {'yaxis.automargin': 'top'}, { - t: 'grew', l: '=', - b: '=', r: '=' - })) - .then(check('automargin not top', {'yaxis.automargin': 'bottom+width'}, { - t: '=', l: 'grew', - b: '=', r: '=' - })) - .then(check('automargin keep left', {'yaxis.automargin': 'left'}, { - t: '=', l: 'grew', - b: '=', r: '=' - })) - .then(check('automargin keep width', {'yaxis.automargin': 'width'}, { - t: '=', l: 'grew', - b: '=', r: '=' - })) - .then(check('automargin x', {'xaxis.automargin': true, 'yaxis.automargin': false}, { - t: '=', l: '=', - b: 'grew', r: 'grew' - })) - .then(check('automargin not bottom', {'xaxis.automargin': 'top+width'}, { - t: '=', l: '=', - b: '=', r: 'grew' - })) - .then(check('automargin keep right', {'xaxis.automargin': 'right'}, { - t: '=', l: '=', - b: '=', r: 'grew' - })) - .then(check('automargin keep bottom', {'xaxis.automargin': 'bottom'}, { - t: '=', l: '=', - b: 'grew', r: '=' - })) - .then(check('automargin keep top right', {'xaxis.automargin': 'top+right'}, { - t: '=', l: '=', - b: '=', r: 'grew' - })) - .then(check('automargin keep top left', {'xaxis.automargin': 'top+left'}, { - t: '=', l: '=', - b: '=', r: '=' - })) - .then(check('automargin keep bottom left', {'xaxis.automargin': 'bottom+left'}, { - t: '=', l: '=', - b: 'grew', r: '=' - })) - .then(check('turn off automargin', {'xaxis.automargin': false, 'yaxis.automargin': false}, { - t: '=', l: '=', - b: '=', r: '=' - })) - .then(done, done.fail); + var gs = gd._fullLayout._size; + initialSize = Lib.extendDeep({}, gs); + }) + .then(check('automargin y', { 'yaxis.automargin': true, 'yaxis.tickangle': 30, 'yaxis.ticklen': 30 }, { + t: 'grew', l: 'grew', + b: '=', r: '=' + })) + .then(check('automargin not left', { 'yaxis.automargin': 'right+height' }, { + t: 'grew', l: '=', + b: '=', r: '=' + })) + .then(check('automargin keep left height', { 'yaxis.automargin': 'left+height' }, { + t: 'grew', l: 'grew', + b: '=', r: '=' + })) + .then(check('automargin keep bottom right', { 'yaxis.automargin': 'bottom+right' }, { + t: '=', l: '=', + b: '=', r: '=' + })) + .then(check('automargin keep height', { 'yaxis.automargin': 'height' }, { + t: 'grew', l: '=', + b: '=', r: '=' + })) + .then(check('automargin keep top', { 'yaxis.automargin': 'top' }, { + t: 'grew', l: '=', + b: '=', r: '=' + })) + .then(check('automargin not top', { 'yaxis.automargin': 'bottom+width' }, { + t: '=', l: 'grew', + b: '=', r: '=' + })) + .then(check('automargin keep left', { 'yaxis.automargin': 'left' }, { + t: '=', l: 'grew', + b: '=', r: '=' + })) + .then(check('automargin keep width', { 'yaxis.automargin': 'width' }, { + t: '=', l: 'grew', + b: '=', r: '=' + })) + .then(check('automargin x', { 'xaxis.automargin': true, 'yaxis.automargin': false }, { + t: '=', l: '=', + b: 'grew', r: 'grew' + })) + .then(check('automargin not bottom', { 'xaxis.automargin': 'top+width' }, { + t: '=', l: '=', + b: '=', r: 'grew' + })) + .then(check('automargin keep right', { 'xaxis.automargin': 'right' }, { + t: '=', l: '=', + b: '=', r: 'grew' + })) + .then(check('automargin keep bottom', { 'xaxis.automargin': 'bottom' }, { + t: '=', l: '=', + b: 'grew', r: '=' + })) + .then(check('automargin keep top right', { 'xaxis.automargin': 'top+right' }, { + t: '=', l: '=', + b: '=', r: 'grew' + })) + .then(check('automargin keep top left', { 'xaxis.automargin': 'top+left' }, { + t: '=', l: '=', + b: '=', r: '=' + })) + .then(check('automargin keep bottom left', { 'xaxis.automargin': 'bottom+left' }, { + t: '=', l: '=', + b: 'grew', r: '=' + })) + .then(check('turn off automargin', { 'xaxis.automargin': false, 'yaxis.automargin': false }, { + t: '=', l: '=', + b: '=', r: '=' + })) + .then(done, done.fail); }); - it('should handle cases with free+mirror axes', function(done) { + it('should handle cases with free+mirror axes', function (done) { Plotly.newPlot(gd, [{ y: [1, 2, 1] }], { @@ -4840,14 +4847,14 @@ describe('Test axes', function() { automargin: true } }) - .then(function() { - // N.B. no '.automargin.mirror' - expect(Object.keys(gd._fullLayout._pushmargin)) - .toEqual(['x.automargin', 'y.automargin', 'base']); - }) - .then(done, done.fail); + .then(function () { + // N.B. no '.automargin.mirror' + expect(Object.keys(gd._fullLayout._pushmargin)) + .toEqual(['x.automargin', 'y.automargin', 'base']); + }) + .then(done, done.fail); }); - it('should respect axis title placement on relayout', function(done) { + it('should respect axis title placement on relayout', function (done) { function getPos(gd, sel) { return d3Select(gd).select(sel).node().getBoundingClientRect(); } @@ -4863,20 +4870,20 @@ describe('Test axes', function() { var fig = require('../../image/mocks/automargin-zoom.json'); Plotly.newPlot(gd, fig) - .then(assertLayout) - .then(function() { - return Plotly.relayout(gd, {'xaxis.range': [6, 14]}); - }) - .then(function() { - assertLayout(); - }) - .then(done, done.fail); + .then(assertLayout) + .then(function () { + return Plotly.relayout(gd, { 'xaxis.range': [6, 14] }); + }) + .then(function () { + assertLayout(); + }) + .then(done, done.fail); }); }); - describe('zeroline visibility logic', function() { + describe('zeroline visibility logic', function () { var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); afterEach(destroyGraphDiv); @@ -4884,7 +4891,7 @@ describe('Test axes', function() { function assertZeroLines(expectedIDs) { var sortedIDs = expectedIDs.slice().sort(); var zlIDs = []; - d3Select(gd).selectAll('.zl').each(function() { + d3Select(gd).selectAll('.zl').each(function () { var cls = d3Select(this).attr('class'); var clsMatch = cls.match(/[xy]\d*(?=zl)/g)[0]; zlIDs.push(clsMatch); @@ -4893,150 +4900,150 @@ describe('Test axes', function() { expect(zlIDs).toEqual(sortedIDs); } - it('works with a single subplot', function(done) { - Plotly.newPlot(gd, [{x: [1, 2, 3], y: [1, 2, 3]}], { - xaxis: {range: [0, 4], zeroline: true, showline: true}, - yaxis: {range: [0, 4], zeroline: true, showline: true}, + it('works with a single subplot', function (done) { + Plotly.newPlot(gd, [{ x: [1, 2, 3], y: [1, 2, 3] }], { + xaxis: { range: [0, 4], zeroline: true, showline: true }, + yaxis: { range: [0, 4], zeroline: true, showline: true }, width: 600, height: 600 }) - .then(function() { - assertZeroLines([]); - return Plotly.relayout(gd, {'xaxis.showline': false}); - }) - .then(function() { - assertZeroLines(['y']); - return Plotly.relayout(gd, {'xaxis.showline': true, 'yaxis.showline': false}); - }) - .then(function() { - assertZeroLines(['x']); - return Plotly.relayout(gd, {'yaxis.showline': true, 'yaxis.range': [4, 0]}); - }) - .then(function() { - assertZeroLines(['y']); - return Plotly.relayout(gd, {'xaxis.range': [4, 0], 'xaxis.side': 'top'}); - }) - .then(function() { - assertZeroLines(['x']); - return Plotly.relayout(gd, {'yaxis.side': 'right', 'xaxis.anchor': 'free', 'xaxis.position': 1}); - }) - .then(function() { - assertZeroLines([]); - return Plotly.relayout(gd, {'xaxis.range': [0, 4], 'yaxis.range': [0, 4]}); - }) - .then(function() { - assertZeroLines(['x', 'y']); - return Plotly.relayout(gd, {'xaxis.mirror': 'all', 'yaxis.mirror': true}); - }) - .then(function() { - assertZeroLines([]); - return Plotly.relayout(gd, {'xaxis.range': [-0.1, 4], 'yaxis.range': [-0.1, 4]}); - }) - .then(function() { - assertZeroLines(['x', 'y']); - return Plotly.relayout(gd, { - 'xaxis.showline': false, 'xaxis.nticks': 1, 'xaxis.range': [0, 0.1], - 'yaxis.showline': false, 'yaxis.nticks': 2, 'yaxis.range': [0, 0.1] - }); - }) - .then(function() { - // no grid lines, but still should show zeroline in this case - // see https://github.com/plotly/plotly.js/issues/4027 - expect(gd._fullLayout.xaxis._gridVals.length).toBe(0, '# of grid lines'); - expect(gd._fullLayout.xaxis._gridVals.length).toBe(0, '# of grid lines'); - assertZeroLines(['x', 'y']); - }) - .then(done, done.fail); + .then(function () { + assertZeroLines([]); + return Plotly.relayout(gd, { 'xaxis.showline': false }); + }) + .then(function () { + assertZeroLines(['y']); + return Plotly.relayout(gd, { 'xaxis.showline': true, 'yaxis.showline': false }); + }) + .then(function () { + assertZeroLines(['x']); + return Plotly.relayout(gd, { 'yaxis.showline': true, 'yaxis.range': [4, 0] }); + }) + .then(function () { + assertZeroLines(['y']); + return Plotly.relayout(gd, { 'xaxis.range': [4, 0], 'xaxis.side': 'top' }); + }) + .then(function () { + assertZeroLines(['x']); + return Plotly.relayout(gd, { 'yaxis.side': 'right', 'xaxis.anchor': 'free', 'xaxis.position': 1 }); + }) + .then(function () { + assertZeroLines([]); + return Plotly.relayout(gd, { 'xaxis.range': [0, 4], 'yaxis.range': [0, 4] }); + }) + .then(function () { + assertZeroLines(['x', 'y']); + return Plotly.relayout(gd, { 'xaxis.mirror': 'all', 'yaxis.mirror': true }); + }) + .then(function () { + assertZeroLines([]); + return Plotly.relayout(gd, { 'xaxis.range': [-0.1, 4], 'yaxis.range': [-0.1, 4] }); + }) + .then(function () { + assertZeroLines(['x', 'y']); + return Plotly.relayout(gd, { + 'xaxis.showline': false, 'xaxis.nticks': 1, 'xaxis.range': [0, 0.1], + 'yaxis.showline': false, 'yaxis.nticks': 2, 'yaxis.range': [0, 0.1] + }); + }) + .then(function () { + // no grid lines, but still should show zeroline in this case + // see https://github.com/plotly/plotly.js/issues/4027 + expect(gd._fullLayout.xaxis._gridVals.length).toBe(0, '# of grid lines'); + expect(gd._fullLayout.xaxis._gridVals.length).toBe(0, '# of grid lines'); + assertZeroLines(['x', 'y']); + }) + .then(done, done.fail); }); - it('works with multiple coupled subplots', function(done) { + it('works with multiple coupled subplots', function (done) { Plotly.newPlot(gd, [ - {x: [1, 2, 3], y: [1, 2, 3]}, - {x: [1, 2, 3], y: [1, 2, 3], xaxis: 'x2'}, - {x: [1, 2, 3], y: [1, 2, 3], yaxis: 'y2'} + { x: [1, 2, 3], y: [1, 2, 3] }, + { x: [1, 2, 3], y: [1, 2, 3], xaxis: 'x2' }, + { x: [1, 2, 3], y: [1, 2, 3], yaxis: 'y2' } ], { - xaxis: {range: [0, 4], zeroline: true, domain: [0, 0.4]}, - yaxis: {range: [0, 4], zeroline: true, domain: [0, 0.4]}, - xaxis2: {range: [0, 4], zeroline: true, domain: [0.6, 1]}, - yaxis2: {range: [0, 4], zeroline: true, domain: [0.6, 1]}, + xaxis: { range: [0, 4], zeroline: true, domain: [0, 0.4] }, + yaxis: { range: [0, 4], zeroline: true, domain: [0, 0.4] }, + xaxis2: { range: [0, 4], zeroline: true, domain: [0.6, 1] }, + yaxis2: { range: [0, 4], zeroline: true, domain: [0.6, 1] }, width: 600, height: 600 }) - .then(function() { - assertZeroLines(['x', 'x', 'y', 'y', 'x2', 'y2']); - return Plotly.relayout(gd, {'xaxis.showline': true, 'xaxis.mirror': 'all'}); - }) - .then(function() { - assertZeroLines(['x', 'x', 'y', 'x2']); - return Plotly.relayout(gd, {'yaxis.showline': true, 'yaxis.mirror': 'all'}); - }) - .then(function() { - // x axis still has a zero line on xy2, and y on x2y - // all the others have disappeared now - assertZeroLines(['x', 'y']); - return Plotly.relayout(gd, {'xaxis.mirror': 'allticks', 'yaxis.mirror': 'allticks'}); - }) - .then(function() { - // allticks works the same as all - assertZeroLines(['x', 'y']); - }) - .then(done, done.fail); + .then(function () { + assertZeroLines(['x', 'x', 'y', 'y', 'x2', 'y2']); + return Plotly.relayout(gd, { 'xaxis.showline': true, 'xaxis.mirror': 'all' }); + }) + .then(function () { + assertZeroLines(['x', 'x', 'y', 'x2']); + return Plotly.relayout(gd, { 'yaxis.showline': true, 'yaxis.mirror': 'all' }); + }) + .then(function () { + // x axis still has a zero line on xy2, and y on x2y + // all the others have disappeared now + assertZeroLines(['x', 'y']); + return Plotly.relayout(gd, { 'xaxis.mirror': 'allticks', 'yaxis.mirror': 'allticks' }); + }) + .then(function () { + // allticks works the same as all + assertZeroLines(['x', 'y']); + }) + .then(done, done.fail); }); - it('works with multiple overlaid subplots', function(done) { + it('works with multiple overlaid subplots', function (done) { Plotly.newPlot(gd, [ - {x: [1, 2, 3], y: [1, 2, 3]}, - {x: [1, 2, 3], y: [1, 2, 3], xaxis: 'x2', yaxis: 'y2'} + { x: [1, 2, 3], y: [1, 2, 3] }, + { x: [1, 2, 3], y: [1, 2, 3], xaxis: 'x2', yaxis: 'y2' } ], { - xaxis: {range: [0, 4], zeroline: true}, - yaxis: {range: [0, 4], zeroline: true}, - xaxis2: {range: [0, 4], zeroline: true, side: 'top', overlaying: 'x'}, - yaxis2: {range: [0, 4], zeroline: true, side: 'right', overlaying: 'y'}, + xaxis: { range: [0, 4], zeroline: true }, + yaxis: { range: [0, 4], zeroline: true }, + xaxis2: { range: [0, 4], zeroline: true, side: 'top', overlaying: 'x' }, + yaxis2: { range: [0, 4], zeroline: true, side: 'right', overlaying: 'y' }, width: 600, height: 600 }) - .then(function() { - assertZeroLines(['x', 'y', 'x2', 'y2']); - return Plotly.relayout(gd, {'xaxis.showline': true, 'yaxis.showline': true}); - }) - .then(function() { - assertZeroLines([]); - return Plotly.relayout(gd, { - 'xaxis.range': [4, 0], - 'yaxis.range': [4, 0], - 'xaxis2.range': [4, 0], - 'yaxis2.range': [4, 0] - }); - }) - .then(function() { - assertZeroLines(['x', 'y', 'x2', 'y2']); - return Plotly.relayout(gd, { - 'xaxis.showline': false, - 'yaxis.showline': false, - 'xaxis2.showline': true, - 'yaxis2.showline': true - }); - }) - .then(function() { - assertZeroLines([]); - }) - .then(done, done.fail); + .then(function () { + assertZeroLines(['x', 'y', 'x2', 'y2']); + return Plotly.relayout(gd, { 'xaxis.showline': true, 'yaxis.showline': true }); + }) + .then(function () { + assertZeroLines([]); + return Plotly.relayout(gd, { + 'xaxis.range': [4, 0], + 'yaxis.range': [4, 0], + 'xaxis2.range': [4, 0], + 'yaxis2.range': [4, 0] + }); + }) + .then(function () { + assertZeroLines(['x', 'y', 'x2', 'y2']); + return Plotly.relayout(gd, { + 'xaxis.showline': false, + 'yaxis.showline': false, + 'xaxis2.showline': true, + 'yaxis2.showline': true + }); + }) + .then(function () { + assertZeroLines([]); + }) + .then(done, done.fail); }); }); - describe('*tickson*:', function() { + describe('*tickson*:', function () { var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); afterEach(destroyGraphDiv); - it('should respond to relayout', function(done) { + it('should respond to relayout', function (done) { function getPositions(query) { var pos = []; - d3SelectAll(query).each(function() { + d3SelectAll(query).each(function () { pos.push(this.getBoundingClientRect().x); }); return pos; @@ -5050,7 +5057,7 @@ describe('Test axes', function() { expect(ticks).toBeCloseToArray(exp.ticks, 1, msg + '- ticks'); expect(gridLines).toBeCloseToArray(exp.gridLines, 1, msg + '- grid lines'); expect(tickLabels.length).toBe(exp.tickLabels.length, msg + '- # of tick labels'); - tickLabels.forEach(function(tl, i) { + tickLabels.forEach(function (tl, i) { expect(tl).toBeWithin(exp.tickLabels[i], 2, msg + '- tick label ' + i); }); } @@ -5064,47 +5071,47 @@ describe('Test axes', function() { showgrid: true } }) - .then(function() { - _assert('on labels (defaults)', { - ticks: [110.75, 350, 589.25], - gridLines: [110.75, 350, 589.25], - tickLabels: [106.421, 345.671, 585.25] - }); - return Plotly.relayout(gd, 'xaxis.tickson', 'boundaries'); - }) - .then(function() { - _assert('inside on boundaries', { - ticks: [230.369, 469.619], // N.B. first and last tick are clipped - gridLines: [230.369, 469.619], - tickLabels: [106.421875, 345.671875, 585.25] - }); - return Plotly.relayout(gd, 'xaxis.ticks', 'outside'); - }) - .then(function() { - _assert('outside on boundaries', { - ticks: [230.369, 469.619], - gridLines: [230.369, 469.619], - tickLabels: [106.421875, 345.671875, 585.25] - }); - return Plotly.restyle(gd, 'x', [[1, 2, 1]]); - }) - .then(function() { - _assert('fallback to *labels* on non-category axes', { - ticks: [110.75, 206.449, 302.149, 397.85, 493.549, 589.25], - gridLines: [110.75, 206.449, 302.149, 397.85, 493.549, 589.25], - tickLabels: [106.421, 197.121, 292.821, 388.521, 484.221, 584.921] - }); - }) - .then(done, done.fail); + .then(function () { + _assert('on labels (defaults)', { + ticks: [110.75, 350, 589.25], + gridLines: [110.75, 350, 589.25], + tickLabels: [106.421, 345.671, 585.25] + }); + return Plotly.relayout(gd, 'xaxis.tickson', 'boundaries'); + }) + .then(function () { + _assert('inside on boundaries', { + ticks: [230.369, 469.619], // N.B. first and last tick are clipped + gridLines: [230.369, 469.619], + tickLabels: [106.421875, 345.671875, 585.25] + }); + return Plotly.relayout(gd, 'xaxis.ticks', 'outside'); + }) + .then(function () { + _assert('outside on boundaries', { + ticks: [230.369, 469.619], + gridLines: [230.369, 469.619], + tickLabels: [106.421875, 345.671875, 585.25] + }); + return Plotly.restyle(gd, 'x', [[1, 2, 1]]); + }) + .then(function () { + _assert('fallback to *labels* on non-category axes', { + ticks: [110.75, 206.449, 302.149, 397.85, 493.549, 589.25], + gridLines: [110.75, 206.449, 302.149, 397.85, 493.549, 589.25], + tickLabels: [106.421, 197.121, 292.821, 388.521, 484.221, 584.921] + }); + }) + .then(done, done.fail); }); - it('should rotate labels to avoid overlaps', function(done) { + it('should rotate labels to avoid overlaps', function (done) { function _assert(msg, exp) { var tickLabels = d3SelectAll('.xtick > text'); expect(tickLabels.size()).withContext(msg + ' - # of tick labels').toBe(exp.angle.length); - tickLabels.each(function(_, i) { + tickLabels.each(function (_, i) { var t = d3Select(this).attr('transform'); var rotate = (t.split('rotate(')[1] || '').split(')')[0]; var angle = rotate.split(',')[0]; @@ -5124,46 +5131,46 @@ describe('Test axes', function() { width: 500, height: 500 }) - .then(function() { - _assert('base - rotated', { - angle: [30, 30, 30] - }); + .then(function () { + _assert('base - rotated', { + angle: [30, 30, 30] + }); - return Plotly.relayout(gd, 'xaxis.range', [-0.4, 1.4]); - }) - .then(function() { - _assert('narrower range - unrotated', { - angle: [0, 0] - }); + return Plotly.relayout(gd, 'xaxis.range', [-0.4, 1.4]); + }) + .then(function () { + _assert('narrower range - unrotated', { + angle: [0, 0] + }); - return Plotly.relayout(gd, 'xaxis.tickwidth', 30); - }) - .then(function() { - _assert('narrow range / wide ticks - rotated', { - angle: [30, 30] - }); - }) - .then(done, done.fail); + return Plotly.relayout(gd, 'xaxis.tickwidth', 30); + }) + .then(function () { + _assert('narrow range / wide ticks - rotated', { + angle: [30, 30] + }); + }) + .then(done, done.fail); }); }); - describe('*rangebreaks*', function() { - describe('during doCalcdata', function() { + describe('*rangebreaks*', function () { + describe('during doCalcdata', function () { var gd; function _calc(trace, layout) { - gd = {data: [trace], layout: layout}; + gd = { data: [trace], layout: layout }; supplyDefaults(gd); Plots.doCalcdata(gd); } function _assert(msg, exp) { var cd = gd.calcdata[0]; - var xc = cd.map(function(cdi) { return cdi.x; }); + var xc = cd.map(function (cdi) { return cdi.x; }); expect(xc).withContext(msg).toEqual(exp); } - it('should discard coords within break bounds', function() { + it('should discard coords within break bounds', function () { var x = [ '1970-01-01 00:00:00.000', '1970-01-01 00:00:00.010', @@ -5180,21 +5187,25 @@ describe('Test axes', function() { }, { xaxis: { rangebreaks: [ - {bounds: [ - '1970-01-01 00:00:00.010', - '1970-01-01 00:00:00.090' - ]}, - {bounds: [ - '1970-01-01 00:00:00.100', - '1970-01-01 00:00:00.190' - ]} + { + bounds: [ + '1970-01-01 00:00:00.010', + '1970-01-01 00:00:00.090' + ] + }, + { + bounds: [ + '1970-01-01 00:00:00.100', + '1970-01-01 00:00:00.190' + ] + } ] } }); _assert('', [0, BADNUM, BADNUM, 90, BADNUM, BADNUM, 190, 200]); }); - it('should discard coords within break bounds - date day of week case', function() { + it('should discard coords within break bounds - date day of week case', function () { var x = [ // Thursday '2020-01-02 08:00', '2020-01-02 16:00', @@ -5219,17 +5230,17 @@ describe('Test axes', function() { 1578384000000, 1578412800000 ]; - _calc({x: x}, { + _calc({ x: x }, { xaxis: { rangebreaks: [ - {pattern: 'day of week', bounds: [6, 1]} + { pattern: 'day of week', bounds: [6, 1] } ] } }); _assert('[6,1]', noWeekend); }); - it('should discard coords within break bounds - date hour case', function() { + it('should discard coords within break bounds - date hour case', function () { _calc({ x: [ '2020-01-02 08:00', '2020-01-02 20:00', @@ -5242,7 +5253,7 @@ describe('Test axes', function() { }, { xaxis: { rangebreaks: [ - {pattern: 'hour', bounds: [17, 8]} + { pattern: 'hour', bounds: [17, 8] } ] } }); @@ -5256,7 +5267,7 @@ describe('Test axes', function() { ]); }); - it('should discard coords within break bounds - date hour / high precision case', function() { + it('should discard coords within break bounds - date hour / high precision case', function () { _calc({ x: [ '2020-01-03 16:45', @@ -5271,7 +5282,7 @@ describe('Test axes', function() { }, { xaxis: { rangebreaks: [ - {pattern: 'hour', bounds: [17, 8]} + { pattern: 'hour', bounds: [17, 8] } ] } }); @@ -5287,7 +5298,7 @@ describe('Test axes', function() { ]); }); - it('should discard coords within break bounds - date hour case of [23, 1]', function() { + it('should discard coords within break bounds - date hour case of [23, 1]', function () { _calc({ x: [ '2020-01-01 22', @@ -5306,7 +5317,7 @@ describe('Test axes', function() { }, { xaxis: { rangebreaks: [ - {pattern: 'hour', bounds: [23, 1]} + { pattern: 'hour', bounds: [23, 1] } ] } }); @@ -5326,7 +5337,7 @@ describe('Test axes', function() { ]); }); - it('should discard coords within break bounds - date hour case of [23, 0]', function() { + it('should discard coords within break bounds - date hour case of [23, 0]', function () { _calc({ x: [ '2020-01-01 22', @@ -5345,7 +5356,7 @@ describe('Test axes', function() { }, { xaxis: { rangebreaks: [ - {pattern: 'hour', bounds: [23, 0]} + { pattern: 'hour', bounds: [23, 0] } ] } }); @@ -5365,7 +5376,7 @@ describe('Test axes', function() { ]); }); - it('should discard coords within break bounds - date hour case of [23, 24]', function() { + it('should discard coords within break bounds - date hour case of [23, 24]', function () { _calc({ x: [ '2020-01-01 22', @@ -5384,7 +5395,7 @@ describe('Test axes', function() { }, { xaxis: { rangebreaks: [ - {pattern: 'hour', bounds: [23, 24]} + { pattern: 'hour', bounds: [23, 24] } ] } }); @@ -5404,7 +5415,7 @@ describe('Test axes', function() { ]); }); - it('should discard coords within break bounds - date hour case of [23.75, 0.25]', function() { + it('should discard coords within break bounds - date hour case of [23.75, 0.25]', function () { _calc({ x: [ '2020-01-01 22', @@ -5423,7 +5434,7 @@ describe('Test axes', function() { }, { xaxis: { rangebreaks: [ - {pattern: 'hour', bounds: [23.75, 0.25]} + { pattern: 'hour', bounds: [23.75, 0.25] } ] } }); @@ -5443,7 +5454,7 @@ describe('Test axes', function() { ]); }); - it('should discard coords within [values[i], values[i] + dvalue] bounds', function() { + it('should discard coords within [values[i], values[i] + dvalue] bounds', function () { var x = [ // Thursday '2020-01-02 08:00', '2020-01-02 16:00', @@ -5459,9 +5470,9 @@ describe('Test axes', function() { '2020-01-07 08:00', '2020-01-07 16:00' ]; - _calc({x: x}, { + _calc({ x: x }, { xaxis: { - rangebreaks: [{values: ['2020-01-04', '2020-01-05'], dvalue: ONEDAY}], + rangebreaks: [{ values: ['2020-01-04', '2020-01-05'], dvalue: ONEDAY }], } }); _assert('two values', [ @@ -5474,7 +5485,7 @@ describe('Test axes', function() { ]); }); - it('should discard coords equal to two consecutive open values bounds', function() { + it('should discard coords equal to two consecutive open values bounds', function () { _calc({ x: [ '1970-01-01 00:00:00.001', @@ -5485,16 +5496,18 @@ describe('Test axes', function() { ] }, { xaxis: { - rangebreaks: [{ values: [ - '1970-01-01 00:00:00.002', - '1970-01-01 00:00:00.003' - ], dvalue: 1 }] + rangebreaks: [{ + values: [ + '1970-01-01 00:00:00.002', + '1970-01-01 00:00:00.003' + ], dvalue: 1 + }] } }); _assert('', [1, BADNUM, BADNUM, 4, 5]); }); - it('should adapt coords generated from x0/dx about rangebreaks', function() { + it('should adapt coords generated from x0/dx about rangebreaks', function () { _calc({ x0: '1970-01-01 00:00:00.001', dx: 0.5, @@ -5502,10 +5515,12 @@ describe('Test axes', function() { }, { xaxis: { rangebreaks: [ - {bounds: [ - '1970-01-01 00:00:00.002', - '1970-01-01 00:00:00.003' - ]} + { + bounds: [ + '1970-01-01 00:00:00.002', + '1970-01-01 00:00:00.003' + ] + } ] } }); @@ -5513,10 +5528,10 @@ describe('Test axes', function() { }); }); - describe('during doAutorange', function() { + describe('during doAutorange', function () { var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); @@ -5527,7 +5542,7 @@ describe('Test axes', function() { expect(gd._fullLayout.xaxis._lBreaks).toBe(exp.lBreaks, msg + '| lBreaks'); } - it('should adapt padding about axis rangebreaks length', function(done) { + it('should adapt padding about axis rangebreaks length', function (done) { Plotly.newPlot(gd, [{ mode: 'markers', x: [ @@ -5543,62 +5558,66 @@ describe('Test axes', function() { }], { xaxis: { rangebreaks: [ - {bounds: [ - '1970-01-01 00:00:00.011', - '1970-01-01 00:00:00.089' - ]}, - {bounds: [ - '1970-01-01 00:00:00.101', - '1970-01-01 00:00:00.189' - ]} + { + bounds: [ + '1970-01-01 00:00:00.011', + '1970-01-01 00:00:00.089' + ] + }, + { + bounds: [ + '1970-01-01 00:00:00.101', + '1970-01-01 00:00:00.189' + ] + } ] } }) - .then(function() { - _assert('mode:markers (i.e. with padding)', { - xrng: ['1969-12-31 23:59:59.9978', '1970-01-01 00:00:00.2022'], - lBreaks: 166 - }); - }) - .then(function() { - gd.data[0].mode = 'lines'; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('mode:lines (i.e. no padding)', { - xrng: ['1970-01-01', '1970-01-01 00:00:00.2'], - lBreaks: 166 - }); - }) - .then(function() { - gd.data[0].mode = 'markers'; - gd.layout.xaxis.rangebreaks[0].enabled = false; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('mode:markers | one of two rangebreaks enabled', { - xrng: ['1969-12-31 23:59:59.9928', '1970-01-01 00:00:00.2072'], - lBreaks: 88 - }); - }) - .then(function() { - gd.layout.xaxis.rangebreaks[1].enabled = false; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('mode:markers | no rangebreaks enabled', { - xrng: ['1969-12-31 23:59:59.9871', '1970-01-01 00:00:00.2129'], - lBreaks: 0 - }); - }) - .then(done, done.fail); + .then(function () { + _assert('mode:markers (i.e. with padding)', { + xrng: ['1969-12-31 23:59:59.9978', '1970-01-01 00:00:00.2022'], + lBreaks: 166 + }); + }) + .then(function () { + gd.data[0].mode = 'lines'; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('mode:lines (i.e. no padding)', { + xrng: ['1970-01-01', '1970-01-01 00:00:00.2'], + lBreaks: 166 + }); + }) + .then(function () { + gd.data[0].mode = 'markers'; + gd.layout.xaxis.rangebreaks[0].enabled = false; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('mode:markers | one of two rangebreaks enabled', { + xrng: ['1969-12-31 23:59:59.9928', '1970-01-01 00:00:00.2072'], + lBreaks: 88 + }); + }) + .then(function () { + gd.layout.xaxis.rangebreaks[1].enabled = false; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('mode:markers | no rangebreaks enabled', { + xrng: ['1969-12-31 23:59:59.9871', '1970-01-01 00:00:00.2129'], + lBreaks: 0 + }); + }) + .then(done, done.fail); }); }); - describe('during setConvert (once range is available)', function() { + describe('during setConvert (once range is available)', function () { var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); @@ -5608,10 +5627,10 @@ describe('Test axes', function() { var fullLayout = gd._fullLayout; var ax = fullLayout[axLetter + 'axis']; - if(exp) { + if (exp) { expect(ax._rangebreaks.length) .toBe(exp.rangebreaks.length, msg + '| correct # of rangebreaks'); - expect(ax._rangebreaks.map(function(brk) { return [brk.min, brk.max]; })) + expect(ax._rangebreaks.map(function (brk) { return [brk.min, brk.max]; })) .toBeCloseTo2DArray(exp.rangebreaks, 2, msg + '| rangebreaks [min,max]'); expect(ax._m2).toBe(exp.m2, msg + '| l2p slope'); @@ -5623,7 +5642,7 @@ describe('Test axes', function() { } } - it('should locate rangebreaks & compute l <-> p parameters - x-axis case', function(done) { + it('should locate rangebreaks & compute l <-> p parameters - x-axis case', function (done) { Plotly.newPlot(gd, [{ x: [ '1970-01-01 00:00:00.000', @@ -5638,113 +5657,133 @@ describe('Test axes', function() { }], { xaxis: {} }) - .then(function() { - _assert('no set rangebreaks', 'x', null); - }) - .then(function() { - gd.layout.xaxis.rangebreaks = [ - {bounds: [ - '1970-01-01 00:00:00.011', - '1970-01-01 00:00:00.089' - ]}, - {bounds: [ - '1970-01-01 00:00:00.101', - '1970-01-01 00:00:00.189' - ]} - ]; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('2 disjoint rangebreaks within range', 'x', { - rangebreaks: [[11, 89], [101, 189]], - m2: 14.062499999998405, - B: [30.937, -1065.937, -2303.437] - }); - }) - .then(function() { - gd.layout.xaxis.rangebreaks = [ - {bounds: [ - '1970-01-01 00:00:00.011', - '1970-01-01 00:00:00.089' - ]}, - {bounds: [ - '1970-01-01 00:00:00.070', - '1970-01-01 00:00:00.189' - ]} - ]; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('2 overlapping rangebreaks within range', 'x', { - rangebreaks: [[11, 189]], - m2: 21.7741935483922, - B: [30.483, -3845.322] - }); - }) - .then(function() { - gd.layout.xaxis.rangebreaks = [ - {bounds: [ - '1969-12-31 23:59:59.990', - '1970-01-01 00:00:00.089' - ]}, - {bounds: [ - '1970-01-01 00:00:00.101', - '1970-01-01 00:00:00.189' - ]} - ]; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('break beyond xaxis.range[0]', 'x', { - rangebreaks: [[88.6, 89], [101, 189]], - m2: 22.1311475409836, - B: [-1960.819, -1969.672, -3917.213] - }); - }) - .then(function() { - gd.layout.xaxis.rangebreaks = [ - {bounds: [ - '1970-01-01 00:00:00.011', - '1970-01-01 00:00:00.089' - ]}, - {bounds: [ - '1970-01-01 00:00:00.101', - '1970-01-01 00:00:00.300' - ]} - ]; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('break beyond xaxis.range[1]', 'x', { - rangebreaks: [[11, 89], [101, 101.4]], - m2: 22.131147540988888, - B: [30.983, -1695.245, -1704.098] - }); - }) - .then(function() { - gd.layout.xaxis.rangebreaks = [ - {bounds: [ - '1969-12-31 23:59:59.989', - '1970-01-01 00:00:00.090' - ]}, - {bounds: [ - '1970-01-01 00:00:00.101', - '1970-01-01 00:00:00.300' - ]} - ]; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('both rangebreaks beyond xaxis.range', 'x', { - rangebreaks: [[89.4, 90]], - m2: 50.943396226415125, - B: [-4554.339622641512, -4584.9056603773615] - }); - }) - .then(done, done.fail); + .then(function () { + _assert('no set rangebreaks', 'x', null); + }) + .then(function () { + gd.layout.xaxis.rangebreaks = [ + { + bounds: [ + '1970-01-01 00:00:00.011', + '1970-01-01 00:00:00.089' + ] + }, + { + bounds: [ + '1970-01-01 00:00:00.101', + '1970-01-01 00:00:00.189' + ] + } + ]; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('2 disjoint rangebreaks within range', 'x', { + rangebreaks: [[11, 89], [101, 189]], + m2: 14.062499999998405, + B: [30.937, -1065.937, -2303.437] + }); + }) + .then(function () { + gd.layout.xaxis.rangebreaks = [ + { + bounds: [ + '1970-01-01 00:00:00.011', + '1970-01-01 00:00:00.089' + ] + }, + { + bounds: [ + '1970-01-01 00:00:00.070', + '1970-01-01 00:00:00.189' + ] + } + ]; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('2 overlapping rangebreaks within range', 'x', { + rangebreaks: [[11, 189]], + m2: 21.7741935483922, + B: [30.483, -3845.322] + }); + }) + .then(function () { + gd.layout.xaxis.rangebreaks = [ + { + bounds: [ + '1969-12-31 23:59:59.990', + '1970-01-01 00:00:00.089' + ] + }, + { + bounds: [ + '1970-01-01 00:00:00.101', + '1970-01-01 00:00:00.189' + ] + } + ]; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('break beyond xaxis.range[0]', 'x', { + rangebreaks: [[88.6, 89], [101, 189]], + m2: 22.1311475409836, + B: [-1960.819, -1969.672, -3917.213] + }); + }) + .then(function () { + gd.layout.xaxis.rangebreaks = [ + { + bounds: [ + '1970-01-01 00:00:00.011', + '1970-01-01 00:00:00.089' + ] + }, + { + bounds: [ + '1970-01-01 00:00:00.101', + '1970-01-01 00:00:00.300' + ] + } + ]; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('break beyond xaxis.range[1]', 'x', { + rangebreaks: [[11, 89], [101, 101.4]], + m2: 22.131147540988888, + B: [30.983, -1695.245, -1704.098] + }); + }) + .then(function () { + gd.layout.xaxis.rangebreaks = [ + { + bounds: [ + '1969-12-31 23:59:59.989', + '1970-01-01 00:00:00.090' + ] + }, + { + bounds: [ + '1970-01-01 00:00:00.101', + '1970-01-01 00:00:00.300' + ] + } + ]; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('both rangebreaks beyond xaxis.range', 'x', { + rangebreaks: [[89.4, 90]], + m2: 50.943396226415125, + B: [-4554.339622641512, -4584.9056603773615] + }); + }) + .then(done, done.fail); }); - it('should locate rangebreaks & compute l <-> p parameters - y-axis case', function(done) { + it('should locate rangebreaks & compute l <-> p parameters - y-axis case', function (done) { Plotly.newPlot(gd, [{ y: [ '1970-01-01 00:00:00.000', @@ -5759,53 +5798,61 @@ describe('Test axes', function() { }], { yaxis: {} }) - .then(function() { - _assert('no set rangebreaks', 'y', null); - }) - .then(function() { - gd.layout.yaxis.rangebreaks = [ - {bounds: [ - '1970-01-01 00:00:00.011', - '1970-01-01 00:00:00.089' - ]}, - {bounds: [ - '1970-01-01 00:00:00.101', - '1970-01-01 00:00:00.189' - ]} - ]; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('2 disjoint rangebreaks within range', 'y', { - rangebreaks: [[101, 189], [11, 89]], - m2: -6.923076923076923, - B: [1401.923, 792.692, 252.692] - }); - }) - .then(function() { - gd.layout.yaxis.rangebreaks = [ - {bounds: [ - '1970-01-01 00:00:00.011', - '1970-01-01 00:00:00.089' - ]}, - {bounds: [ - '1970-01-01 00:00:00.070', - '1970-01-01 00:00:00.189' - ]} - ]; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('2 overlapping rangebreaks within range', 'y', { - rangebreaks: [[11, 189]], - m2: -10.714285714283243, - B: [2160, 252.857] - }); - }) - .then(done, done.fail); + .then(function () { + _assert('no set rangebreaks', 'y', null); + }) + .then(function () { + gd.layout.yaxis.rangebreaks = [ + { + bounds: [ + '1970-01-01 00:00:00.011', + '1970-01-01 00:00:00.089' + ] + }, + { + bounds: [ + '1970-01-01 00:00:00.101', + '1970-01-01 00:00:00.189' + ] + } + ]; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('2 disjoint rangebreaks within range', 'y', { + rangebreaks: [[101, 189], [11, 89]], + m2: -6.923076923076923, + B: [1401.923, 792.692, 252.692] + }); + }) + .then(function () { + gd.layout.yaxis.rangebreaks = [ + { + bounds: [ + '1970-01-01 00:00:00.011', + '1970-01-01 00:00:00.089' + ] + }, + { + bounds: [ + '1970-01-01 00:00:00.070', + '1970-01-01 00:00:00.189' + ] + } + ]; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('2 overlapping rangebreaks within range', 'y', { + rangebreaks: [[11, 189]], + m2: -10.714285714283243, + B: [2160, 252.857] + }); + }) + .then(done, done.fail); }); - it('should locate rangebreaks & compute l <-> p parameters - date axis case', function(done) { + it('should locate rangebreaks & compute l <-> p parameters - date axis case', function (done) { Plotly.newPlot(gd, [{ x: [ // Thursday @@ -5824,161 +5871,161 @@ describe('Test axes', function() { }], { xaxis: {} }) - .then(function() { - _assert('no set rangebreaks', 'x', null); - }) - .then(function() { - gd.layout.xaxis.rangebreaks = [ - {pattern: 'day of week', bounds: [6, 1]} - ]; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('break over the weekend days', 'x', { - rangebreaks: [ - ['2020-01-04', '2020-01-06'].map(Lib.dateTime2ms) - ], - m2: 0.000001640946501588664, - B: [-2589304.064, -2589587.619] - }); - }) - .then(function() { - gd.layout.xaxis.rangebreaks = [ - {pattern: 'day of week', bounds: [5, 6]} - ]; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('skip Friday', 'x', { - rangebreaks: [ - ['2020-01-03', '2020-01-04'].map(Lib.dateTime2ms) - ], - m2: 0.0000012658730158736563, - B: [-1997456.107, -1997565.478] - }); - }) - .then(function() { - gd.layout.xaxis.rangebreaks = [ - {pattern: 'day of week', bounds: [5, 5]} - ]; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('bad input -> implied empty rangebreaks', 'x', null); - }) - .then(function() { - gd.layout.xaxis.rangebreaks = [ - {pattern: 'hour', bounds: [17, 8]} - ]; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('breaks outside workday hours', 'x', { - rangebreaks: [ - ['2020-01-02 17:00:00', '2020-01-03 08:00:00'].map(Lib.dateTime2ms), - ['2020-01-03 17:00:00', '2020-01-04 08:00:00'].map(Lib.dateTime2ms), - ['2020-01-04 17:00:00', '2020-01-05 08:00:00'].map(Lib.dateTime2ms), - ['2020-01-05 17:00:00', '2020-01-06 08:00:00'].map(Lib.dateTime2ms), - ['2020-01-06 17:00:00', '2020-01-07 08:00:00'].map(Lib.dateTime2ms) - ], - m2: 0.0000029537037039351, - B: [ - -4660771.917031818, -4660931.41703183, - -4661090.917031842, -4661250.417031854, - -4661409.9170318665, -4661569.417031879 - ] - }); - }) - .then(function() { - gd.layout.xaxis.rangebreaks = [ - {pattern: 'day of week', bounds: [6, 1]}, - {pattern: 'hour', bounds: [17, 8]} - ]; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('breaks outside workday hours & weekends', 'x', { - rangebreaks: [ - ['2020-01-02 17:00:00', '2020-01-03 08:00:00'].map(Lib.dateTime2ms), - ['2020-01-03 17:00:00', '2020-01-06 08:00:00'].map(Lib.dateTime2ms), - ['2020-01-06 17:00:00', '2020-01-07 08:00:00'].map(Lib.dateTime2ms) - ], - m2: 0.000004922839504765992, - B: [ - -7767973.692224438, -7768239.525557696, - -7769356.025557376, -7769621.858890634 - ] - }); - }) - .then(function() { - gd.layout.xaxis.rangebreaks = [ - {pattern: 'hour', bounds: [17, 8]}, - {pattern: 'day of week', bounds: [6, 1]} - ]; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('breaks outside workday hours & weekends (reversed break order)', 'x', { - rangebreaks: [ - ['2020-01-02 17:00:00', '2020-01-03 08:00:00'].map(Lib.dateTime2ms), - ['2020-01-03 17:00:00', '2020-01-06 08:00:00'].map(Lib.dateTime2ms), - ['2020-01-06 17:00:00', '2020-01-07 08:00:00'].map(Lib.dateTime2ms) - ], - m2: 0.000004922839504765992, - B: [ - -7767973.692224438, -7768239.525557696, - -7769356.025557376, -7769621.858890634 - ] - }); - }) - .then(function() { - gd.layout.xaxis.rangebreaks = [ - {pattern: 'hour', bounds: [17, 8]} - ]; - // N.B. xaxis.range[0] falls within a break - gd.layout.xaxis.autorange = false; - gd.layout.xaxis.range = ['2020-01-01 20:00:00', '2020-01-04 20:00:00']; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('when range[0] falls within a break pattern (hour case)', 'x', { - rangebreaks: [ - [1577908800000, Lib.dateTime2ms('2020-01-02 08:00:00')], - ['2020-01-02 17:00:00', '2020-01-03 08:00:00'].map(Lib.dateTime2ms), - ['2020-01-03 17:00:00', '2020-01-04 08:00:00'].map(Lib.dateTime2ms), - ['2020-01-04 17:00:00', '2020-01-04 20:00:00'].map(Lib.dateTime2ms) - ], - m2: 0.000005555555555555556, - B: [-8766160, -8766400, -8766700, -8767000, -8767060] - }); - }) - .then(function() { - gd.layout.xaxis.rangebreaks = [ - {pattern: 'day of week', bounds: [2, 4]} - ]; - // N.B. xaxis.range[0] falls within a break - gd.layout.xaxis.autorange = false; - gd.layout.xaxis.range = ['2020-01-01', '2020-01-09']; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('when range[0] falls within a break pattern (day of week case)', 'x', { - rangebreaks: [ - ['2020-01-01 00:00:00', '2020-01-02 00:00:00'].map(Lib.dateTime2ms), - ['2020-01-07 00:00:00', '2020-01-09 00:00:00'].map(Lib.dateTime2ms) - ], - m2: 0.00000125, - B: [-1972296, -1972404, -1972620] - }); - }) - .then(done, done.fail); + .then(function () { + _assert('no set rangebreaks', 'x', null); + }) + .then(function () { + gd.layout.xaxis.rangebreaks = [ + { pattern: 'day of week', bounds: [6, 1] } + ]; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('break over the weekend days', 'x', { + rangebreaks: [ + ['2020-01-04', '2020-01-06'].map(Lib.dateTime2ms) + ], + m2: 0.000001640946501588664, + B: [-2589304.064, -2589587.619] + }); + }) + .then(function () { + gd.layout.xaxis.rangebreaks = [ + { pattern: 'day of week', bounds: [5, 6] } + ]; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('skip Friday', 'x', { + rangebreaks: [ + ['2020-01-03', '2020-01-04'].map(Lib.dateTime2ms) + ], + m2: 0.0000012658730158736563, + B: [-1997456.107, -1997565.478] + }); + }) + .then(function () { + gd.layout.xaxis.rangebreaks = [ + { pattern: 'day of week', bounds: [5, 5] } + ]; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('bad input -> implied empty rangebreaks', 'x', null); + }) + .then(function () { + gd.layout.xaxis.rangebreaks = [ + { pattern: 'hour', bounds: [17, 8] } + ]; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('breaks outside workday hours', 'x', { + rangebreaks: [ + ['2020-01-02 17:00:00', '2020-01-03 08:00:00'].map(Lib.dateTime2ms), + ['2020-01-03 17:00:00', '2020-01-04 08:00:00'].map(Lib.dateTime2ms), + ['2020-01-04 17:00:00', '2020-01-05 08:00:00'].map(Lib.dateTime2ms), + ['2020-01-05 17:00:00', '2020-01-06 08:00:00'].map(Lib.dateTime2ms), + ['2020-01-06 17:00:00', '2020-01-07 08:00:00'].map(Lib.dateTime2ms) + ], + m2: 0.0000029537037039351, + B: [ + -4660771.917031818, -4660931.41703183, + -4661090.917031842, -4661250.417031854, + -4661409.9170318665, -4661569.417031879 + ] + }); + }) + .then(function () { + gd.layout.xaxis.rangebreaks = [ + { pattern: 'day of week', bounds: [6, 1] }, + { pattern: 'hour', bounds: [17, 8] } + ]; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('breaks outside workday hours & weekends', 'x', { + rangebreaks: [ + ['2020-01-02 17:00:00', '2020-01-03 08:00:00'].map(Lib.dateTime2ms), + ['2020-01-03 17:00:00', '2020-01-06 08:00:00'].map(Lib.dateTime2ms), + ['2020-01-06 17:00:00', '2020-01-07 08:00:00'].map(Lib.dateTime2ms) + ], + m2: 0.000004922839504765992, + B: [ + -7767973.692224438, -7768239.525557696, + -7769356.025557376, -7769621.858890634 + ] + }); + }) + .then(function () { + gd.layout.xaxis.rangebreaks = [ + { pattern: 'hour', bounds: [17, 8] }, + { pattern: 'day of week', bounds: [6, 1] } + ]; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('breaks outside workday hours & weekends (reversed break order)', 'x', { + rangebreaks: [ + ['2020-01-02 17:00:00', '2020-01-03 08:00:00'].map(Lib.dateTime2ms), + ['2020-01-03 17:00:00', '2020-01-06 08:00:00'].map(Lib.dateTime2ms), + ['2020-01-06 17:00:00', '2020-01-07 08:00:00'].map(Lib.dateTime2ms) + ], + m2: 0.000004922839504765992, + B: [ + -7767973.692224438, -7768239.525557696, + -7769356.025557376, -7769621.858890634 + ] + }); + }) + .then(function () { + gd.layout.xaxis.rangebreaks = [ + { pattern: 'hour', bounds: [17, 8] } + ]; + // N.B. xaxis.range[0] falls within a break + gd.layout.xaxis.autorange = false; + gd.layout.xaxis.range = ['2020-01-01 20:00:00', '2020-01-04 20:00:00']; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('when range[0] falls within a break pattern (hour case)', 'x', { + rangebreaks: [ + [1577908800000, Lib.dateTime2ms('2020-01-02 08:00:00')], + ['2020-01-02 17:00:00', '2020-01-03 08:00:00'].map(Lib.dateTime2ms), + ['2020-01-03 17:00:00', '2020-01-04 08:00:00'].map(Lib.dateTime2ms), + ['2020-01-04 17:00:00', '2020-01-04 20:00:00'].map(Lib.dateTime2ms) + ], + m2: 0.000005555555555555556, + B: [-8766160, -8766400, -8766700, -8767000, -8767060] + }); + }) + .then(function () { + gd.layout.xaxis.rangebreaks = [ + { pattern: 'day of week', bounds: [2, 4] } + ]; + // N.B. xaxis.range[0] falls within a break + gd.layout.xaxis.autorange = false; + gd.layout.xaxis.range = ['2020-01-01', '2020-01-09']; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('when range[0] falls within a break pattern (day of week case)', 'x', { + rangebreaks: [ + ['2020-01-01 00:00:00', '2020-01-02 00:00:00'].map(Lib.dateTime2ms), + ['2020-01-07 00:00:00', '2020-01-09 00:00:00'].map(Lib.dateTime2ms) + ], + m2: 0.00000125, + B: [-1972296, -1972404, -1972620] + }); + }) + .then(done, done.fail); }); }); - describe('during calcTicks', function() { + describe('during calcTicks', function () { var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); @@ -5988,13 +6035,13 @@ describe('Test axes', function() { var fullLayout = gd._fullLayout; var xa = fullLayout.xaxis; - var vals = xa._vals.map(function(d) { return Lib.ms2DateTime(d.x); }); - if(autorange === 'reversed') vals.reverse(); + var vals = xa._vals.map(function (d) { return Lib.ms2DateTime(d.x); }); + if (autorange === 'reversed') vals.reverse(); expect(vals).withContext(msg).toEqual(exp.tickVals); } - it('should not include requested ticks that fall within rangebreaks', function(done) { + it('should not include requested ticks that fall within rangebreaks', function (done) { Plotly.newPlot(gd, [{ x: [ '1970-01-01 00:00:00.000', @@ -6011,36 +6058,40 @@ describe('Test axes', function() { width: 800, height: 400 }) - .then(function() { - _assert('base', { - tickVals: ['1970-01-01', '1970-01-01 00:00:00.05', '1970-01-01 00:00:00.1', '1970-01-01 00:00:00.15', '1970-01-01 00:00:00.2'] - }); - }) - .then(function() { - gd.layout.xaxis = { - rangebreaks: [ - {bounds: [ - '1970-01-01 00:00:00.011', - '1970-01-01 00:00:00.089' - ]}, - {bounds: [ - '1970-01-01 00:00:00.101', - '1970-01-01 00:00:00.189' - ]} - ] - }; - return Plotly.react(gd, gd.data, gd.layout); - }) - .then(function() { - _assert('with two rangebreaks', { - tickVals: ['1970-01-01', '1970-01-01 00:00:00.089', '1970-01-01 00:00:00.1', '1970-01-01 00:00:00.189', '1970-01-01 00:00:00.2'] - }); - }) - .then(done, done.fail); + .then(function () { + _assert('base', { + tickVals: ['1970-01-01', '1970-01-01 00:00:00.05', '1970-01-01 00:00:00.1', '1970-01-01 00:00:00.15', '1970-01-01 00:00:00.2'] + }); + }) + .then(function () { + gd.layout.xaxis = { + rangebreaks: [ + { + bounds: [ + '1970-01-01 00:00:00.011', + '1970-01-01 00:00:00.089' + ] + }, + { + bounds: [ + '1970-01-01 00:00:00.101', + '1970-01-01 00:00:00.189' + ] + } + ] + }; + return Plotly.react(gd, gd.data, gd.layout); + }) + .then(function () { + _assert('with two rangebreaks', { + tickVals: ['1970-01-01', '1970-01-01 00:00:00.089', '1970-01-01 00:00:00.1', '1970-01-01 00:00:00.189', '1970-01-01 00:00:00.2'] + }); + }) + .then(done, done.fail); }); - [true, 'reversed'].forEach(function(autorange) { - it('with ' + autorange + ' autorange, should include requested ticks using tick0 and dtick with rangebreaks', function(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: [ @@ -6071,99 +6122,99 @@ describe('Test axes', function() { tick0: '1970-01-01 08:00', dtick: 4 * 60 * 60 * 1000, rangebreaks: [{ - bounds: [ 17, 8 ], + bounds: [17, 8], pattern: 'hour' }, { - bounds: [ 6, 1 ], + 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' - ] - }, autorange); - }) - .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' - ] - }, autorange); - }) - .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' - ] - }, autorange); - }) - .then(done, done.fail); + .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' + ] + }, autorange); + }) + .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' + ] + }, autorange); + }) + .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' + ] + }, autorange); + }) + .then(done, done.fail); }); }); }); - it('should set visible:false in scattergl traces on axis with rangebreaks', function(done) { + it('should set visible:false in scattergl traces on axis with rangebreaks', function (done) { var gd = createGraphDiv(); spyOn(Lib, 'warn'); @@ -6180,26 +6231,26 @@ describe('Test axes', function() { ] }], { xaxis: { - rangebreaks: [{pattern: 'hour', bounds: [17, 8]}] + rangebreaks: [{ pattern: 'hour', bounds: [17, 8] }] } }) - .then(function() { - expect(gd._fullData[0].visible).toBe(false, 'sets visible:false'); - expect(Lib.warn).toHaveBeenCalledTimes(1); - expect(Lib.warn).toHaveBeenCalledWith('scattergl traces do not work on axes with rangebreaks. Setting trace 0 to `visible: false`.'); - }) - .then(function() { - destroyGraphDiv(); - done(); - }, done.fail); + .then(function () { + expect(gd._fullData[0].visible).toBe(false, 'sets visible:false'); + expect(Lib.warn).toHaveBeenCalledTimes(1); + expect(Lib.warn).toHaveBeenCalledWith('scattergl traces do not work on axes with rangebreaks. Setting trace 0 to `visible: false`.'); + }) + .then(function () { + destroyGraphDiv(); + done(); + }, done.fail); }); }); - describe('label positioning using *ticklabelmode*: "period"', function() { + describe('label positioning using *ticklabelmode*: "period"', function () { var hovertemplate = 'x:%{x|%x %X}'; // to make debugging easier var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); @@ -6208,19 +6259,19 @@ describe('Test axes', function() { function _assert(msg, expPositions, expLabels) { var ax = gd._fullLayout.xaxis; - var positions = ax._vals.map(function(d) { return ax.c2d(d.periodX !== undefined ? d.periodX : d.x); }); - var labels = ax._vals.map(function(d) { return d.text; }); + var positions = ax._vals.map(function (d) { return ax.c2d(d.periodX !== undefined ? d.periodX : d.x); }); + var labels = ax._vals.map(function (d) { return d.text; }); - for(var i = 0; i < labels.length; i++) { + for (var i = 0; i < labels.length; i++) { expect(labels[i]).withContext(msg).toBe(expLabels[i]); - if(labels[i] !== '') { + if (labels[i] !== '') { expect(positions[i]).withContext(msg).toBe(expPositions[i]); } } } - ['%Y', '%y'].forEach(function(formatter, i) { - it('should respect yearly tickformat that includes ' + formatter, function(done) { + ['%Y', '%y'].forEach(function (formatter, i) { + it('should respect yearly tickformat that includes ' + formatter, function (done) { Plotly.newPlot(gd, { data: [{ hovertemplate: hovertemplate, @@ -6234,26 +6285,26 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert('', [ - '2019-07-02 12:00', - '2020-07-02', - '2021-07-02 12:00', - '2022-07-02 12:00', - '2023-07-02 12:00', - '2024-07-02', - '2025-07-02 12:00', - '2026-07-02 12:00' - ], [ - ['', '2020', '2021', '2022', '2023', '2024', '2025', ''], - ['', '20', '21', '22', '23', '24', '25', ''] - ][i]); - }) - .then(done, done.fail); + .then(function () { + _assert('', [ + '2019-07-02 12:00', + '2020-07-02', + '2021-07-02 12:00', + '2022-07-02 12:00', + '2023-07-02 12:00', + '2024-07-02', + '2025-07-02 12:00', + '2026-07-02 12:00' + ], [ + ['', '2020', '2021', '2022', '2023', '2024', '2025', ''], + ['', '20', '21', '22', '23', '24', '25', ''] + ][i]); + }) + .then(done, done.fail); }); }); - it('should respect quarters tickformat that includes %q', function(done) { + it('should respect quarters tickformat that includes %q', function (done) { Plotly.newPlot(gd, { data: [{ hovertemplate: hovertemplate, @@ -6267,24 +6318,24 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert('', [ - '2019-11-16', - '2020-02-15 12:00', - '2020-05-16 12:00', - '2020-08-16', - '2020-11-16', - '2021-02-15', - '2021-05-16 12:00', - '2021-08-16', - '2021-11-16', - '2022-02-16' - ], ['', '2020-Q1', '2020-Q2', '2020-Q3', '2020-Q4', '2021-Q1', '2021-Q2', '2021-Q3', '2021-Q4', '']); - }) - .then(done, done.fail); + .then(function () { + _assert('', [ + '2019-11-16', + '2020-02-15 12:00', + '2020-05-16 12:00', + '2020-08-16', + '2020-11-16', + '2021-02-15', + '2021-05-16 12:00', + '2021-08-16', + '2021-11-16', + '2022-02-16' + ], ['', '2020-Q1', '2020-Q2', '2020-Q3', '2020-Q4', '2021-Q1', '2021-Q2', '2021-Q3', '2021-Q4', '']); + }) + .then(done, done.fail); }); - it('should position quarters - case of dtick set to M6', function(done) { + it('should position quarters - case of dtick set to M6', function (done) { Plotly.newPlot(gd, { data: [{ hovertemplate: hovertemplate, @@ -6299,21 +6350,21 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert('', [ - '2019-08-15 15:45', - '2020-02-15 15:45', - '2020-08-15 15:45', - '2021-02-15 15:45', - '2021-08-15 15:45', - '2022-02-15 15:45' - ], ['', '2020-Q1', '2020-Q3', '2021-Q1', '2021-Q3', '']); - }) - .then(done, done.fail); + .then(function () { + _assert('', [ + '2019-08-15 15:45', + '2020-02-15 15:45', + '2020-08-15 15:45', + '2021-02-15 15:45', + '2021-08-15 15:45', + '2022-02-15 15:45' + ], ['', '2020-Q1', '2020-Q3', '2021-Q1', '2021-Q3', '']); + }) + .then(done, done.fail); }); - ['%B', '%b', '%m'].forEach(function(formatter, i) { - it('should respect monthly tickformat that includes ' + formatter, function(done) { + ['%B', '%b', '%m'].forEach(function (formatter, i) { + it('should respect monthly tickformat that includes ' + formatter, function (done) { Plotly.newPlot(gd, { data: [{ hovertemplate: hovertemplate, @@ -6327,27 +6378,27 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert('', [ - '2019-12-16 12:00', - '2020-01-16 12:00', - '2020-02-15 12:00', - '2020-03-16 12:00', - '2020-04-16', - '2020-05-16 12:00', - '2020-06-16', - '2020-07-16' - ], [ - ['', 'Q1-January', 'Q1-February', 'Q1-March', 'Q2-April', 'Q2-May', 'Q2-June', ''], - ['', 'Q1-Jan', 'Q1-Feb', 'Q1-Mar', 'Q2-Apr', 'Q2-May', 'Q2-Jun', ''], - ['', 'Q1-01', 'Q1-02', 'Q1-03', 'Q2-04', 'Q2-05', 'Q2-06', ''] - ][i]); - }) - .then(done, done.fail); + .then(function () { + _assert('', [ + '2019-12-16 12:00', + '2020-01-16 12:00', + '2020-02-15 12:00', + '2020-03-16 12:00', + '2020-04-16', + '2020-05-16 12:00', + '2020-06-16', + '2020-07-16' + ], [ + ['', 'Q1-January', 'Q1-February', 'Q1-March', 'Q2-April', 'Q2-May', 'Q2-June', ''], + ['', 'Q1-Jan', 'Q1-Feb', 'Q1-Mar', 'Q2-Apr', 'Q2-May', 'Q2-Jun', ''], + ['', 'Q1-01', 'Q1-02', 'Q1-03', 'Q2-04', 'Q2-05', 'Q2-06', ''] + ][i]); + }) + .then(done, done.fail); }); }); - it('should respect Sunday-based week tickformat that includes %U', function(done) { + it('should respect Sunday-based week tickformat that includes %U', function (done) { Plotly.newPlot(gd, { data: [{ hovertemplate: hovertemplate, @@ -6361,25 +6412,25 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert('', [ - '2020-01-29 12:00', - '2020-02-05 12:00', - '2020-02-12 12:00', - '2020-02-19 12:00', - '2020-02-26 12:00', - '2020-03-04 12:00', - '2020-03-11 12:00', - '2020-03-18 12:00', - '2020-03-25 12:00', - '2020-04-01 12:00' - ], ['Jan-W04', 'Feb-W05', 'Feb-W06', 'Feb-W07', 'Feb-W08', 'Mar-W09', 'Mar-W10', 'Mar-W11', 'Mar-W12', 'Mar-W13']); - }) - .then(done, done.fail); + .then(function () { + _assert('', [ + '2020-01-29 12:00', + '2020-02-05 12:00', + '2020-02-12 12:00', + '2020-02-19 12:00', + '2020-02-26 12:00', + '2020-03-04 12:00', + '2020-03-11 12:00', + '2020-03-18 12:00', + '2020-03-25 12:00', + '2020-04-01 12:00' + ], ['Jan-W04', 'Feb-W05', 'Feb-W06', 'Feb-W07', 'Feb-W08', 'Mar-W09', 'Mar-W10', 'Mar-W11', 'Mar-W12', 'Mar-W13']); + }) + .then(done, done.fail); }); - ['%V', '%W'].forEach(function(formatter, i) { - it('should respect Monday-based week tickformat that includes ' + formatter, function(done) { + ['%V', '%W'].forEach(function (formatter, i) { + it('should respect Monday-based week tickformat that includes ' + formatter, function (done) { Plotly.newPlot(gd, { data: [{ hovertemplate: hovertemplate, @@ -6393,29 +6444,29 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert('', [ - '2020-01-30 12:00', - '2020-02-06 12:00', - '2020-02-13 12:00', - '2020-02-20 12:00', - '2020-02-27 12:00', - '2020-03-05 12:00', - '2020-03-12 12:00', - '2020-03-19 12:00', - '2020-03-26 12:00', - '2020-04-02 12:00' - ], [ - ['Jan-W05', 'Feb-W06', 'Feb-W07', 'Feb-W08', 'Feb-W09', 'Mar-W10', 'Mar-W11', 'Mar-W12', 'Mar-W13', 'Mar-W14'], - ['Jan-W04', 'Feb-W05', 'Feb-W06', 'Feb-W07', 'Feb-W08', 'Mar-W09', 'Mar-W10', 'Mar-W11', 'Mar-W12', 'Mar-W13'] - ][i]); - }) - .then(done, done.fail); + .then(function () { + _assert('', [ + '2020-01-30 12:00', + '2020-02-06 12:00', + '2020-02-13 12:00', + '2020-02-20 12:00', + '2020-02-27 12:00', + '2020-03-05 12:00', + '2020-03-12 12:00', + '2020-03-19 12:00', + '2020-03-26 12:00', + '2020-04-02 12:00' + ], [ + ['Jan-W05', 'Feb-W06', 'Feb-W07', 'Feb-W08', 'Feb-W09', 'Mar-W10', 'Mar-W11', 'Mar-W12', 'Mar-W13', 'Mar-W14'], + ['Jan-W04', 'Feb-W05', 'Feb-W06', 'Feb-W07', 'Feb-W08', 'Mar-W09', 'Mar-W10', 'Mar-W11', 'Mar-W12', 'Mar-W13'] + ][i]); + }) + .then(done, done.fail); }); }); - ['%U', '%V', '%W'].forEach(function(formatter, i) { - it('should position weekly labels in the middle when *day of week* rangebreak is present', function(done) { + ['%U', '%V', '%W'].forEach(function (formatter, i) { + it('should position weekly labels in the middle when *day of week* rangebreak is present', function (done) { Plotly.newPlot(gd, { data: [{ hovertemplate: hovertemplate, @@ -6456,29 +6507,29 @@ describe('Test axes', function() { layout: { width: 1000, xaxis: { - rangebreaks: [{bounds: ['sat', 'mon']}], + rangebreaks: [{ bounds: ['sat', 'mon'] }], ticklabelmode: 'period', tickformat: '%b-W' + formatter } } }) - .then(function() { - _assert('', [ - ['2020-01-08 12:00', '2020-01-15 12:00', '2020-01-22 12:00', '2020-01-29 12:00'], - ['2020-01-08 12:00', '2020-01-15 12:00', '2020-01-22 12:00', '2020-01-29 12:00'], - ['2020-01-08 12:00', '2020-01-15 12:00', '2020-01-22 12:00', '2020-01-29 12:00'] - ][i], [ - ['Jan-W01', 'Jan-W02', 'Jan-W03', 'Jan-W04'], - ['Jan-W02', 'Jan-W03', 'Jan-W04', 'Jan-W05'], - ['Jan-W01', 'Jan-W02', 'Jan-W03', 'Jan-W04'] - ][i]); - }) - .then(done, done.fail); + .then(function () { + _assert('', [ + ['2020-01-08 12:00', '2020-01-15 12:00', '2020-01-22 12:00', '2020-01-29 12:00'], + ['2020-01-08 12:00', '2020-01-15 12:00', '2020-01-22 12:00', '2020-01-29 12:00'], + ['2020-01-08 12:00', '2020-01-15 12:00', '2020-01-22 12:00', '2020-01-29 12:00'] + ][i], [ + ['Jan-W01', 'Jan-W02', 'Jan-W03', 'Jan-W04'], + ['Jan-W02', 'Jan-W03', 'Jan-W04', 'Jan-W05'], + ['Jan-W01', 'Jan-W02', 'Jan-W03', 'Jan-W04'] + ][i]); + }) + .then(done, done.fail); }); }); - ['%A', '%a', '%d', '%e', '%j', '%u', '%w', '%x'].forEach(function(formatter, i) { - it('should respect daily tickformat that includes ' + formatter, function(done) { + ['%A', '%a', '%d', '%e', '%j', '%u', '%w', '%x'].forEach(function (formatter, i) { + it('should respect daily tickformat that includes ' + formatter, function (done) { Plotly.newPlot(gd, { data: [{ hovertemplate: hovertemplate, @@ -6492,34 +6543,34 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert('', [ - '2019-12-31 12:00', - '2020-01-01 12:00', - '2020-01-02 12:00', - '2020-01-03 12:00', - '2020-01-04 12:00', - '2020-01-05 12:00', - '2020-01-06 12:00', - '2020-01-07 12:00', - '2020-01-08 12:00' - ], [ - ['', 'Jan-Wednesday', 'Jan-Thursday', 'Jan-Friday', 'Jan-Saturday', 'Jan-Sunday', 'Jan-Monday', 'Jan-Tuesday', ''], - ['', 'Jan-Wed', 'Jan-Thu', 'Jan-Fri', 'Jan-Sat', 'Jan-Sun', 'Jan-Mon', 'Jan-Tue', ''], - ['', 'Jan-01', 'Jan-02', 'Jan-03', 'Jan-04', 'Jan-05', 'Jan-06', 'Jan-07', ''], - ['', 'Jan- 1', 'Jan- 2', 'Jan- 3', 'Jan- 4', 'Jan- 5', 'Jan- 6', 'Jan- 7', ''], - ['', 'Jan-001', 'Jan-002', 'Jan-003', 'Jan-004', 'Jan-005', 'Jan-006', 'Jan-007', ''], - ['', 'Jan-3', 'Jan-4', 'Jan-5', 'Jan-6', 'Jan-7', 'Jan-1', 'Jan-2', ''], - ['', 'Jan-3', 'Jan-4', 'Jan-5', 'Jan-6', 'Jan-0', 'Jan-1', 'Jan-2', ''], - ['', 'Jan-01/01/2020', 'Jan-01/02/2020', 'Jan-01/03/2020', 'Jan-01/04/2020', 'Jan-01/05/2020', 'Jan-01/06/2020', 'Jan-01/07/2020', ''] - ][i]); - }) - .then(done, done.fail); + .then(function () { + _assert('', [ + '2019-12-31 12:00', + '2020-01-01 12:00', + '2020-01-02 12:00', + '2020-01-03 12:00', + '2020-01-04 12:00', + '2020-01-05 12:00', + '2020-01-06 12:00', + '2020-01-07 12:00', + '2020-01-08 12:00' + ], [ + ['', 'Jan-Wednesday', 'Jan-Thursday', 'Jan-Friday', 'Jan-Saturday', 'Jan-Sunday', 'Jan-Monday', 'Jan-Tuesday', ''], + ['', 'Jan-Wed', 'Jan-Thu', 'Jan-Fri', 'Jan-Sat', 'Jan-Sun', 'Jan-Mon', 'Jan-Tue', ''], + ['', 'Jan-01', 'Jan-02', 'Jan-03', 'Jan-04', 'Jan-05', 'Jan-06', 'Jan-07', ''], + ['', 'Jan- 1', 'Jan- 2', 'Jan- 3', 'Jan- 4', 'Jan- 5', 'Jan- 6', 'Jan- 7', ''], + ['', 'Jan-001', 'Jan-002', 'Jan-003', 'Jan-004', 'Jan-005', 'Jan-006', 'Jan-007', ''], + ['', 'Jan-3', 'Jan-4', 'Jan-5', 'Jan-6', 'Jan-7', 'Jan-1', 'Jan-2', ''], + ['', 'Jan-3', 'Jan-4', 'Jan-5', 'Jan-6', 'Jan-0', 'Jan-1', 'Jan-2', ''], + ['', 'Jan-01/01/2020', 'Jan-01/02/2020', 'Jan-01/03/2020', 'Jan-01/04/2020', 'Jan-01/05/2020', 'Jan-01/06/2020', 'Jan-01/07/2020', ''] + ][i]); + }) + .then(done, done.fail); }); }); - ['%Q', '%s', '%X'].forEach(function(formatter, i) { - it('should respect daily tickformat that includes ' + formatter, function(done) { + ['%Q', '%s', '%X'].forEach(function (formatter, i) { + it('should respect daily tickformat that includes ' + formatter, function (done) { Plotly.newPlot(gd, { data: [{ hovertemplate: hovertemplate, @@ -6533,25 +6584,25 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert('', [ - '2019-12-31 21:00', - '2020-01-01', - '2020-01-01 03:00', - '2020-01-01 06:00', - '2020-01-01 09:00', - '2020-01-01 12:00', - '2020-01-01 15:00', - '2020-01-01 18:00', - '2020-01-01 21:00', - '2020-01-02' - ], [ - ['', 'Wed-1577836800000', 'Wed-1577847600000', 'Wed-1577858400000', 'Wed-1577869200000', 'Wed-1577880000000', 'Wed-1577890800000', 'Wed-1577901600000', 'Wed-1577912400000', 'Thu-1577923200000'], - ['', 'Wed-1577836800', 'Wed-1577847600', 'Wed-1577858400', 'Wed-1577869200', 'Wed-1577880000', 'Wed-1577890800', 'Wed-1577901600', 'Wed-1577912400', 'Thu-1577923200'], - ['', 'Wed-00:00:00', 'Wed-03:00:00', 'Wed-06:00:00', 'Wed-09:00:00', 'Wed-12:00:00', 'Wed-15:00:00', 'Wed-18:00:00', 'Wed-21:00:00', 'Thu-00:00:00'] - ][i]); - }) - .then(done, done.fail); + .then(function () { + _assert('', [ + '2019-12-31 21:00', + '2020-01-01', + '2020-01-01 03:00', + '2020-01-01 06:00', + '2020-01-01 09:00', + '2020-01-01 12:00', + '2020-01-01 15:00', + '2020-01-01 18:00', + '2020-01-01 21:00', + '2020-01-02' + ], [ + ['', 'Wed-1577836800000', 'Wed-1577847600000', 'Wed-1577858400000', 'Wed-1577869200000', 'Wed-1577880000000', 'Wed-1577890800000', 'Wed-1577901600000', 'Wed-1577912400000', 'Thu-1577923200000'], + ['', 'Wed-1577836800', 'Wed-1577847600', 'Wed-1577858400', 'Wed-1577869200', 'Wed-1577880000', 'Wed-1577890800', 'Wed-1577901600', 'Wed-1577912400', 'Thu-1577923200'], + ['', 'Wed-00:00:00', 'Wed-03:00:00', 'Wed-06:00:00', 'Wed-09:00:00', 'Wed-12:00:00', 'Wed-15:00:00', 'Wed-18:00:00', 'Wed-21:00:00', 'Thu-00:00:00'] + ][i]); + }) + .then(done, done.fail); }); }); @@ -6591,8 +6642,8 @@ describe('Test axes', function() { positions: ['2019-12-31 21:00', '2020-01-01', '2020-01-01 03:00', '2020-01-01 06:00', '2020-01-01 09:00', '2020-01-01 12:00', '2020-01-01 15:00', '2020-01-01 18:00', '2020-01-01 21:00', '2020-01-02'], labels: ['', 'Wed-0', 'Wed-0', 'Wed-0', 'Wed-0', 'Wed-0', 'Wed-0', 'Wed-0', 'Wed-0', 'Thu-0'] } - ].forEach(function(t) { - it('should respect time tickformat that includes ' + t.formatter, function(done) { + ].forEach(function (t) { + it('should respect time tickformat that includes ' + t.formatter, function (done) { Plotly.newPlot(gd, { data: [{ hovertemplate: hovertemplate, @@ -6606,10 +6657,10 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert('', t.positions, t.labels); - }) - .then(done, done.fail); + .then(function () { + _assert('', t.positions, t.labels); + }) + .then(done, done.fail); }); }); @@ -6629,8 +6680,8 @@ describe('Test axes', function() { positions: ['2020-01-20', '2020-01-16 12:00'], labels: ['', '2020-Jan'] } - ].forEach(function(t) { - it('should position labels with monthly tickformat when auto dtick is weekly | range:' + t.range, function(done) { + ].forEach(function (t) { + it('should position labels with monthly tickformat when auto dtick is weekly | range:' + t.range, function (done) { Plotly.newPlot(gd, { data: [{ x: [ @@ -6652,10 +6703,10 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert('', t.positions, t.labels); - }) - .then(done, done.fail); + .then(function () { + _assert('', t.positions, t.labels); + }) + .then(done, done.fail); }); }); @@ -6730,8 +6781,8 @@ describe('Test axes', function() { positions: ['2020-12-14 22:00', '2020-12-15', '2020-12-15 02:00', '2020-12-15 04:00', '2020-12-15 06:00', '2020-12-15 08:00', '2020-12-15 10:00', '2020-12-15 12:00'], labels: ['', '00:00
Dec 15, 2020', '02:00', '04:00', '06:00', '08:00', '10:00', '12:00'] } - ].forEach(function(t) { - it('should position auto labels | range:' + t.range, function(done) { + ].forEach(function (t) { + it('should position auto labels | range:' + t.range, function (done) { Plotly.newPlot(gd, { data: [{ hovertemplate: hovertemplate, @@ -6772,10 +6823,10 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert('', t.positions, t.labels); - }) - .then(done, done.fail); + .then(function () { + _assert('', t.positions, t.labels); + }) + .then(done, done.fail); }); }); @@ -6850,8 +6901,8 @@ describe('Test axes', function() { positions: ['2020-12-15 14:00', '2020-12-15 12:00', '2020-12-15 10:00', '2020-12-15 08:00', '2020-12-15 06:00', '2020-12-15 04:00', '2020-12-15 02:00', '2020-12-15'], labels: ['', '12:00
Dec 15, 2020', '10:00', '08:00', '06:00', '04:00', '02:00', '00:00'] } - ].forEach(function(t) { - it('should position auto labels | reversed range:' + t.range, function(done) { + ].forEach(function (t) { + it('should position auto labels | reversed range:' + t.range, function (done) { Plotly.newPlot(gd, { data: [{ hovertemplate: hovertemplate, @@ -6892,10 +6943,10 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert('', t.positions, t.labels); - }) - .then(done, done.fail); + .then(function () { + _assert('', t.positions, t.labels); + }) + .then(done, done.fail); }); }); @@ -6945,8 +6996,8 @@ describe('Test axes', function() { positions: ['2020-12-14 12:00', '2020-12-15 06:00', '2020-12-15 12:00', '2020-12-16 06:00'], labels: ['12:00
Dec 14, 2020', '06:00
Dec 15, 2020', '12:00', '06:00
Dec 16, 2020'] } - ].forEach(function(t) { - it('should position auto labels with rangebreaks | range:' + t.range, function(done) { + ].forEach(function (t) { + it('should position auto labels with rangebreaks | range:' + t.range, function (done) { Plotly.newPlot(gd, { data: [{ hovertemplate: hovertemplate, @@ -6996,15 +7047,15 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert('', t.positions, t.labels); - }) - .then(done, done.fail); + .then(function () { + _assert('', t.positions, t.labels); + }) + .then(done, done.fail); }); }); - [undefined, '%U', '%V', '%W'].forEach(function(tickformat) { - it('with ' + tickformat + ' tickformat, should default tick0 on a Sunday when dtick is a round number of weeks', function(done) { + [undefined, '%U', '%V', '%W'].forEach(function (tickformat) { + it('with ' + tickformat + ' tickformat, should default tick0 on a Sunday when dtick is a round number of weeks', function (done) { var fig = { data: [ { @@ -7031,18 +7082,18 @@ describe('Test axes', function() { }; Plotly.newPlot(gd, fig) - .then(function() { - expect(gd._fullLayout.xaxis.tick0).toBe('2000-01-02'); - }) - .then(done, done.fail); + .then(function () { + expect(gd._fullLayout.xaxis.tick0).toBe('2000-01-02'); + }) + .then(done, done.fail); }); }); }); - describe('minor ticks"', function() { + describe('minor ticks"', function () { var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); @@ -7054,8 +7105,8 @@ describe('Test axes', function() { // minor positions var positions = ax._vals - .filter(function(d) { return d.minor; }) - .map(function(d) { return d.x; }); + .filter(function (d) { return d.minor; }) + .map(function (d) { return d.x; }); expect(positions).toEqual(expPositions); } @@ -7066,13 +7117,13 @@ describe('Test axes', function() { // minor positions var positions = ax._vals - .filter(function(d) { return d.minor; }) - .map(function(d) { return d.x; }); + .filter(function (d) { return d.minor; }) + .map(function (d) { return d.x; }); expect(positions).toBeCloseToArray(expPositions, 3); } - it('minor tickvals', function(done) { + it('minor tickvals', function (done) { Plotly.newPlot(gd, { data: [{ x: [10, 100] @@ -7087,13 +7138,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 12, 34, 56, 78 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([12, 34, 56, 78]); + }) + .then(done, done.fail); }); - it('linear auto', function(done) { + it('linear auto', function (done) { Plotly.newPlot(gd, { data: [{ x: [10, 100] @@ -7107,13 +7158,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 5, 10, 15, 25, 30, 35, 45, 50, 55, 65, 70, 75, 85, 90, 95, 105 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([5, 10, 15, 25, 30, 35, 45, 50, 55, 65, 70, 75, 85, 90, 95, 105]); + }) + .then(done, done.fail); }); - it('linear auto with defined minor nticks: 2', function(done) { + it('linear auto with defined minor nticks: 2', function (done) { Plotly.newPlot(gd, { data: [{ x: [10, 100] @@ -7128,13 +7179,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 10, 30, 50, 70, 90 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([10, 30, 50, 70, 90]); + }) + .then(done, done.fail); }); - it('linear auto with defined minor nticks: 7', function(done) { + it('linear auto with defined minor nticks: 7', function (done) { Plotly.newPlot(gd, { data: [{ x: [10, 100] @@ -7149,13 +7200,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 5, 10, 15, 25, 30, 35, 45, 50, 55, 65, 70, 75, 85, 90, 95, 105 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([5, 10, 15, 25, 30, 35, 45, 50, 55, 65, 70, 75, 85, 90, 95, 105]); + }) + .then(done, done.fail); }); - it('linear auto with defined minor nticks: 10', function(done) { + it('linear auto with defined minor nticks: 10', function (done) { Plotly.newPlot(gd, { data: [{ x: [10, 100] @@ -7170,13 +7221,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 6, 8, 10, 12, 14, 16, 18, 22, 24, 26, 28, 30, 32, 34, 36, 38, 42, 44, 46, 48, 50, 52, 54, 56, 58, 62, 64, 66, 68, 70, 72, 74, 76, 78, 82, 84, 86, 88, 90, 92, 94, 96, 98, 102, 104 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([6, 8, 10, 12, 14, 16, 18, 22, 24, 26, 28, 30, 32, 34, 36, 38, 42, 44, 46, 48, 50, 52, 54, 56, 58, 62, 64, 66, 68, 70, 72, 74, 76, 78, 82, 84, 86, 88, 90, 92, 94, 96, 98, 102, 104]); + }) + .then(done, done.fail); }); - it('linear auto with defined minor dtick: 2.5', function(done) { + it('linear auto with defined minor dtick: 2.5', function (done) { Plotly.newPlot(gd, { data: [{ x: [10, 100] @@ -7191,13 +7242,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 5, 7.5, 10, 12.5, 15, 17.5, 22.5, 25, 27.5, 30, 32.5, 35, 37.5, 42.5, 45, 47.5, 50, 52.5, 55, 57.5, 62.5, 65, 67.5, 70, 72.5, 75, 77.5, 82.5, 85, 87.5, 90, 92.5, 95, 97.5, 102.5, 105 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([5, 7.5, 10, 12.5, 15, 17.5, 22.5, 25, 27.5, 30, 32.5, 35, 37.5, 42.5, 45, 47.5, 50, 52.5, 55, 57.5, 62.5, 65, 67.5, 70, 72.5, 75, 77.5, 82.5, 85, 87.5, 90, 92.5, 95, 97.5, 102.5, 105]); + }) + .then(done, done.fail); }); - it('linear auto with defined major dtick: 10', function(done) { + it('linear auto with defined major dtick: 10', function (done) { Plotly.newPlot(gd, { data: [{ x: [10, 100] @@ -7212,13 +7263,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 6, 8, 12, 14, 16, 18, 22, 24, 26, 28, 32, 34, 36, 38, 42, 44, 46, 48, 52, 54, 56, 58, 62, 64, 66, 68, 72, 74, 76, 78, 82, 84, 86, 88, 92, 94, 96, 98, 102, 104 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([6, 8, 12, 14, 16, 18, 22, 24, 26, 28, 32, 34, 36, 38, 42, 44, 46, 48, 52, 54, 56, 58, 62, 64, 66, 68, 72, 74, 76, 78, 82, 84, 86, 88, 92, 94, 96, 98, 102, 104]); + }) + .then(done, done.fail); }); - it('linear with defined major & minor dtick', function(done) { + it('linear with defined major & minor dtick', function (done) { Plotly.newPlot(gd, { data: [{ x: [10, 100] @@ -7234,13 +7285,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 5, 15, 25, 35, 45, 55, 65, 75, 85, 95, 105 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([5, 15, 25, 35, 45, 55, 65, 75, 85, 95, 105]); + }) + .then(done, done.fail); }); - it('log auto - case 1', function(done) { + it('log auto - case 1', function (done) { Plotly.newPlot(gd, { data: [{ x: [1, 10e20] @@ -7255,13 +7306,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ -1, 1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([-1, 1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22]); + }) + .then(done, done.fail); }); - it('log auto - case 2', function(done) { + it('log auto - case 2', function (done) { Plotly.newPlot(gd, { data: [{ x: [1, 10e10] @@ -7276,13 +7327,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 1, 3, 5, 7, 9, 11 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([1, 3, 5, 7, 9, 11]); + }) + .then(done, done.fail); }); - it('log auto - case 3', function(done) { + it('log auto - case 3', function (done) { Plotly.newPlot(gd, { data: [{ x: [1, 10e3] @@ -7297,13 +7348,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assertClose([ -0.22184874961635648, -0.1549019599857433, -0.09691001300805657, -0.04575749056067513, 0.4771212547196623, 0.6020599913279623, 0.7781512503836435, 0.8450980400142567, 0.9030899869919434, 0.9542425094393249, 1.4771212547196624, 1.6020599913279623, 1.7781512503836434, 1.8450980400142567, 1.9030899869919433, 1.9542425094393248, 2.477121254719662, 2.6020599913279625, 2.7781512503836434, 2.845098040014257, 2.9030899869919433, 2.9542425094393248, 3.477121254719662, 3.6020599913279625, 3.7781512503836434, 3.845098040014257, 3.9030899869919433, 3.9542425094393248 ]); - }) - .then(done, done.fail); + .then(function () { + _assertClose([-0.22184874961635648, -0.1549019599857433, -0.09691001300805657, -0.04575749056067513, 0.4771212547196623, 0.6020599913279623, 0.7781512503836435, 0.8450980400142567, 0.9030899869919434, 0.9542425094393249, 1.4771212547196624, 1.6020599913279623, 1.7781512503836434, 1.8450980400142567, 1.9030899869919433, 1.9542425094393248, 2.477121254719662, 2.6020599913279625, 2.7781512503836434, 2.845098040014257, 2.9030899869919433, 2.9542425094393248, 3.477121254719662, 3.6020599913279625, 3.7781512503836434, 3.845098040014257, 3.9030899869919433, 3.9542425094393248]); + }) + .then(done, done.fail); }); - it('log auto - case 4', function(done) { + it('log auto - case 4', function (done) { Plotly.newPlot(gd, { data: [{ x: [1, 10] @@ -7318,13 +7369,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([]); - }) - .then(done, done.fail); + .then(function () { + _assert([]); + }) + .then(done, done.fail); }); - it('log auto - case 5', function(done) { + it('log auto - case 5', function (done) { Plotly.newPlot(gd, { data: [{ x: [1, 2] @@ -7339,13 +7390,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assertClose([ -0.017728766960431602, -0.00877392430750515, 0.008600171761917567, 0.017033339298780367, 0.025305865264770258, 0.03342375548694973, 0.049218022670181646, 0.056904851336472634, 0.06445798922691853, 0.07188200730612543, 0.08635983067474828, 0.09342168516223513, 0.10037054511756296, 0.10720996964786844, 0.12057393120584996, 0.1271047983648077, 0.13353890837021762, 0.13987908640123659, 0.15228834438305658, 0.15836249209524975, 0.1643528557844372, 0.17026171539495752, 0.18184358794477265, 0.18752072083646318, 0.1931245983544617, 0.1986570869544227, 0.20951501454263102, 0.21484384804769796, 0.22010808804005513, 0.22530928172586287, 0.23552844690754896, 0.24054924828259974, 0.24551266781414988, 0.250420002308894, 0.2600713879850748, 0.2648178230095364, 0.26951294421791616, 0.2741578492636797, 0.28330122870354935, 0.2878017299302258, 0.29225607135647574, 0.29666519026153076, 0.30535136944662333, 0.3096301674258983, 0.31386722036915293, 0.31806333496276107 ]); - }) - .then(done, done.fail); + .then(function () { + _assertClose([-0.017728766960431602, -0.00877392430750515, 0.008600171761917567, 0.017033339298780367, 0.025305865264770258, 0.03342375548694973, 0.049218022670181646, 0.056904851336472634, 0.06445798922691853, 0.07188200730612543, 0.08635983067474828, 0.09342168516223513, 0.10037054511756296, 0.10720996964786844, 0.12057393120584996, 0.1271047983648077, 0.13353890837021762, 0.13987908640123659, 0.15228834438305658, 0.15836249209524975, 0.1643528557844372, 0.17026171539495752, 0.18184358794477265, 0.18752072083646318, 0.1931245983544617, 0.1986570869544227, 0.20951501454263102, 0.21484384804769796, 0.22010808804005513, 0.22530928172586287, 0.23552844690754896, 0.24054924828259974, 0.24551266781414988, 0.250420002308894, 0.2600713879850748, 0.2648178230095364, 0.26951294421791616, 0.2741578492636797, 0.28330122870354935, 0.2878017299302258, 0.29225607135647574, 0.29666519026153076, 0.30535136944662333, 0.3096301674258983, 0.31386722036915293, 0.31806333496276107]); + }) + .then(done, done.fail); }); - it('log with defined minor dtick: D2', function(done) { + it('log with defined minor dtick: D2', function (done) { Plotly.newPlot(gd, { data: [{ x: [1, 10e6] @@ -7361,13 +7412,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assertClose([ -0.30102999566398125, 0.30102999566398114, 0.6989700043360187, 1.3010299956639813, 1.6989700043360187, 2.3010299956639813, 2.6989700043360187, 3.3010299956639813, 3.6989700043360187, 4.301029995663981, 4.698970004336019, 5.301029995663981, 5.698970004336019, 6.301029995663981, 6.698970004336019, 7.301029995663981 ]); - }) - .then(done, done.fail); + .then(function () { + _assertClose([-0.30102999566398125, 0.30102999566398114, 0.6989700043360187, 1.3010299956639813, 1.6989700043360187, 2.3010299956639813, 2.6989700043360187, 3.3010299956639813, 3.6989700043360187, 4.301029995663981, 4.698970004336019, 5.301029995663981, 5.698970004336019, 6.301029995663981, 6.698970004336019, 7.301029995663981]); + }) + .then(done, done.fail); }); - it('log with defined minor dtick: L0.5', function(done) { + it('log with defined minor dtick: L0.5', function (done) { Plotly.newPlot(gd, { data: [{ x: [1, 10] @@ -7383,13 +7434,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assertClose([ 0.17609125905568124, 0.3979400086720376, 0.5440680443502756, 0.6532125137753436, 0.7403626894942437, 0.8129133566428552, 0.8750612633916998, 0.9294189257142923, 0.9777236052888472, 1.0211892990699374, 1.0413926851582243, 1.0606978403536107 ]); - }) - .then(done, done.fail); + .then(function () { + _assertClose([0.17609125905568124, 0.3979400086720376, 0.5440680443502756, 0.6532125137753436, 0.7403626894942437, 0.8129133566428552, 0.8750612633916998, 0.9294189257142923, 0.9777236052888472, 1.0211892990699374, 1.0413926851582243, 1.0606978403536107]); + }) + .then(done, done.fail); }); - it('date auto - case of 10 years major dtick', function(done) { + it('date auto - case of 10 years major dtick', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01', '2050-01'] @@ -7403,13 +7454,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 883612800000, 1009843200000, 1072915200000, 1136073600000, 1199145600000, 1325376000000, 1388534400000, 1451606400000, 1514764800000, 1640995200000, 1704067200000, 1767225600000, 1830297600000, 1956528000000, 2019686400000, 2082758400000, 2145916800000, 2272147200000, 2335219200000, 2398377600000, 2461449600000, 2587680000000 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([883612800000, 1009843200000, 1072915200000, 1136073600000, 1199145600000, 1325376000000, 1388534400000, 1451606400000, 1514764800000, 1640995200000, 1704067200000, 1767225600000, 1830297600000, 1956528000000, 2019686400000, 2082758400000, 2145916800000, 2272147200000, 2335219200000, 2398377600000, 2461449600000, 2587680000000]); + }) + .then(done, done.fail); }); - it('date auto - case of 5 years major dtick', function(done) { + it('date auto - case of 5 years major dtick', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01', '2020-01'] @@ -7423,13 +7474,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 915148800000, 978307200000, 1009843200000, 1041379200000, 1072915200000, 1136073600000, 1167609600000, 1199145600000, 1230768000000, 1293840000000, 1325376000000, 1356998400000, 1388534400000, 1451606400000, 1483228800000, 1514764800000, 1546300800000, 1609459200000 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([915148800000, 978307200000, 1009843200000, 1041379200000, 1072915200000, 1136073600000, 1167609600000, 1199145600000, 1230768000000, 1293840000000, 1325376000000, 1356998400000, 1388534400000, 1451606400000, 1483228800000, 1514764800000, 1546300800000, 1609459200000]); + }) + .then(done, done.fail); }); - it('date auto - case of 2 years major dtick', function(done) { + it('date auto - case of 2 years major dtick', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01', '2010-01'] @@ -7443,13 +7494,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 930787200000, 962409600000, 978307200000, 993945600000, 1025481600000, 1041379200000, 1057017600000, 1088640000000, 1104537600000, 1120176000000, 1151712000000, 1167609600000, 1183248000000, 1214870400000, 1230768000000, 1246406400000, 1277942400000 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([930787200000, 962409600000, 978307200000, 993945600000, 1025481600000, 1041379200000, 1057017600000, 1088640000000, 1104537600000, 1120176000000, 1151712000000, 1167609600000, 1183248000000, 1214870400000, 1230768000000, 1246406400000, 1277942400000]); + }) + .then(done, done.fail); }); - it('date auto - case of 1 year major dtick', function(done) { + it('date auto - case of 1 year major dtick', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01', '2005-01'] @@ -7463,13 +7514,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 938736000000, 954547200000, 962409600000, 970358400000, 986083200000, 993945600000, 1001894400000, 1017619200000, 1025481600000, 1033430400000, 1049155200000, 1057017600000, 1064966400000, 1080777600000, 1088640000000, 1096588800000, 1112313600000 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([938736000000, 954547200000, 962409600000, 970358400000, 986083200000, 993945600000, 1001894400000, 1017619200000, 1025481600000, 1033430400000, 1049155200000, 1057017600000, 1064966400000, 1080777600000, 1088640000000, 1096588800000, 1112313600000]); + }) + .then(done, done.fail); }); - it('date auto - case of M6 major dtick', function(done) { + it('date auto - case of M6 major dtick', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01', '2003-01'] @@ -7483,13 +7534,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 941414400000, 951868800000, 957139200000, 967766400000, 973036800000, 983404800000, 988675200000, 999302400000, 1004572800000, 1014940800000, 1020211200000, 1030838400000, 1036108800000, 1046476800000 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([941414400000, 951868800000, 957139200000, 967766400000, 973036800000, 983404800000, 988675200000, 999302400000, 1004572800000, 1014940800000, 1020211200000, 1030838400000, 1036108800000, 1046476800000]); + }) + .then(done, done.fail); }); - it('date auto - case of M3 major dtick', function(done) { + it('date auto - case of M3 major dtick', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01', '2002-01'] @@ -7503,13 +7554,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 944006400000, 949363200000, 951868800000, 957139200000, 959817600000, 965088000000, 967766400000, 973036800000, 975628800000, 980985600000, 983404800000, 988675200000, 991353600000, 996624000000, 999302400000, 1004572800000, 1007164800000, 1012521600000 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([944006400000, 949363200000, 951868800000, 957139200000, 959817600000, 965088000000, 967766400000, 973036800000, 975628800000, 980985600000, 983404800000, 988675200000, 991353600000, 996624000000, 999302400000, 1004572800000, 1007164800000, 1012521600000]); + }) + .then(done, done.fail); }); - it('date auto - case of M2 major dtick', function(done) { + it('date auto - case of M2 major dtick', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01', '2001-01'] @@ -7523,13 +7574,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 949363200000, 954547200000, 959817600000, 965088000000, 970358400000, 975628800000 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([949363200000, 954547200000, 959817600000, 965088000000, 970358400000, 975628800000]); + }) + .then(done, done.fail); }); - it('date auto - case of M1 major dtick', function(done) { + it('date auto - case of M1 major dtick', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01', '2000-06'] @@ -7543,13 +7594,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([]); - }) - .then(done, done.fail); + .then(function () { + _assert([]); + }) + .then(done, done.fail); }); - it('date auto - case of 2 weeks major dtick', function(done) { + it('date auto - case of 2 weeks major dtick', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01', '2000-04'] @@ -7563,13 +7614,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 947376000000, 948585600000, 949795200000, 951004800000, 952214400000, 953424000000, 954633600000 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([947376000000, 948585600000, 949795200000, 951004800000, 952214400000, 953424000000, 954633600000]); + }) + .then(done, done.fail); }); - it('date auto - case of 1 week major dtick', function(done) { + it('date auto - case of 1 week major dtick', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01', '2000-02'] @@ -7583,13 +7634,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 946598400000, 946684800000, 946857600000, 946944000000, 947030400000, 947116800000, 947203200000, 947289600000, 947462400000, 947548800000, 947635200000, 947721600000, 947808000000, 947894400000, 948067200000, 948153600000, 948240000000, 948326400000, 948412800000, 948499200000, 948672000000, 948758400000, 948844800000, 948931200000, 949017600000, 949104000000, 949276800000, 949363200000, 949449600000 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([946598400000, 946684800000, 946857600000, 946944000000, 947030400000, 947116800000, 947203200000, 947289600000, 947462400000, 947548800000, 947635200000, 947721600000, 947808000000, 947894400000, 948067200000, 948153600000, 948240000000, 948326400000, 948412800000, 948499200000, 948672000000, 948758400000, 948844800000, 948931200000, 949017600000, 949104000000, 949276800000, 949363200000, 949449600000]); + }) + .then(done, done.fail); }); - it('date auto - case of 3 days major dtick', function(done) { + it('date auto - case of 3 days major dtick', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01-01', '2000-01-21'] @@ -7603,13 +7654,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 946598400000, 946684800000, 946857600000, 946944000000, 947116800000, 947203200000, 947376000000, 947462400000, 947635200000, 947721600000, 947894400000, 947980800000, 948153600000, 948240000000, 948412800000, 948499200000 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([946598400000, 946684800000, 946857600000, 946944000000, 947116800000, 947203200000, 947376000000, 947462400000, 947635200000, 947721600000, 947894400000, 947980800000, 948153600000, 948240000000, 948412800000, 948499200000]); + }) + .then(done, done.fail); }); - it('date auto - case of 2 days major dtick', function(done) { + it('date auto - case of 2 days major dtick', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01-01', '2000-01-11'] @@ -7623,13 +7674,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 946641600000, 946684800000, 946728000000, 946814400000, 946857600000, 946900800000, 946987200000, 947030400000, 947073600000, 947160000000, 947203200000, 947246400000, 947332800000, 947376000000, 947419200000, 947505600000, 947548800000, 947592000000 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([946641600000, 946684800000, 946728000000, 946814400000, 946857600000, 946900800000, 946987200000, 947030400000, 947073600000, 947160000000, 947203200000, 947246400000, 947332800000, 947376000000, 947419200000, 947505600000, 947548800000, 947592000000]); + }) + .then(done, done.fail); }); - it('date auto - case of 1 day major dtick', function(done) { + it('date auto - case of 1 day major dtick', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01-01', '2000-01-06'] @@ -7643,13 +7694,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 946663200000, 946706400000, 946728000000, 946749600000, 946792800000, 946814400000, 946836000000, 946879200000, 946900800000, 946922400000, 946965600000, 946987200000, 947008800000, 947052000000, 947073600000, 947095200000, 947138400000 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([946663200000, 946706400000, 946728000000, 946749600000, 946792800000, 946814400000, 946836000000, 946879200000, 946900800000, 946922400000, 946965600000, 946987200000, 947008800000, 947052000000, 947073600000, 947095200000, 947138400000]); + }) + .then(done, done.fail); }); - it('date auto - case of 12 hours major dtick', function(done) { + it('date auto - case of 12 hours major dtick', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01-01', '2000-01-03'] @@ -7663,13 +7714,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 946677600000, 946692000000, 946699200000, 946713600000, 946720800000, 946735200000, 946742400000, 946756800000, 946764000000, 946778400000, 946785600000, 946800000000, 946807200000, 946821600000, 946828800000, 946843200000, 946850400000, 946864800000 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([946677600000, 946692000000, 946699200000, 946713600000, 946720800000, 946735200000, 946742400000, 946756800000, 946764000000, 946778400000, 946785600000, 946800000000, 946807200000, 946821600000, 946828800000, 946843200000, 946850400000, 946864800000]); + }) + .then(done, done.fail); }); - it('date auto - case of 6 hours major dtick', function(done) { + it('date auto - case of 6 hours major dtick', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01-01', '2000-01-02 12:00'] @@ -7683,13 +7734,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 946677600000, 946692000000, 946699200000, 946713600000, 946720800000, 946735200000, 946742400000, 946756800000, 946764000000, 946778400000, 946785600000, 946800000000, 946807200000, 946821600000 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([946677600000, 946692000000, 946699200000, 946713600000, 946720800000, 946735200000, 946742400000, 946756800000, 946764000000, 946778400000, 946785600000, 946800000000, 946807200000, 946821600000]); + }) + .then(done, done.fail); }); - it('date auto - case of 3 hours major dtick', function(done) { + it('date auto - case of 3 hours major dtick', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01-01', '2000-01-02'] @@ -7703,13 +7754,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 946681200000, 946688400000, 946692000000, 946699200000, 946702800000, 946710000000, 946713600000, 946720800000, 946724400000, 946731600000, 946735200000, 946742400000, 946746000000, 946753200000, 946756800000, 946764000000, 946767600000, 946774800000 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([946681200000, 946688400000, 946692000000, 946699200000, 946702800000, 946710000000, 946713600000, 946720800000, 946724400000, 946731600000, 946735200000, 946742400000, 946746000000, 946753200000, 946756800000, 946764000000, 946767600000, 946774800000]); + }) + .then(done, done.fail); }); - it('date auto - case of 2 hours major dtick', function(done) { + it('date auto - case of 2 hours major dtick', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01-01', '2000-01-01 10:00'] @@ -7723,13 +7774,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 946683000000, 946686600000, 946688400000, 946690200000, 946693800000, 946695600000, 946697400000, 946701000000, 946702800000, 946704600000, 946708200000, 946710000000, 946711800000, 946715400000, 946717200000, 946719000000, 946722600000 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([946683000000, 946686600000, 946688400000, 946690200000, 946693800000, 946695600000, 946697400000, 946701000000, 946702800000, 946704600000, 946708200000, 946710000000, 946711800000, 946715400000, 946717200000, 946719000000, 946722600000]); + }) + .then(done, done.fail); }); - it('date auto - case of M1 major dtick with weekly minor', function(done) { + it('date auto - case of M1 major dtick with weekly minor', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01', '2000-06'] @@ -7744,13 +7795,13 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 946166400000, 946771200000, 947376000000, 947980800000, 948585600000, 949190400000, 949795200000, 950400000000, 951004800000, 951609600000, 952214400000, 952819200000, 953424000000, 954028800000, 954633600000, 955238400000, 955843200000, 956448000000, 957052800000, 957657600000, 958262400000, 958867200000, 959472000000, 960076800000 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([946166400000, 946771200000, 947376000000, 947980800000, 948585600000, 949190400000, 949795200000, 950400000000, 951004800000, 951609600000, 952214400000, 952819200000, 953424000000, 954028800000, 954633600000, 955238400000, 955843200000, 956448000000, 957052800000, 957657600000, 958262400000, 958867200000, 959472000000, 960076800000]); + }) + .then(done, done.fail); }); - it('date auto - case of M1 major dtick with weekly minor start on Sunday', function(done) { + it('date auto - case of M1 major dtick with weekly minor start on Sunday', function (done) { Plotly.newPlot(gd, { data: [{ x: ['2000-01', '2000-06'] @@ -7766,10 +7817,10 @@ describe('Test axes', function() { } } }) - .then(function() { - _assert([ 946339200000, 946944000000, 947548800000, 948153600000, 948758400000, 949968000000, 950572800000, 951177600000, 951782400000, 952387200000, 952992000000, 953596800000, 954201600000, 954806400000, 955411200000, 956016000000, 956620800000, 957225600000, 957830400000, 958435200000, 959040000000, 959644800000, 960249600000 ]); - }) - .then(done, done.fail); + .then(function () { + _assert([946339200000, 946944000000, 947548800000, 948153600000, 948758400000, 949968000000, 950572800000, 951177600000, 951782400000, 952387200000, 952992000000, 953596800000, 954201600000, 954806400000, 955411200000, 956016000000, 956620800000, 957225600000, 957830400000, 958435200000, 959040000000, 959644800000, 960249600000]); + }) + .then(done, done.fail); }); }); }); @@ -7786,10 +7837,10 @@ function getFormatter(format) { return utcFormat(format); } -describe('Test Axes.getTickformat', function() { +describe('Test Axes.getTickformat', function () { 'use strict'; - it('get proper tickformatstop for linear axis', function() { + it('get proper tickformatstop for linear axis', function () { var lineartickformatstops = [ { enabled: true, @@ -7844,7 +7895,7 @@ describe('Test Axes.getTickformat', function() { })).toEqual(lineartickformatstops[2].value); }); - it('get proper tickformatstop for date axis', function() { + it('get proper tickformatstop for date axis', function () { var MILLISECOND = 1; var SECOND = MILLISECOND * 1000; var MINUTE = SECOND * 60; @@ -7938,7 +7989,7 @@ describe('Test Axes.getTickformat', function() { })).toEqual(datetickformatstops[7].value); // year }); - it('get proper tickformatstop for log axis', function() { + it('get proper tickformatstop for log axis', function () { var logtickformatstops = [ { enabled: true, @@ -7991,14 +8042,14 @@ describe('Test Axes.getTickformat', function() { }); }); -describe('Test tickformatstops:', function() { +describe('Test tickformatstops:', function () { 'use strict'; var mock = require('../../image/mocks/tickformatstops.json'); var mockCopy, gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); mockCopy = Lib.extendDeep({}, mock); mockCopy.layout.hovermode = 'x'; @@ -8006,22 +8057,22 @@ describe('Test tickformatstops:', function() { afterEach(destroyGraphDiv); - it('handles zooming-in until milliseconds zoom level', function(done) { + it('handles zooming-in until milliseconds zoom level', function (done) { var promise = Plotly.newPlot(gd, mockCopy.data, mockCopy.layout); var testCount = 0; - var zoomIn = function() { - promise = promise.then(function() { + var zoomIn = function () { + promise = promise.then(function () { getZoomInButton(gd).click(); var xLabels = Axes.calcTicks(gd._fullLayout.xaxis); var formatter = getFormatter(Axes.getTickFormat(gd._fullLayout.xaxis)); - var expectedLabels = xLabels.map(function(d) {return formatter(new Date(d.x));}); - var actualLabels = xLabels.map(function(d) {return d.text;}); + var expectedLabels = xLabels.map(function (d) { return formatter(new Date(d.x)); }); + var actualLabels = xLabels.map(function (d) { return d.text; }); expect(expectedLabels).toEqual(actualLabels); testCount++; - if(gd._fullLayout.xaxis.dtick > 1) { + if (gd._fullLayout.xaxis.dtick > 1) { zoomIn(); } else { // make sure we tested as many levels as we thought we would @@ -8033,22 +8084,22 @@ describe('Test tickformatstops:', function() { zoomIn(); }); - it('handles zooming-out until years zoom level', function(done) { + it('handles zooming-out until years zoom level', function (done) { var promise = Plotly.newPlot(gd, mockCopy.data, mockCopy.layout); var testCount = 0; - var zoomOut = function() { - promise = promise.then(function() { + var zoomOut = function () { + promise = promise.then(function () { getZoomOutButton(gd).click(); var xLabels = Axes.calcTicks(gd._fullLayout.xaxis); var formatter = getFormatter(Axes.getTickFormat(gd._fullLayout.xaxis)); - var expectedLabels = xLabels.map(function(d) {return formatter(new Date(d.x));}); - var actualLabels = xLabels.map(function(d) {return d.text;}); + var expectedLabels = xLabels.map(function (d) { return formatter(new Date(d.x)); }); + var actualLabels = xLabels.map(function (d) { return d.text; }); expect(expectedLabels).toEqual(actualLabels); testCount++; - if(typeof gd._fullLayout.xaxis.dtick === 'number' || + if (typeof gd._fullLayout.xaxis.dtick === 'number' || typeof gd._fullLayout.xaxis.dtick === 'string' && parseInt(gd._fullLayout.xaxis.dtick.replace(/\D/g, '')) < 48) { zoomOut(); } else { @@ -8061,10 +8112,10 @@ describe('Test tickformatstops:', function() { zoomOut(); }); - it('responds to hover', function(done) { + it('responds to hover', function (done) { var evt = { xpx: 270, ypx: 10 }; - Plotly.newPlot(gd, mockCopy.data, mockCopy.layout).then(function() { + Plotly.newPlot(gd, mockCopy.data, mockCopy.layout).then(function () { Fx.hover(gd, evt, 'xy'); var hoverTrace = gd._hoverdata[0]; @@ -8080,35 +8131,35 @@ describe('Test tickformatstops:', function() { expect(d3SelectAll('g.axistext').select('text').html()).toEqual(formatter(new Date(hoverTrace.x))); expect(d3SelectAll('g.hovertext').select('text').html()).toEqual('0'); }) - .then(done, done.fail); + .then(done, done.fail); }); - it('doesn\'t fail on bad input', function(done) { + it('doesn\'t fail on bad input', function (done) { var promise = Plotly.newPlot(gd, mockCopy.data, mockCopy.layout); - [1, {a: 1, b: 2}, 'boo'].forEach(function(v) { - promise = promise.then(function() { - return Plotly.relayout(gd, {'xaxis.tickformatstops': v}); - }).then(function() { + [1, { a: 1, b: 2 }, 'boo'].forEach(function (v) { + promise = promise.then(function () { + return Plotly.relayout(gd, { 'xaxis.tickformatstops': v }); + }).then(function () { expect(gd._fullLayout.xaxis.tickformatstops).toBeUndefined(); }); }); promise - .then(done, done.fail); + .then(done, done.fail); }); }); -describe('Test template:', function() { +describe('Test template:', function () { 'use strict'; var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); afterEach(destroyGraphDiv); - it('apply axis *type*, *rangebreaks* and *tickformatstops* from template', function(done) { + it('apply axis *type*, *rangebreaks* and *tickformatstops* from template', function (done) { Plotly.newPlot(gd, { data: [{ x: [1e10, 2e10, 3e10, 4e10, 5e10, 6e10, 7e10], @@ -8134,28 +8185,28 @@ describe('Test template:', function() { } } }) - .then(function() { - var xaxis = gd._fullLayout.xaxis; - expect(xaxis.type).toBe('date'); - expect(xaxis.rangebreaks).not.toBe(undefined, 'rangebreaks'); - expect(xaxis.rangebreaks.length).toBe(1); - expect(xaxis.tickformatstops).not.toBe(undefined, 'tickformatstops'); - expect(xaxis.tickformatstops.length).toBe(1); - }) - .then(done, done.fail); + .then(function () { + var xaxis = gd._fullLayout.xaxis; + expect(xaxis.type).toBe('date'); + expect(xaxis.rangebreaks).not.toBe(undefined, 'rangebreaks'); + expect(xaxis.rangebreaks.length).toBe(1); + expect(xaxis.tickformatstops).not.toBe(undefined, 'tickformatstops'); + expect(xaxis.tickformatstops.length).toBe(1); + }) + .then(done, done.fail); }); }); -describe('more react tests', function() { +describe('more react tests', function () { var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); afterEach(destroyGraphDiv); - it('should sort catgories on matching axes using react and relink using relayout', function(done) { + it('should sort catgories on matching axes using react and relink using relayout', function (done) { var fig = { data: [{ yaxis: 'y', @@ -8174,7 +8225,7 @@ describe('more react tests', function() { showlegend: false, xaxis: { matches: 'x2', - domain: [ 0, 1] + domain: [0, 1] }, yaxis: { domain: [0.6, 1], @@ -8192,99 +8243,99 @@ describe('more react tests', function() { }; Plotly.newPlot(gd, fig) - .then(function() { - expect(gd._fullLayout.xaxis._categories).toEqual(['A', 'Z']); - expect(gd._fullLayout.xaxis2._categories).toEqual(['A', 'Z']); - expect(gd._fullLayout.xaxis._categoriesMap).toEqual({A: 0, Z: 1}); - expect(gd._fullLayout.xaxis2._categoriesMap).toEqual({A: 0, Z: 1}); - }) - .then(function() { - // flip order - fig.data[0].x = ['Z', 'A']; - fig.data[1].x = ['Z', 'A']; - - return Plotly.react(gd, fig); - }) - .then(function() { - expect(gd._fullLayout.xaxis._categories).toEqual(['Z', 'A']); - expect(gd._fullLayout.xaxis2._categories).toEqual(['Z', 'A']); - expect(gd._fullLayout.xaxis._categoriesMap).toEqual({Z: 0, A: 1}); - expect(gd._fullLayout.xaxis2._categoriesMap).toEqual({Z: 0, A: 1}); - }) - .then(function() { - // should get the same order with newPlot - return Plotly.newPlot(gd, fig); - }) - .then(function() { - expect(gd._fullLayout.xaxis._categories).toEqual(['Z', 'A']); - expect(gd._fullLayout.xaxis2._categories).toEqual(['Z', 'A']); - expect(gd._fullLayout.xaxis._categoriesMap).toEqual({Z: 0, A: 1}); - expect(gd._fullLayout.xaxis2._categoriesMap).toEqual({Z: 0, A: 1}); - }) - .then(function() { - // add new category - fig.data[0].x = ['Z', 0, 'A']; - fig.data[1].x = ['Z', 0, 'A']; - fig.data[0].y = [1, 2, 3]; - fig.data[1].y = [2, 4, 6]; - - return Plotly.react(gd, fig); - }) - .then(function() { - expect(gd._fullLayout.xaxis._categories).toEqual(['Z', '0', 'A']); - expect(gd._fullLayout.xaxis2._categories).toEqual(['Z', '0', 'A']); - expect(gd._fullLayout.xaxis._categoriesMap).toEqual({Z: 0, 0: 1, A: 2}); - expect(gd._fullLayout.xaxis2._categoriesMap).toEqual({Z: 0, 0: 1, A: 2}); - }) - .then(function() { - // should get the same order with newPlot - return Plotly.newPlot(gd, fig); - }) - .then(function() { - expect(gd._fullLayout.xaxis._categories).toEqual(['Z', '0', 'A']); - expect(gd._fullLayout.xaxis2._categories).toEqual(['Z', '0', 'A']); - expect(gd._fullLayout.xaxis._categoriesMap).toEqual({Z: 0, 0: 1, A: 2}); - expect(gd._fullLayout.xaxis2._categoriesMap).toEqual({Z: 0, 0: 1, A: 2}); - }) - .then(function() { - // change data - fig.data[0].x = ['Z', 0, 'A']; - fig.data[1].x = ['A', 'Z']; - fig.data[0].y = [3, 2, 1]; - fig.data[1].y = [-1, 0]; - - return Plotly.react(gd, fig); - }) - .then(function() { - expect(gd._fullLayout.xaxis._categories).toEqual(['Z', '0', 'A']); - expect(gd._fullLayout.xaxis2._categories).toEqual(['Z', '0', 'A']); - expect(gd._fullLayout.xaxis._categoriesMap).toEqual({Z: 0, 0: 1, A: 2}); - expect(gd._fullLayout.xaxis2._categoriesMap).toEqual({Z: 0, 0: 1, A: 2}); - }) - .then(function() { - // should get the same order with newPlot - return Plotly.newPlot(gd, fig); - }) - .then(function() { - expect(gd._fullLayout.xaxis._categories).toEqual(['Z', '0', 'A']); - expect(gd._fullLayout.xaxis2._categories).toEqual(['Z', '0', 'A']); - expect(gd._fullLayout.xaxis._categoriesMap).toEqual({Z: 0, 0: 1, A: 2}); - expect(gd._fullLayout.xaxis2._categoriesMap).toEqual({Z: 0, 0: 1, A: 2}); - }) - .then(function() { - // should get the same order with relayout - return Plotly.relayout(gd, 'width', 600); - }) - .then(function() { - expect(gd._fullLayout.xaxis._categories).toEqual(['Z', '0', 'A']); - expect(gd._fullLayout.xaxis2._categories).toEqual(['Z', '0', 'A']); - expect(gd._fullLayout.xaxis._categoriesMap).toEqual({Z: 0, 0: 1, A: 2}); - expect(gd._fullLayout.xaxis2._categoriesMap).toEqual({Z: 0, 0: 1, A: 2}); - }) - .then(done, done.fail); + .then(function () { + expect(gd._fullLayout.xaxis._categories).toEqual(['A', 'Z']); + expect(gd._fullLayout.xaxis2._categories).toEqual(['A', 'Z']); + expect(gd._fullLayout.xaxis._categoriesMap).toEqual({ A: 0, Z: 1 }); + expect(gd._fullLayout.xaxis2._categoriesMap).toEqual({ A: 0, Z: 1 }); + }) + .then(function () { + // flip order + fig.data[0].x = ['Z', 'A']; + fig.data[1].x = ['Z', 'A']; + + return Plotly.react(gd, fig); + }) + .then(function () { + expect(gd._fullLayout.xaxis._categories).toEqual(['Z', 'A']); + expect(gd._fullLayout.xaxis2._categories).toEqual(['Z', 'A']); + expect(gd._fullLayout.xaxis._categoriesMap).toEqual({ Z: 0, A: 1 }); + expect(gd._fullLayout.xaxis2._categoriesMap).toEqual({ Z: 0, A: 1 }); + }) + .then(function () { + // should get the same order with newPlot + return Plotly.newPlot(gd, fig); + }) + .then(function () { + expect(gd._fullLayout.xaxis._categories).toEqual(['Z', 'A']); + expect(gd._fullLayout.xaxis2._categories).toEqual(['Z', 'A']); + expect(gd._fullLayout.xaxis._categoriesMap).toEqual({ Z: 0, A: 1 }); + expect(gd._fullLayout.xaxis2._categoriesMap).toEqual({ Z: 0, A: 1 }); + }) + .then(function () { + // add new category + fig.data[0].x = ['Z', 0, 'A']; + fig.data[1].x = ['Z', 0, 'A']; + fig.data[0].y = [1, 2, 3]; + fig.data[1].y = [2, 4, 6]; + + return Plotly.react(gd, fig); + }) + .then(function () { + expect(gd._fullLayout.xaxis._categories).toEqual(['Z', '0', 'A']); + expect(gd._fullLayout.xaxis2._categories).toEqual(['Z', '0', 'A']); + expect(gd._fullLayout.xaxis._categoriesMap).toEqual({ Z: 0, 0: 1, A: 2 }); + expect(gd._fullLayout.xaxis2._categoriesMap).toEqual({ Z: 0, 0: 1, A: 2 }); + }) + .then(function () { + // should get the same order with newPlot + return Plotly.newPlot(gd, fig); + }) + .then(function () { + expect(gd._fullLayout.xaxis._categories).toEqual(['Z', '0', 'A']); + expect(gd._fullLayout.xaxis2._categories).toEqual(['Z', '0', 'A']); + expect(gd._fullLayout.xaxis._categoriesMap).toEqual({ Z: 0, 0: 1, A: 2 }); + expect(gd._fullLayout.xaxis2._categoriesMap).toEqual({ Z: 0, 0: 1, A: 2 }); + }) + .then(function () { + // change data + fig.data[0].x = ['Z', 0, 'A']; + fig.data[1].x = ['A', 'Z']; + fig.data[0].y = [3, 2, 1]; + fig.data[1].y = [-1, 0]; + + return Plotly.react(gd, fig); + }) + .then(function () { + expect(gd._fullLayout.xaxis._categories).toEqual(['Z', '0', 'A']); + expect(gd._fullLayout.xaxis2._categories).toEqual(['Z', '0', 'A']); + expect(gd._fullLayout.xaxis._categoriesMap).toEqual({ Z: 0, 0: 1, A: 2 }); + expect(gd._fullLayout.xaxis2._categoriesMap).toEqual({ Z: 0, 0: 1, A: 2 }); + }) + .then(function () { + // should get the same order with newPlot + return Plotly.newPlot(gd, fig); + }) + .then(function () { + expect(gd._fullLayout.xaxis._categories).toEqual(['Z', '0', 'A']); + expect(gd._fullLayout.xaxis2._categories).toEqual(['Z', '0', 'A']); + expect(gd._fullLayout.xaxis._categoriesMap).toEqual({ Z: 0, 0: 1, A: 2 }); + expect(gd._fullLayout.xaxis2._categoriesMap).toEqual({ Z: 0, 0: 1, A: 2 }); + }) + .then(function () { + // should get the same order with relayout + return Plotly.relayout(gd, 'width', 600); + }) + .then(function () { + expect(gd._fullLayout.xaxis._categories).toEqual(['Z', '0', 'A']); + expect(gd._fullLayout.xaxis2._categories).toEqual(['Z', '0', 'A']); + expect(gd._fullLayout.xaxis._categoriesMap).toEqual({ Z: 0, 0: 1, A: 2 }); + expect(gd._fullLayout.xaxis2._categoriesMap).toEqual({ Z: 0, 0: 1, A: 2 }); + }) + .then(done, done.fail); }); - it('insiderange react to new data', function(done) { + it('insiderange react to new data', function (done) { var layout = { xaxis: { insiderange: [0, 2] @@ -8305,24 +8356,24 @@ describe('more react tests', function() { y: [1000, 3000, 2000] }]; - var fig1 = {data: data1, layout: layout}; - var fig2 = {data: data2, layout: layout}; + var fig1 = { data: data1, layout: layout }; + var fig2 = { data: data2, layout: layout }; Plotly.newPlot(gd, fig1) - .then(function() { - expect(gd._fullLayout.xaxis.range).toBeCloseToArray([-0.12, 2]); + .then(function () { + expect(gd._fullLayout.xaxis.range).toBeCloseToArray([-0.12, 2]); - return Plotly.react(gd, fig2); - }).then(function() { - expect(gd._fullLayout.xaxis.range).toBeCloseToArray([-0.173, 2]); - }).then(done, done.fail); + return Plotly.react(gd, fig2); + }).then(function () { + expect(gd._fullLayout.xaxis.range).toBeCloseToArray([-0.173, 2]); + }).then(done, done.fail); }); }); -describe('category preservation tests on gd passed to Plotly.react()', function() { +describe('category preservation tests on gd passed to Plotly.react()', function () { var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); @@ -8334,7 +8385,7 @@ describe('category preservation tests on gd passed to Plotly.react()', function( Lib.clearThrottle(); } - it('should preserve categories and axis ticklabels', function(done) { + it('should preserve categories and axis ticklabels', function (done) { var fig = { data: [{ type: 'bar', @@ -8349,44 +8400,44 @@ describe('category preservation tests on gd passed to Plotly.react()', function( }; Plotly.newPlot(gd, fig) - .then(function(gd) { - return Plotly.react(gd, fig); - }) - .then(function() { - expect(gd._fullLayout.xaxis._categories).toEqual(['a', 'b', 'c', 'd']); - expect(gd._fullLayout.xaxis._categoriesMap).toEqual({a: 0, b: 1, c: 2, d: 3}); - }) - .then(function() { - _hover(gd, { xval: fig.data[0].x.indexOf('a') }); - expect(d3SelectAll('g.axistext').select('text').html()).toEqual('a'); - }) - .then(function() { - _hover(gd, { xval: fig.data[0].x.indexOf('b') }); - expect(d3SelectAll('g.axistext').select('text').html()).toEqual('b'); - }) - .then(function() { - _hover(gd, { xval: fig.data[0].x.indexOf('c') }); - expect(d3SelectAll('g.axistext').select('text').html()).toEqual('c'); - }) - .then(function() { - _hover(gd, { xval: fig.data[0].x.indexOf('d') }); - expect(d3SelectAll('g.axistext').select('text').html()).toEqual('d'); - }) + .then(function (gd) { + return Plotly.react(gd, fig); + }) + .then(function () { + expect(gd._fullLayout.xaxis._categories).toEqual(['a', 'b', 'c', 'd']); + expect(gd._fullLayout.xaxis._categoriesMap).toEqual({ a: 0, b: 1, c: 2, d: 3 }); + }) + .then(function () { + _hover(gd, { xval: fig.data[0].x.indexOf('a') }); + expect(d3SelectAll('g.axistext').select('text').html()).toEqual('a'); + }) + .then(function () { + _hover(gd, { xval: fig.data[0].x.indexOf('b') }); + expect(d3SelectAll('g.axistext').select('text').html()).toEqual('b'); + }) + .then(function () { + _hover(gd, { xval: fig.data[0].x.indexOf('c') }); + expect(d3SelectAll('g.axistext').select('text').html()).toEqual('c'); + }) + .then(function () { + _hover(gd, { xval: fig.data[0].x.indexOf('d') }); + expect(d3SelectAll('g.axistext').select('text').html()).toEqual('d'); + }) - .then(done, done.fail); + .then(done, done.fail); }); }); -describe('more matching axes tests', function() { +describe('more matching axes tests', function () { var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); afterEach(destroyGraphDiv); - it('should bypass non-string id when matching ids', function(done) { + it('should bypass non-string id when matching ids', function (done) { Plotly.newPlot(gd, { data: [{ x: [0, 1], @@ -8410,14 +8461,14 @@ describe('more matching axes tests', function() { } } }) - .then(done, done.fail); + .then(done, done.fail); }); }); -describe('shift tests', function() { +describe('shift tests', function () { var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); @@ -8429,9 +8480,9 @@ describe('shift tests', function() { afterEach(destroyGraphDiv); - it('should set y-axis shifts correctly on first draw when shift=true', function() { + it('should set y-axis shifts correctly on first draw when shift=true', function () { var fig = require('../../image/mocks/mult-yaxes-simple.json'); - Plotly.newPlot(gd, fig).then(function() { + Plotly.newPlot(gd, fig).then(function () { checkLine('path.xy3-y.crisp', 550); checkLine('path.xy4-y.crisp', 691); expect(gd._fullLayout.yaxis3._shift).toBeCloseTo(97, 2); @@ -8439,9 +8490,9 @@ describe('shift tests', function() { }); }); - it('should set y-axis shifts correctly on first draw when shift=', function() { + it('should set y-axis shifts correctly on first draw when shift=', function () { var fig = require('../../image/mocks/mult-yaxes-manual-shift.json'); - Plotly.newPlot(gd, fig).then(function() { + Plotly.newPlot(gd, fig).then(function () { checkLine('path.xy3-y.crisp', 97); checkLine('path.xy4-y.crisp', 616); expect(gd._fullLayout.yaxis3._shift).toBeCloseTo(-100, 2); @@ -8449,30 +8500,30 @@ describe('shift tests', function() { }); }); }); -describe('test tickmode calculator', function() { +describe('test tickmode calculator', function () { var gd; - beforeEach(function() { + beforeEach(function () { gd = createGraphDiv(); }); afterEach(destroyGraphDiv); function generateTickConfig() { - var standardConfig = {tickmode: 'array', ticks: 'inside', ticklen: 1, showticklabels: false}; + var standardConfig = { tickmode: 'array', ticks: 'inside', ticklen: 1, showticklabels: false }; // Number of ticks will be random Lib.seedPseudoRandom(); var n = (Lib.pseudoRandom() * 99) + 1; var tickVals = []; - for(var i = 0; i <= n; i++) { + for (var i = 0; i <= n; i++) { tickVals.push(i); } standardConfig.tickvals = tickVals; standardConfig.ticktext = tickVals; return standardConfig; } - var ticksOff = {tickmode: 'array', ticks: '', tickvals: [], ticktext: [], ticklen: 0, showticklabels: false}; + var ticksOff = { tickmode: 'array', ticks: '', tickvals: [], ticktext: [], ticklen: 0, showticklabels: false }; function _assert(expLength) { var ax = gd._fullLayout.xaxis; @@ -8480,14 +8531,14 @@ describe('test tickmode calculator', function() { // all positions var positions = ax._vals - .filter(function(d) { return d; }) - .map(function(d) { return d.x; }); + .filter(function (d) { return d; }) + .map(function (d) { return d.x; }); expect(positions.length).toEqual(expLength); } - describe('arrayTicks', function() { - it('should return the specified correct number of major ticks and minor ticks', function(done) { + describe('arrayTicks', function () { + it('should return the specified correct number of major ticks and minor ticks', function (done) { var xMajorConfig = ticksOff; var xMinorConfig = ticksOff; xMajorConfig = generateTickConfig(); @@ -8510,18 +8561,18 @@ describe('test tickmode calculator', function() { }, xaxis: xMajorConfig, } - }).then(function() { + }).then(function () { _assert(xMajorConfig.tickvals.length + xMinorConfig.tickvals.length); }).then(done, done.fail); }); }); - describe('sync', function() { - it('shows the exponent on a synced overlaying axis with showexponent *first*/*last*', function(done) { + describe('sync', function () { + it('shows the exponent on a synced overlaying axis with showexponent *first*/*last*', function (done) { Plotly.newPlot(gd, { data: [ - {y: [0, 6]}, - {y: [0, 60000], yaxis: 'y2'} + { y: [0, 6] }, + { y: [0, 60000], yaxis: 'y2' } ], layout: { yaxis2: { @@ -8530,16 +8581,16 @@ describe('test tickmode calculator', function() { showexponent: 'last' } } - }).then(function() { + }).then(function () { var ax = gd._fullLayout.yaxis2; expect(ax.tickmode).toBe('sync'); var labels = ax._vals - .filter(function(d) { return !d.minor; }) - .map(function(d) { return d.text; }); + .filter(function (d) { return !d.minor; }) + .map(function (d) { return d.text; }); // the multiplier (e.g. 'k') must still appear on the labelled tick - expect(labels.some(function(t) { return /k$/.test(t); })) + expect(labels.some(function (t) { return /k$/.test(t); })) .toBe(true, 'expected an SI prefix in: ' + JSON.stringify(labels)); }).then(done, done.fail); }); diff --git a/test/plot-schema.json b/test/plot-schema.json index cebf8f090da..d6d35f69169 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -5309,6 +5309,13 @@ "impliedEdits": {}, "valType": "any" }, + "minrange": { + "description": "Specifies the minimum span of the computed autorange, in linearized units. If the span is smaller than this value, the autorange is expanded symmetrically to match this minimum span. Has no effect when both `autorangeoptions.minallowed` and `autorangeoptions.maxallowed` are provided and valid. Subject to `autorangeoptions.clipmin` and `autorangeoptions.clipmax`.", + "editType": "plot", + "impliedEdits": {}, + "min": 0, + "valType": "number" + }, "role": "object" }, "autotickangles": { @@ -6726,6 +6733,13 @@ "impliedEdits": {}, "valType": "any" }, + "minrange": { + "description": "Specifies the minimum span of the computed autorange, in linearized units. If the span is smaller than this value, the autorange is expanded symmetrically to match this minimum span. Has no effect when both `autorangeoptions.minallowed` and `autorangeoptions.maxallowed` are provided and valid. Subject to `autorangeoptions.clipmin` and `autorangeoptions.clipmax`.", + "editType": "plot", + "impliedEdits": {}, + "min": 0, + "valType": "number" + }, "role": "object" }, "autotypenumbers": { @@ -7446,6 +7460,13 @@ "impliedEdits": {}, "valType": "any" }, + "minrange": { + "description": "Specifies the minimum span of the computed autorange, in linearized units. If the span is smaller than this value, the autorange is expanded symmetrically to match this minimum span. Has no effect when both `autorangeoptions.minallowed` and `autorangeoptions.maxallowed` are provided and valid. Subject to `autorangeoptions.clipmin` and `autorangeoptions.clipmax`.", + "editType": "plot", + "impliedEdits": {}, + "min": 0, + "valType": "number" + }, "role": "object" }, "autotypenumbers": { @@ -8166,6 +8187,13 @@ "impliedEdits": {}, "valType": "any" }, + "minrange": { + "description": "Specifies the minimum span of the computed autorange, in linearized units. If the span is smaller than this value, the autorange is expanded symmetrically to match this minimum span. Has no effect when both `autorangeoptions.minallowed` and `autorangeoptions.maxallowed` are provided and valid. Subject to `autorangeoptions.clipmin` and `autorangeoptions.clipmax`.", + "editType": "plot", + "impliedEdits": {}, + "min": 0, + "valType": "number" + }, "role": "object" }, "autotypenumbers": { @@ -13034,6 +13062,13 @@ "impliedEdits": {}, "valType": "any" }, + "minrange": { + "description": "Specifies the minimum span of the computed autorange, in linearized units. If the span is smaller than this value, the autorange is expanded symmetrically to match this minimum span. Has no effect when both `autorangeoptions.minallowed` and `autorangeoptions.maxallowed` are provided and valid. Subject to `autorangeoptions.clipmin` and `autorangeoptions.clipmax`.", + "editType": "plot", + "impliedEdits": {}, + "min": 0, + "valType": "number" + }, "role": "object" }, "autotickangles": { @@ -14594,6 +14629,13 @@ "impliedEdits": {}, "valType": "any" }, + "minrange": { + "description": "Specifies the minimum span of the computed autorange, in linearized units. If the span is smaller than this value, the autorange is expanded symmetrically to match this minimum span. Has no effect when both `autorangeoptions.minallowed` and `autorangeoptions.maxallowed` are provided and valid. Subject to `autorangeoptions.clipmin` and `autorangeoptions.clipmax`.", + "editType": "plot", + "impliedEdits": {}, + "min": 0, + "valType": "number" + }, "role": "object" }, "autoshift": {