Skip to content

Commit 2ddd334

Browse files
mojoaxelcamdecoster
authored andcommitted
feat(geo): support min/max scale limits
fixes #5191
1 parent 24478b5 commit 2ddd334

File tree

5 files changed

+43
-0
lines changed

5 files changed

+43
-0
lines changed

src/components/modebar/buttons.js

+10
Original file line numberDiff line numberDiff line change
@@ -543,8 +543,18 @@ function handleGeo(gd, ev) {
543543

544544
if(attr === 'zoom') {
545545
var scale = geoLayout.projection.scale;
546+
var minScale = geoLayout.projection.minScale;
547+
var maxScale = geoLayout.projection.maxScale;
548+
546549
var newScale = (val === 'in') ? 2 * scale : 0.5 * scale;
547550

551+
// make sure the scale is within the min/max bounds
552+
if(newScale > maxScale) {
553+
newScale = maxScale;
554+
} else if(newScale < minScale) {
555+
newScale = minScale;
556+
}
557+
548558
Registry.call('_guiRelayout', gd, id + '.projection.scale', newScale);
549559
}
550560
}

src/plots/geo/geo.js

+8
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,14 @@ function getProjection(geoLayout) {
709709

710710
projection.precision(constants.precision);
711711

712+
// https://github.com/d3/d3-zoom/blob/master/README.md#zoom_scaleExtent
713+
projection.scaleExtent = function() {
714+
var minscale = projLayout.minscale;
715+
var maxscale = projLayout.maxscale;
716+
if(maxscale === -1) maxscale = Infinity;
717+
return [100 * minscale, 100 * maxscale];
718+
};
719+
712720
if(geoLayout._isSatellite) {
713721
projection.tilt(projLayout.tilt).distance(projLayout.distance);
714722
}

src/plots/geo/layout_attributes.js

+20
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,26 @@ var attrs = module.exports = overrideAll({
177177
'that fits the map\'s lon and lat ranges. '
178178
].join(' ')
179179
},
180+
minScale: {
181+
valType: 'number',
182+
min: 0,
183+
dflt: 0,
184+
description: [
185+
'Minimal zoom level of the map view.',
186+
'A minScale of *0.5* (50%) corresponds to a zoom level',
187+
'where the map has half the size of base zoom level.'
188+
].join(' ')
189+
},
190+
maxScale: {
191+
valType: 'number',
192+
min: 0,
193+
dflt: Infinity,
194+
description: [
195+
'Maximal zoom level of the map view.',
196+
'A maxScale of *2* (200%) corresponds to a zoom level',
197+
'where the map is twice as big as the base layer.'
198+
].join(' ')
199+
},
180200
},
181201
center: {
182202
lon: {

src/plots/geo/layout_defaults.js

+4
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ function handleGeoDefaults(geoLayoutIn, geoLayoutOut, coerce, opts) {
161161
}
162162

163163
coerce('projection.scale');
164+
coerce('projection.minScale');
165+
coerce('projection.maxScale');
164166

165167
show = coerce('showland', !visible ? false : undefined);
166168
if(show) coerce('landcolor');
@@ -205,6 +207,8 @@ function handleGeoDefaults(geoLayoutIn, geoLayoutOut, coerce, opts) {
205207
// clear attributes that will get auto-filled later
206208
if(fitBounds) {
207209
delete geoLayoutOut.projection.scale;
210+
delete geoLayoutOut.projection.minScale;
211+
delete geoLayoutOut.projection.maxScale;
208212

209213
if(isScoped) {
210214
delete geoLayoutOut.center.lon;

src/plots/geo/zoom.js

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ module.exports = createGeoZoom;
3232
function initZoom(geo, projection) {
3333
return d3.behavior.zoom()
3434
.translate(projection.translate())
35+
.scaleExtent(projection.scaleExtent())
3536
.scale(projection.scale());
3637
}
3738

0 commit comments

Comments
 (0)