diff --git a/src/components/rangeslider/draw.js b/src/components/rangeslider/draw.js index 76ef7a04a78..dfefe0098f4 100644 --- a/src/components/rangeslider/draw.js +++ b/src/components/rangeslider/draw.js @@ -77,19 +77,28 @@ module.exports = function(gd) { // update range // Expand slider range to the axis range - // TODO: what if the ranges are reversed? if(opts.range) { - var outRange = opts.range; - var axRange = axisOpts.range; + var rng = Lib.simpleMap(opts.range, axisOpts.r2l); + var axRng = Lib.simpleMap(axisOpts.range, axisOpts.r2l); + var newRng; + + if(axRng[0] < axRng[1]) { + newRng = [ + Math.min(rng[0], axRng[0]), + Math.max(rng[1], axRng[1]) + ]; + } else { + newRng = [ + Math.max(rng[0], axRng[0]), + Math.min(rng[1], axRng[1]) + ]; + } - outRange[0] = axisOpts.l2r(Math.min(axisOpts.r2l(outRange[0]), axisOpts.r2l(axRange[0]))); - outRange[1] = axisOpts.l2r(Math.max(axisOpts.r2l(outRange[1]), axisOpts.r2l(axRange[1]))); - opts._input.range = outRange.slice(); + opts.range = opts._input.range = Lib.simpleMap(newRng, axisOpts.l2r); } axisOpts.cleanRange('rangeslider.range'); - // update range slider dimensions var margin = fullLayout.margin; diff --git a/test/image/baselines/range_slider_reversed-range.png b/test/image/baselines/range_slider_reversed-range.png new file mode 100644 index 00000000000..c4f87c0c31e Binary files /dev/null and b/test/image/baselines/range_slider_reversed-range.png differ diff --git a/test/image/mocks/range_slider_reversed-range.json b/test/image/mocks/range_slider_reversed-range.json new file mode 100644 index 00000000000..fd031523b74 --- /dev/null +++ b/test/image/mocks/range_slider_reversed-range.json @@ -0,0 +1,28 @@ +{ + "data": [ + { + "mode": "lines", + "hoverinfo": "x", + "showlegend": false, + "line": { + "color": "blue" + }, + "x": [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], + "y": [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120] + } + ], + "layout": { + "xaxis": { + "autorange": "reversed", + "zeroline": false, + "rangeslider": { + "yaxis": { + "rangemode": "match" + } + } + }, + "yaxis": { + "visible": false + } + } +} diff --git a/test/jasmine/tests/range_slider_test.js b/test/jasmine/tests/range_slider_test.js index 6ba00809e06..4ed84f4bf69 100644 --- a/test/jasmine/tests/range_slider_test.js +++ b/test/jasmine/tests/range_slider_test.js @@ -1019,6 +1019,76 @@ describe('rangesliders in general', function() { .catch(failTest) .then(done); }); + + it('should give correct rangeslider range on reversed axes', function(done) { + function _assert(msg, exp) { + var xa = gd._fullLayout.xaxis; + + expect(xa.range) + .toBeCloseToArray(exp.axRng, 1, 'x-axis rng ' + msg); + expect(xa.rangeslider.range) + .toBeCloseToArray(exp.rangesliderRng, 1, 'rangeslider rng ' + msg); + expect(xa.rangeslider._input.range) + .toBeCloseToArray(exp.rangesliderRng, 1, 'rangeslider input rng ' + msg); + } + + Plotly.plot(gd, [{ + x: [1, 2, 1] + }], { + xaxis: { rangeslider: {visible: true} } + }) + .then(function() { + _assert('base', { + axRng: [0.935, 2.06], + rangesliderRng: [0.935, 2.06] + }); + + return Plotly.relayout(gd, 'xaxis.autorange', 'reversed'); + }) + .then(function() { + _assert('reversed!', { + axRng: [2.06, 0.935], + rangesliderRng: [2.06, 0.935] + }); + + return Plotly.relayout(gd, 'xaxis.range', [0, 3]); + }) + .then(function() { + _assert('set increasing rng', { + axRng: [0, 3], + rangesliderRng: [0, 3] + }); + + return Plotly.relayout(gd, 'xaxis.range', [3, 0]); + }) + .then(function() { + _assert('set reversed rng', { + axRng: [3, 0], + rangesliderRng: [3, 0] + }); + + return Plotly.relayout(gd, 'xaxis.rangeslider.range', [0, 3]); + }) + .then(function() { + _assert('reversed ax rng / increasing rangeslider rng', { + axRng: [3, 0], + rangesliderRng: [3, 0] + }); + + return Plotly.relayout(gd, { + 'xaxis.range': [0, 3], + 'xaxis.rangeslider.range': [3, 0] + }); + }) + .then(function() { + _assert('increasing ax rng / reversed rangeslider rng', { + axRng: [0, 3], + rangesliderRng: [0, 3] + }); + }) + .catch(failTest) + .then(done); + }); }); function slide(fromX, fromY, toX, toY) {