diff --git a/src/plots/geo/zoom.js b/src/plots/geo/zoom.js index ac5d234e9b1..f55e123f202 100644 --- a/src/plots/geo/zoom.js +++ b/src/plots/geo/zoom.js @@ -109,14 +109,19 @@ function zoomNonClipped(geo, projection) { var INSIDETOLORANCEPXS = 2; var mouse0, rotate0, translate0, lastRotate, zoomPoint, - mouse1, rotate1, point1; + mouse1, rotate1, point1, didZoom; function position(x) { return projection.invert(x); } function outside(x) { - var pt = projection(position(x)); - return (Math.abs(pt[0] - x[0]) > INSIDETOLORANCEPXS || - Math.abs(pt[1] - x[1]) > INSIDETOLORANCEPXS); + var pos = position(x); + if(!pos) return true; + + var pt = projection(pos); + return ( + Math.abs(pt[0] - x[0]) > INSIDETOLORANCEPXS || + Math.abs(pt[1] - x[1]) > INSIDETOLORANCEPXS + ); } function handleZoomstart() { @@ -152,12 +157,13 @@ function zoomNonClipped(geo, projection) { lastRotate = rotate1; } + didZoom = true; geo.render(); } function handleZoomend() { d3.select(this).style(zoomendStyle); - sync(geo, projection, syncCb); + if(didZoom) sync(geo, projection, syncCb); } function syncCb(set) { diff --git a/test/jasmine/tests/geo_test.js b/test/jasmine/tests/geo_test.js index 6adcea5c2df..2f7adc53849 100644 --- a/test/jasmine/tests/geo_test.js +++ b/test/jasmine/tests/geo_test.js @@ -10,7 +10,7 @@ var topojsonUtils = require('@src/lib/topojson_utils'); var d3 = require('d3'); var createGraphDiv = require('../assets/create_graph_div'); var destroyGraphDiv = require('../assets/destroy_graph_div'); -var fail = require('../assets/fail_test'); +var failTest = require('../assets/fail_test'); var getClientPosition = require('../assets/get_client_position'); var mouseEvent = require('../assets/mouse_event'); var click = require('../assets/click'); @@ -1068,7 +1068,7 @@ describe('Test geo interactions', function() { mouseEvent('mousemove', 350, 250); expect(d3.selectAll('g.hovertext').size()).toEqual(1); }) - .catch(fail) + .catch(failTest) .then(done); }); @@ -1109,7 +1109,7 @@ describe('Test geo interactions', function() { }, 100); }); }) - .catch(fail) + .catch(failTest) .then(done); }); @@ -1138,7 +1138,7 @@ describe('Test geo interactions', function() { check([px, 163], 0); check([px, 360], 1); }) - .catch(fail) + .catch(failTest) .then(done); }); @@ -1198,7 +1198,7 @@ describe('Test geo interactions', function() { 'Invalid geo settings, relayout\'ing to default view.' ); }) - .catch(fail) + .catch(failTest) .then(done); }); @@ -1249,7 +1249,7 @@ describe('Test geo interactions', function() { .then(function() { check([-150, -89], 1, 'spot in Antarctica that requires *stitching*'); }) - .catch(fail) + .catch(failTest) .then(done); }); }); @@ -1518,7 +1518,7 @@ describe('Test geo base layers', function() { ['bg', 'coastlines', 'frame', 'backplot', 'frontplot'] ); }) - .catch(fail) + .catch(failTest) .then(done); }); }); @@ -1686,7 +1686,7 @@ describe('Test geo zoom/pan/drag interactions:', function() { [90, 0], [350, 260], [0, 0], 101.9 ], 'dblclick'); }) - .catch(fail) + .catch(failTest) .then(done); }); @@ -1775,7 +1775,7 @@ describe('Test geo zoom/pan/drag interactions:', function() { [75, -45], 160 ], 'dblclick'); }) - .catch(fail) + .catch(failTest) .then(done); }); @@ -1858,7 +1858,7 @@ describe('Test geo zoom/pan/drag interactions:', function() { [247, 260], [0, 57.5], 292.2 ], 'dblclick'); }) - .catch(fail) + .catch(failTest) .then(done); }); @@ -1938,7 +1938,27 @@ describe('Test geo zoom/pan/drag interactions:', function() { [416, 309], 738.5 ], 'dblclick'); }) - .catch(fail) + .catch(failTest) + .then(done); + }); + + it('should guard againt undefined projection.invert result in some projections', function(done) { + // e.g. aitoff + var fig = Lib.extendDeep({}, require('@mocks/geo_aitoff-sinusoidal.json')); + fig.layout.dragmode = 'pan'; + delete fig.layout.geo2; + fig.data = [fig.data[0]]; + fig.layout.width = 700; + fig.layout.height = 500; + + plot(fig) + .then(function() { return scroll([131, 159], [-200, 200]); }) + .then(function() { + // scrolling outside subplot frame should log errors, + // nor emit events + expect(eventData).toBeUndefined(); + }) + .catch(failTest) .then(done); }); });