diff --git a/src/lib/index.js b/src/lib/index.js index 0a3d8bf7854..9f3686462e4 100644 --- a/src/lib/index.js +++ b/src/lib/index.js @@ -484,6 +484,35 @@ lib.setScale = function(element, x, y) { return transform; }; +lib.setPointGroupScale = function(selection, x, y) { + var t, scale, re; + + x = x || 1; + y = y || 1; + + if(x === 1 && y === 1) { + scale = ''; + } else { + // The same scale transform for every point: + scale = ' scale(' + x + ',' + y + ')'; + } + + // A regex to strip any existing scale: + re = /\s*sc.*/; + + selection.each(function() { + // Get the transform: + t = (this.getAttribute('transform') || '').replace(re, ''); + t += scale; + t = t.trim(); + + // Append the scale transform + this.setAttribute('transform', t); + }); + + return scale; +}; + lib.isIE = function() { return typeof window.navigator.msSaveBlob !== 'undefined'; }; diff --git a/src/plots/cartesian/dragbox.js b/src/plots/cartesian/dragbox.js index ff6f7bc52bf..5b18574482f 100644 --- a/src/plots/cartesian/dragbox.js +++ b/src/plots/cartesian/dragbox.js @@ -633,7 +633,13 @@ module.exports = function dragBox(gd, plotinfo, x, y, w, h, ns, ew) { subplot.plot .call(Lib.setTranslate, plotDx, plotDy) - .call(Lib.setScale, xScaleFactor, yScaleFactor); + .call(Lib.setScale, xScaleFactor, yScaleFactor) + + // This is specifically directed at scatter traces, applying an inverse + // scale to individual points to counteract the scale of the trace + // as a whole: + .selectAll('.points').selectAll('.point') + .call(Lib.setPointGroupScale, 1 / xScaleFactor, 1 / yScaleFactor); } } diff --git a/test/jasmine/tests/lib_test.js b/test/jasmine/tests/lib_test.js index 02c0595b094..b25821f9fd0 100644 --- a/test/jasmine/tests/lib_test.js +++ b/test/jasmine/tests/lib_test.js @@ -1202,6 +1202,44 @@ describe('Test lib.js:', function() { }); }); + describe('setPointGroupScale', function() { + var el, sel; + + beforeEach(function() { + el = document.createElement('div'); + sel = d3.select(el); + }); + + it('sets the scale of a point', function() { + Lib.setPointGroupScale(sel, 2, 2); + expect(el.getAttribute('transform')).toBe('scale(2,2)'); + }); + + it('appends the scale of a point', function() { + el.setAttribute('transform', 'translate(1,2)'); + Lib.setPointGroupScale(sel, 2, 2); + expect(el.getAttribute('transform')).toBe('translate(1,2) scale(2,2)'); + }); + + it('modifies the scale of a point', function() { + el.setAttribute('transform', 'translate(1,2) scale(3,4)'); + Lib.setPointGroupScale(sel, 2, 2); + expect(el.getAttribute('transform')).toBe('translate(1,2) scale(2,2)'); + }); + + it('does not apply the scale of a point if scale (1, 1)', function() { + el.setAttribute('transform', 'translate(1,2)'); + Lib.setPointGroupScale(sel, 1, 1); + expect(el.getAttribute('transform')).toBe('translate(1,2)'); + }); + + it('removes the scale of a point if scale (1, 1)', function() { + el.setAttribute('transform', 'translate(1,2) scale(3,4)'); + Lib.setPointGroupScale(sel, 1, 1); + expect(el.getAttribute('transform')).toBe('translate(1,2)'); + }); + }); + describe('pushUnique', function() { beforeEach(function() {