8000 feat: Add min/max scale limits for geo plots by camdecoster · Pull Request #7371 · plotly/plotly.js · GitHub
[go: up one dir, main page]

Skip to content

feat: Add min/max scale limits for geo plots #7371

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 12 commits into
base: master
Choose a base branch
from
Draft
Next Next commit
feat(geo): support min/max scale limits
fixes #5191
  • Loading branch information
mojoaxel authored and camdecoster committed Feb 18, 2025
commit 57307ee8ab72d4e8555e97af8168c30dfd9f0b8d
10 changes: 10 additions & 0 deletions src/components/modebar/buttons.js
Original file line number Diff line number Diff line change
Expand Up @@ -543,8 +543,18 @@ function handleGeo(gd, ev) {

if(attr === 'zoom') {
var scale = geoLayout.projection.scale;
var minScale = geoLayout.projection.minScale;
var maxScale = geoLayout.projection.maxScale;

var newScale = (val === 'in') ? 2 * scale : 0.5 * scale;

// make sure the scale is within the min/max bounds
if(newScale > maxScale) {
newScale = maxScale;
} else if(newScale < minScale) {
newScale = minScale;
}

Registry.call('_guiRelayout', gd, id + '.projection.scale', newScale);
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/plots/geo/geo.js
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,14 @@ function getProjection(geoLayout) {

projection.precision(constants.precision);

// https://github.com/d3/d3-zoom/blob/master/README.md#zoom_scaleExtent
projection.scaleExtent = function() {
var minscale = projLayout.minscale;
var maxscale = projLayout.maxscale;
if(maxscale === -1) maxscale = Infinity;
return [100 * minscale, 100 * maxscale];
};

if(geoLayout._isSatellite) {
projection.tilt(projLayout.tilt).distance(projLayout.distance);
}
Expand Down
20 changes: 20 additions & 0 deletions src/plots/geo/layout_attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,26 @@ var attrs = module.exports = overrideAll({
'that fits the map\'s lon and lat ranges. '
].join(' ')
},
minScale: {
valType: 'number',
min: 0,
dflt: 0,
description: [
'Minimal zoom level of the map view.',
'A minScale of *0.5* (50%) corresponds to a zoom level',
'where the map has half the size of base zoom level.'
].join(' ')
},
maxScale: {
valType: 'number',
min: 0,
dflt: Infinity,
description: [
'Maximal zoom level of the map view.',
'A maxScale of *2* (200%) corresponds to a zoom level',
'where the map is twice as big as the base layer.'
].join(' ')
},
},
center: {
lon: {
Expand Down
4 changes: 4 additions & 0 deletions src/plots/geo/layout_defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ function handleGeoDefaults(geoLayoutIn, geoLayoutOut, coerce, opts) {
}

coerce('projection.scale');
coerce('projection.minScale');
coerce('projection.maxScale');

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

if(isScoped) {
delete geoLayoutOut.center.lon;
Expand Down
1 change: 1 addition & 0 deletions src/plots/geo/zoom.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module.exports = createGeoZoom;
function initZoom(geo, projection) {
return d3.behavior.zoom()
.translate(projection.translate())
.scaleExtent(projection.scaleExtent())
.scale(projection.scale());
}

Expand Down
0