Skip to content

Commit e605853

Browse files
authored
Merge pull request #2811 from plotly/projection-invert-fixup
Guard against undefined projection.invert results
2 parents 918ed9c + 878d375 commit e605853

File tree

2 files changed

+42
-16
lines changed

2 files changed

+42
-16
lines changed

src/plots/geo/zoom.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,19 @@ function zoomNonClipped(geo, projection) {
109109
var INSIDETOLORANCEPXS = 2;
110110

111111
var mouse0, rotate0, translate0, lastRotate, zoomPoint,
112-
mouse1, rotate1, point1;
112+
mouse1, rotate1, point1, didZoom;
113113

114114
function position(x) { return projection.invert(x); }
115115

116116
function outside(x) {
117-
var pt = projection(position(x));
118-
return (Math.abs(pt[0] - x[0]) > INSIDETOLORANCEPXS ||
119-
Math.abs(pt[1] - x[1]) > INSIDETOLORANCEPXS);
117+
var pos = position(x);
118+
if(!pos) return true;
119+
120+
var pt = projection(pos);
121+
return (
122+
Math.abs(pt[0] - x[0]) > INSIDETOLORANCEPXS ||
123+
Math.abs(pt[1] - x[1]) > INSIDETOLORANCEPXS
124+
);
120125
}
121126

122127
function handleZoomstart() {
@@ -152,12 +157,13 @@ function zoomNonClipped(geo, projection) {
152157
lastRotate = rotate1;
153158
}
154159

160+
didZoom = true;
155161
geo.render();
156162
}
157163

158164
function handleZoomend() {
159165
d3.select(this).style(zoomendStyle);
160-
sync(geo, projection, syncCb);
166+
if(didZoom) sync(geo, projection, syncCb);
161167
}
162168

163169
function syncCb(set) {

test/jasmine/tests/geo_test.js

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ var topojsonUtils = require('@src/lib/topojson_utils');
1010
var d3 = require('d3');
1111
var createGraphDiv = require('../assets/create_graph_div');
1212
var destroyGraphDiv = require('../assets/destroy_graph_div');
13-
var fail = require('../assets/fail_test');
13+
var failTest = require('../assets/fail_test');
1414
var getClientPosition = require('../assets/get_client_position');
1515
var mouseEvent = require('../assets/mouse_event');
1616
var click = require('../assets/click');
@@ -1068,7 +1068,7 @@ describe('Test geo interactions', function() {
10681068
mouseEvent('mousemove', 350, 250);
10691069
expect(d3.selectAll('g.hovertext').size()).toEqual(1);
10701070
})
1071-
.catch(fail)
1071+
.catch(failTest)
10721072
.then(done);
10731073
});
10741074

@@ -1109,7 +1109,7 @@ describe('Test geo interactions', function() {
11091109
}, 100);
11101110
});
11111111
})
1112-
.catch(fail)
1112+
.catch(failTest)
11131113
.then(done);
11141114
});
11151115

@@ -1138,7 +1138,7 @@ describe('Test geo interactions', function() {
11381138
check([px, 163], 0);
11391139
check([px, 360], 1);
11401140
})
1141-
.catch(fail)
1141+
.catch(failTest)
11421142
.then(done);
11431143
});
11441144

@@ -1198,7 +1198,7 @@ describe('Test geo interactions', function() {
11981198
'Invalid geo settings, relayout\'ing to default view.'
11991199
);
12001200
})
1201-
.catch(fail)
1201+
.catch(failTest)
12021202
.then(done);
12031203
});
12041204

@@ -1249,7 +1249,7 @@ describe('Test geo interactions', function() {
12491249
.then(function() {
12501250
check([-150, -89], 1, 'spot in Antarctica that requires *stitching*');
12511251
})
1252-
.catch(fail)
1252+
.catch(failTest)
12531253
.then(done);
12541254
});
12551255
});
@@ -1518,7 +1518,7 @@ describe('Test geo base layers', function() {
15181518
['bg', 'coastlines', 'frame', 'backplot', 'frontplot']
15191519
);
15201520
})
1521-
.catch(fail)
1521+
.catch(failTest)
15221522
.then(done);
15231523
});
15241524
});
@@ -1686,7 +1686,7 @@ describe('Test geo zoom/pan/drag interactions:', function() {
16861686
[90, 0], [350, 260], [0, 0], 101.9
16871687
], 'dblclick');
16881688
})
1689-
.catch(fail)
1689+
.catch(failTest)
16901690
.then(done);
16911691
});
16921692

@@ -1775,7 +1775,7 @@ describe('Test geo zoom/pan/drag interactions:', function() {
17751775
[75, -45], 160
17761776
], 'dblclick');
17771777
})
1778-
.catch(fail)
1778+
.catch(failTest)
17791779
.then(done);
17801780
});
17811781

@@ -1858,7 +1858,7 @@ describe('Test geo zoom/pan/drag interactions:', function() {
18581858
[247, 260], [0, 57.5], 292.2
18591859
], 'dblclick');
18601860
})
1861-
.catch(fail)
1861+
.catch(failTest)
18621862
.then(done);
18631863
});
18641864

@@ -1938,7 +1938,27 @@ describe('Test geo zoom/pan/drag interactions:', function() {
19381938
[416, 309], 738.5
19391939
], 'dblclick');
19401940
})
1941-
.catch(fail)
1941+
.catch(failTest)
1942+
.then(done);
1943+
});
1944+
1945+
it('should guard againt undefined projection.invert result in some projections', function(done) {
1946+
// e.g. aitoff
1947+
var fig = Lib.extendDeep({}, require('@mocks/geo_aitoff-sinusoidal.json'));
1948+
fig.layout.dragmode = 'pan';
1949+
delete fig.layout.geo2;
1950+
fig.data = [fig.data[0]];
1951+
fig.layout.width = 700;
1952+
fig.layout.height = 500;
1953+
1954+
plot(fig)
1955+
.then(function() { return scroll([131, 159], [-200, 200]); })
1956+
.then(function() {
1957+
// scrolling outside subplot frame should log errors,
1958+
// nor emit events
1959+
expect(eventData).toBeUndefined();
1960+
})
1961+
.catch(failTest)
19421962
.then(done);
19431963
});
19441964
});

0 commit comments

Comments
 (0)