diff --git a/src/components/rangeslider/create_slider.js b/src/components/rangeslider/create_slider.js index 61d6854e783..83caa2ad7eb 100644 --- a/src/components/rangeslider/create_slider.js +++ b/src/components/rangeslider/create_slider.js @@ -141,27 +141,49 @@ module.exports = function createSlider(gd) { window.addEventListener('mouseup', mouseUp); function mouseMove(e) { - var delta = +e.clientX - startX; + var delta = +e.clientX - startX, + pixelMin, + pixelMax; switch(target) { case slideBox: slider.style.cursor = 'ew-resize'; - setPixelRange(+maxVal + delta, +minVal + delta); + + pixelMin = +minVal + delta; + pixelMax = +maxVal + delta; + + setPixelRange(pixelMin, pixelMax); + setDataRange(pixelToData(pixelMin), pixelToData(pixelMax)); break; case grabAreaMin: slider.style.cursor = 'col-resize'; - setPixelRange(+minVal + delta, +maxVal); + + pixelMin = +minVal + delta; + pixelMax = +maxVal; + + setPixelRange(pixelMin, pixelMax); + setDataRange(pixelToData(pixelMin), pixelToData(pixelMax)); break; case grabAreaMax: slider.style.cursor = 'col-resize'; - setPixelRange(+minVal, +maxVal + delta); + + pixelMin = +minVal; + pixelMax = +maxVal + delta; + + setPixelRange(pixelMin, pixelMax); + setDataRange(pixelToData(pixelMin), pixelToData(pixelMax)); break; default: slider.style.cursor = 'ew-resize'; - setPixelRange(offsetX, offsetX + delta); + + pixelMin = offsetX; + pixelMax = offsetX + delta; + + setPixelRange(pixelMin, pixelMax); + setDataRange(pixelToData(pixelMin), pixelToData(pixelMax)); break; } } @@ -173,6 +195,17 @@ module.exports = function createSlider(gd) { } }); + function pixelToData(pixel) { + var rangeMin = options.range[0], + rangeMax = options.range[1], + range = rangeMax - rangeMin, + dataValue = pixel / width * range + rangeMin; + + dataValue = Lib.constrain(dataValue, rangeMin, rangeMax); + + return dataValue; + } + function setRange(min, max) { min = min || -Infinity; @@ -187,52 +220,49 @@ module.exports = function createSlider(gd) { setPixelRange(pixelMin, pixelMax); } + function setDataRange(dataMin, dataMax) { + + if(window.requestAnimationFrame) { + window.requestAnimationFrame(function() { + Plotly.relayout(gd, 'xaxis.range', [dataMin, dataMax]); + }); + } else { + setTimeout(function() { + Plotly.relayout(gd, 'xaxis.range', [dataMin, dataMax]); + }, 16); + } + } - function setPixelRange(min, max) { - min = Lib.constrain(min, 0, width); - max = Lib.constrain(max, 0, width); + function setPixelRange(pixelMin, pixelMax) { - if(max < min) { - var temp = max; - max = min; - min = temp; + pixelMin = Lib.constrain(pixelMin, 0, width); + pixelMax = Lib.constrain(pixelMax, 0, width); + + if(pixelMax < pixelMin) { + var temp = pixelMax; + pixelMax = pixelMin; + pixelMin = temp; } helpers.setAttributes(slider, { - 'data-min': min, - 'data-max': max + 'data-min': pixelMin, + 'data-max': pixelMax }); helpers.setAttributes(slideBox, { - 'x': min, - 'width': max - min + 'x': pixelMin, + 'width': pixelMax - pixelMin }); - helpers.setAttributes(maskMin, { 'width': min }); + helpers.setAttributes(maskMin, { 'width': pixelMin }); helpers.setAttributes(maskMax, { - 'x': max, - 'width': width - max + 'x': pixelMax, + 'width': width - pixelMax }); - helpers.setAttributes(grabberMin, { 'transform': 'translate(' + (min - handleWidth - 1) + ')' }); - helpers.setAttributes(grabberMax, { 'transform': 'translate(' + max + ')' }); - - var rangeMin = options.range[0], - rangeMax = options.range[1], - range = rangeMax - rangeMin, - dataMin = min / width * range + rangeMin, - dataMax = max / width * range + rangeMin; - - if(window.requestAnimationFrame) { - window.requestAnimationFrame(function() { - Plotly.relayout(gd, 'xaxis.range', [dataMin, dataMax]); - }); - } else { - setTimeout(function() { - Plotly.relayout(gd, 'xaxis.range', [dataMin, dataMax]); - }, 16); - } + helpers.setAttributes(grabberMin, { 'transform': 'translate(' + (pixelMin - handleWidth - 1) + ')' }); + helpers.setAttributes(grabberMax, { 'transform': 'translate(' + pixelMax + ')' }); } diff --git a/src/lib/index.js b/src/lib/index.js index 13a053004c4..72177b36ac5 100644 --- a/src/lib/index.js +++ b/src/lib/index.js @@ -256,17 +256,6 @@ lib.smooth = function(arrayIn, FWHM) { return arrayOut; }; -// helpers for promises - -/** - * promiseError: log errors properly inside promises - * use: - * .then(undefined,Plotly.Lib.promiseError) (for IE compatibility) - * or .catch(Plotly.Lib.promiseError) - * TODO: I guess we need another step to send this error to Sentry? - */ -lib.promiseError = function(err) { console.log(err, err.stack); }; - /** * syncOrAsync: run a sequence of functions synchronously * as long as its returns are not promises (ie have no .then) diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js index f567d260680..2da62220350 100644 --- a/src/plot_api/plot_api.js +++ b/src/plot_api/plot_api.js @@ -2438,8 +2438,9 @@ Plotly.relayout = function relayout(gd, astr, val) { } function setRange(changes) { - var newMin = changes['xaxis.range[0]'], - newMax = changes['xaxis.range[1]']; + + var newMin = changes['xaxis.range'] ? changes['xaxis.range'][0] : changes['xaxis.range[0]'], + newMax = changes['xaxis.range'] ? changes['xaxis.range'][1] : changes['xaxis.range[1]']; var rangeSlider = fullLayout.xaxis && fullLayout.xaxis.rangeslider ? fullLayout.xaxis.rangeslider : {}; diff --git a/test/jasmine/tests/range_slider_test.js b/test/jasmine/tests/range_slider_test.js index 17d7ff808d6..a603c21b324 100644 --- a/test/jasmine/tests/range_slider_test.js +++ b/test/jasmine/tests/range_slider_test.js @@ -137,6 +137,25 @@ describe('the range slider', function() { expect(rangeDiff3).toBeLessThan(rangeDiff2); }).then(done); }); + + it('should relayout with relayout "array syntax"', function(done) { + Plotly.relayout(gd, 'xaxis.range', [10, 20]) + .then(function() { + expect(gd._fullLayout.xaxis.range).toEqual([10, 20]); + expect(+rangeSlider.getAttribute('data-min')).toBeCloseTo(125.51, 0); + expect(+rangeSlider.getAttribute('data-max')).toBeCloseTo(251.02, 0); + }) + .then(done); + }); + + it('should relayout with relayout "element syntax"', function(done) { + Plotly.relayout(gd, 'xaxis.range[0]', 10) + .then(function() { + expect(gd._fullLayout.xaxis.range[0]).toEqual(10); + expect(+rangeSlider.getAttribute('data-min')).toBeCloseTo(125.51, 0); + }) + .then(done); + }); });