From 57307ee8ab72d4e8555e97af8168c30dfd9f0b8d Mon Sep 17 00:00:00 2001 From: Alexander Wunschik Date: Mon, 5 Oct 2020 17:15:12 +0200 Subject: [PATCH 01/11] feat(geo): support min/max scale limits fixes #5191 --- src/components/modebar/buttons.js | 10 ++++++++++ src/plots/geo/geo.js | 8 ++++++++ src/plots/geo/layout_attributes.js | 20 ++++++++++++++++++++ src/plots/geo/layout_defaults.js | 4 ++++ src/plots/geo/zoom.js | 1 + 5 files changed, 43 insertions(+) diff --git a/src/components/modebar/buttons.js b/src/components/modebar/buttons.js index 82c5dff9a48..ee5452beb55 100644 --- a/src/components/modebar/buttons.js +++ b/src/components/modebar/buttons.js @@ -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); } } diff --git a/src/plots/geo/geo.js b/src/plots/geo/geo.js index 797ab8373b6..1ad80e5e30f 100644 --- a/src/plots/geo/geo.js +++ b/src/plots/geo/geo.js @@ -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); } diff --git a/src/plots/geo/layout_attributes.js b/src/plots/geo/layout_attributes.js index b94cca3bec5..bdfa0118219 100644 --- a/src/plots/geo/layout_attributes.js +++ b/src/plots/geo/layout_attributes.js @@ -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: { diff --git a/src/plots/geo/layout_defaults.js b/src/plots/geo/layout_defaults.js index a5d64e2e9f8..35f1fe804e3 100644 --- a/src/plots/geo/layout_defaults.js +++ b/src/plots/geo/layout_defaults.js @@ -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'); @@ -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; diff --git a/src/plots/geo/zoom.js b/src/plots/geo/zoom.js index 2d79d69f581..824ba39a0ef 100644 --- a/src/plots/geo/zoom.js +++ b/src/plots/geo/zoom.js @@ -32,6 +32,7 @@ module.exports = createGeoZoom; function initZoom(geo, projection) { return d3.behavior.zoom() .translate(projection.translate()) + .scaleExtent(projection.scaleExtent()) .scale(projection.scale()); } From d870252e3e2d2838f39b6ca996f704fba106fefe Mon Sep 17 00:00:00 2001 From: Alexander Wunschik Date: Mon, 26 Oct 2020 20:11:21 +0100 Subject: [PATCH 02/11] refactor: rename min/max scale limits --- src/components/modebar/buttons.js | 12 ++++++------ src/plots/geo/layout_attributes.js | 6 +++--- src/plots/geo/layout_defaults.js | 8 ++++---- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/components/modebar/buttons.js b/src/components/modebar/buttons.js index ee5452beb55..6a112726f22 100644 --- a/src/components/modebar/buttons.js +++ b/src/components/modebar/buttons.js @@ -543,16 +543,16 @@ function handleGeo(gd, ev) { if(attr === 'zoom') { var scale = geoLayout.projection.scale; - var minScale = geoLayout.projection.minScale; - var maxScale = geoLayout.projection.maxScale; + 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; + if(newScale > maxscale) { + newScale = maxscale; + } else if(newScale < minscale) { + newScale = minscale; } Registry.call('_guiRelayout', gd, id + '.projection.scale', newScale); diff --git a/src/plots/geo/layout_attributes.js b/src/plots/geo/layout_attributes.js index bdfa0118219..00421328516 100644 --- a/src/plots/geo/layout_attributes.js +++ b/src/plots/geo/layout_attributes.js @@ -177,7 +177,7 @@ var attrs = module.exports = overrideAll({ 'that fits the map\'s lon and lat ranges. ' ].join(' ') }, - minScale: { + minscale: { valType: 'number', min: 0, dflt: 0, @@ -187,10 +187,10 @@ var attrs = module.exports = overrideAll({ 'where the map has half the size of base zoom level.' ].join(' ') }, - maxScale: { + maxscale: { valType: 'number', min: 0, - dflt: Infinity, + dflt: null, description: [ 'Maximal zoom level of the map view.', 'A maxScale of *2* (200%) corresponds to a zoom level', diff --git a/src/plots/geo/layout_defaults.js b/src/plots/geo/layout_defaults.js index 35f1fe804e3..8848f5b7f05 100644 --- a/src/plots/geo/layout_defaults.js +++ b/src/plots/geo/layout_defaults.js @@ -161,8 +161,8 @@ function handleGeoDefaults(geoLayoutIn, geoLayoutOut, coerce, opts) { } coerce('projection.scale'); - coerce('projection.minScale'); - coerce('projection.maxScale'); + coerce('projection.minscale'); + coerce('projection.maxscale'); show = coerce('showland', !visible ? false : undefined); if(show) coerce('landcolor'); @@ -207,8 +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; + delete geoLayoutOut.projection.minscale; + delete geoLayoutOut.projection.maxscale; if(isScoped) { delete geoLayoutOut.center.lon; From 2d9e5f2726383a3cb6aa5dce4635733fd2d6f881 Mon Sep 17 00:00:00 2001 From: Alexander Wunschik Date: Mon, 26 Oct 2020 20:43:18 +0100 Subject: [PATCH 03/11] chore: use dflt: -1 instad of null --- src/components/modebar/buttons.js | 1 + src/plots/geo/layout_attributes.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/modebar/buttons.js b/src/components/modebar/buttons.js index 6a112726f22..b0340856f68 100644 --- a/src/components/modebar/buttons.js +++ b/src/components/modebar/buttons.js @@ -546,6 +546,7 @@ function handleGeo(gd, ev) { var minscale = geoLayout.projection.minscale; var maxscale = geoLayout.projection.maxscale; + if(maxscale < 0) maxscale = Infinity; var newScale = (val === 'in') ? 2 * scale : 0.5 * scale; // make sure the scale is within the min/max bounds diff --git a/src/plots/geo/layout_attributes.js b/src/plots/geo/layout_attributes.js index 00421328516..69a49acaa44 100644 --- a/src/plots/geo/layout_attributes.js +++ b/src/plots/geo/layout_attributes.js @@ -190,7 +190,7 @@ var attrs = module.exports = overrideAll({ maxscale: { valType: 'number', min: 0, - dflt: null, + dflt: -1, description: [ 'Maximal zoom level of the map view.', 'A maxScale of *2* (200%) corresponds to a zoom level', From dd635ee36c1435fb50a1839348f546721bd1192a Mon Sep 17 00:00:00 2001 From: Alexander Wunschik Date: Mon, 26 Oct 2020 21:26:40 +0100 Subject: [PATCH 04/11] feat: handle maxscale default in scaleExtent --- src/components/modebar/buttons.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/modebar/buttons.js b/src/components/modebar/buttons.js index b0340856f68..6d7930063cc 100644 --- a/src/components/modebar/buttons.js +++ b/src/components/modebar/buttons.js @@ -546,7 +546,7 @@ function handleGeo(gd, ev) { var minscale = geoLayout.projection.minscale; var maxscale = geoLayout.projection.maxscale; - if(maxscale < 0) maxscale = Infinity; + if(maxscale === -1) maxscale = Infinity; var newScale = (val === 'in') ? 2 * scale : 0.5 * scale; // make sure the scale is within the min/max bounds From 8a2c0c557b6a96f55be47fe3395ffe07e0030129 Mon Sep 17 00:00:00 2001 From: Alexander Wunschik Date: Mon, 26 Oct 2020 22:39:43 +0100 Subject: [PATCH 05/11] chore: only rerender on zoom if scale changes --- src/components/modebar/buttons.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/modebar/buttons.js b/src/components/modebar/buttons.js index 6d7930063cc..2bf8ad6b940 100644 --- a/src/components/modebar/buttons.js +++ b/src/components/modebar/buttons.js @@ -556,7 +556,9 @@ function handleGeo(gd, ev) { newScale = minscale; } - Registry.call('_guiRelayout', gd, id + '.projection.scale', newScale); + if(newScale !== scale) { + Registry.call('_guiRelayout', gd, id + '.projection.scale', newScale); + } } } From f882191bfcbdd15d91cac7206e146978fbff5d43 Mon Sep 17 00:00:00 2001 From: Alexander Wunschik Date: Mon, 26 Oct 2020 22:40:26 +0100 Subject: [PATCH 06/11] chore: fix typo in min/maxscale attributes --- src/plots/geo/layout_attributes.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plots/geo/layout_attributes.js b/src/plots/geo/layout_attributes.js index 69a49acaa44..aa9e6e59acc 100644 --- a/src/plots/geo/layout_attributes.js +++ b/src/plots/geo/layout_attributes.js @@ -183,7 +183,7 @@ var attrs = module.exports = overrideAll({ dflt: 0, description: [ 'Minimal zoom level of the map view.', - 'A minScale of *0.5* (50%) corresponds to a zoom level', + 'A minscale of *0.5* (50%) corresponds to a zoom level', 'where the map has half the size of base zoom level.' ].join(' ') }, @@ -193,7 +193,7 @@ var attrs = module.exports = overrideAll({ dflt: -1, description: [ 'Maximal zoom level of the map view.', - 'A maxScale of *2* (200%) corresponds to a zoom level', + 'A maxscale of *2* (200%) corresponds to a zoom level', 'where the map is twice as big as the base layer.' ].join(' ') }, From 8ed949fe4cf76028c12435f624e9947b040b12a2 Mon Sep 17 00:00:00 2001 From: Alexander Wunschik Date: Mon, 10 Jun 2024 23:52:30 +0200 Subject: [PATCH 07/11] test: adopt test/plot-schema.json to new plot-schema --- test/plot-schema.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/plot-schema.json b/test/plot-schema.json index 6aa77cf3338..3eca5b100d7 100644 --- a/test/plot-schema.json +++ b/test/plot-schema.json @@ -2373,6 +2373,20 @@ "valType": "number" }, "editType": "plot", + "maxscale": { + "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.", + "dflt": -1, + "editType": "plot", + "min": 0, + "valType": "number" + }, + "minscale": { + "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.", + "dflt": 0, + "editType": "plot", + "min": 0, + "valType": "number" + }, "parallels": { "description": "For conic projection types only. Sets the parallels (tangent, secant) where the cone intersects the sphere.", "editType": "plot", From 29b4316ed781bf93f17a9b34ff529e7acbfd2781 Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Tue, 18 Feb 2025 07:05:32 -0700 Subject: [PATCH 08/11] Trigger initial zoom event to set minscale --- src/plots/geo/geo.js | 21 +++++++++++++-------- src/plots/geo/zoom.js | 21 ++++++++++++++++----- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/plots/geo/geo.js b/src/plots/geo/geo.js index 1ad80e5e30f..1171ce5c722 100644 --- a/src/plots/geo/geo.js +++ b/src/plots/geo/geo.js @@ -484,7 +484,11 @@ proto.updateFx = function(fullLayout, geoLayout) { if(dragMode === 'pan') { bgRect.node().onmousedown = null; - bgRect.call(createGeoZoom(_this, geoLayout)); + const zoom = createGeoZoom(_this, geoLayout) + bgRect.call(zoom); + // TODO: Figure out how to restrict when this transition occurs. Or is it a no-op if nothing has changed? + // Trigger transition to handle if minscale attribute isn't 0 + zoom.event(bgRect.transition()) bgRect.on('dblclick.zoom', zoomReset); if(!gd._context._scrollZoom.geo) { bgRect.on('wheel.zoom', null); @@ -709,14 +713,15 @@ 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]; + // https://d3js.org/d3-zoom#zoom_scaleExtent + projection.scaleExtent = () => { + let { minscale, maxscale } = projLayout; + maxscale = maxscale === -1 ? Infinity : maxscale; + const max = Math.max(minscale, maxscale); + const min = Math.min(minscale, maxscale); + return [100 * min, 100 * max]; }; - + if(geoLayout._isSatellite) { projection.tilt(projLayout.tilt).distance(projLayout.distance); } diff --git a/src/plots/geo/zoom.js b/src/plots/geo/zoom.js index 824ba39a0ef..f5768063fc3 100644 --- a/src/plots/geo/zoom.js +++ b/src/plots/geo/zoom.js @@ -133,7 +133,10 @@ function zoomNonClipped(geo, projection) { function handleZoomstart() { d3.select(this).style(zoomstartStyle); - mouse0 = d3.mouse(this); + const { bottom, left, right, top } = this.getBoundingClientRect() + mouse0 = d3.event.sourceEvent + ? d3.mouse(this) + : [(left + right) / 2, (bottom + top) / 2]; rotate0 = projection.rotate(); translate0 = projection.translate(); lastRotate = rotate0; @@ -141,8 +144,10 @@ function zoomNonClipped(geo, projection) { } function handleZoom() { - mouse1 = d3.mouse(this); - + const { bottom, left, right, top } = this.getBoundingClientRect() + mouse1 = d3.event.sourceEvent + ? d3.mouse(this) + : [(left + right) / 2, (bottom + top) / 2]; if(outside(mouse0)) { zoom.scale(projection.scale()); zoom.translate(projection.translate()); @@ -211,7 +216,10 @@ function zoomClipped(geo, projection) { zoom.on('zoomstart', function() { d3.select(this).style(zoomstartStyle); - var mouse0 = d3.mouse(this); + const { bottom, left, right, top } = this.getBoundingClientRect() + let mouse0 = d3.event.sourceEvent + ? d3.mouse(this) + : [(left + right) / 2, (bottom + top) / 2]; var rotate0 = projection.rotate(); var lastRotate = rotate0; var translate0 = projection.translate(); @@ -220,7 +228,10 @@ function zoomClipped(geo, projection) { zoomPoint = position(projection, mouse0); zoomOn.call(zoom, 'zoom', function() { - var mouse1 = d3.mouse(this); + const { bottom, left, right, top } = this.getBoundingClientRect() + let mouse1 = d3.event.sourceEvent + ? d3.mouse(this) + : [(left + right) / 2, (bottom + top) / 2]; projection.scale(view.k = d3.event.scale); From 048f1786e5781208b4e118a27e8826482b3d71d3 Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Fri, 21 Feb 2025 06:52:51 -0700 Subject: [PATCH 09/11] Switch to ES5 syntax --- src/components/modebar/buttons.js | 16 ++++++++-------- src/plots/geo/geo.js | 10 +++++----- src/plots/geo/zoom.js | 20 ++++++++++---------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/components/modebar/buttons.js b/src/components/modebar/buttons.js index 2bf8ad6b940..8ebe360ebc0 100644 --- a/src/components/modebar/buttons.js +++ b/src/components/modebar/buttons.js @@ -544,19 +544,19 @@ function handleGeo(gd, ev) { if(attr === 'zoom') { var scale = geoLayout.projection.scale; var minscale = geoLayout.projection.minscale; - var maxscale = geoLayout.projection.maxscale; - - if(maxscale === -1) maxscale = Infinity; + var maxscale = geoLayout.projection.maxscale === -1 ? Infinity : geoLayout.projection.maxscale; + var max = Math.max(minscale, maxscale); + var min = Math.min(minscale, 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; + if (newScale > max) { + newScale = max; + } else if (newScale < min) { + newScale = min; } - if(newScale !== scale) { + if (newScale !== scale) { Registry.call('_guiRelayout', gd, id + '.projection.scale', newScale); } } diff --git a/src/plots/geo/geo.js b/src/plots/geo/geo.js index 1171ce5c722..555f031ca11 100644 --- a/src/plots/geo/geo.js +++ b/src/plots/geo/geo.js @@ -484,7 +484,7 @@ proto.updateFx = function(fullLayout, geoLayout) { if(dragMode === 'pan') { bgRect.node().onmousedown = null; - const zoom = createGeoZoom(_this, geoLayout) + var zoom = createGeoZoom(_this, geoLayout) bgRect.call(zoom); // TODO: Figure out how to restrict when this transition occurs. Or is it a no-op if nothing has changed? // Trigger transition to handle if minscale attribute isn't 0 @@ -715,10 +715,10 @@ function getProjection(geoLayout) { // https://d3js.org/d3-zoom#zoom_scaleExtent projection.scaleExtent = () => { - let { minscale, maxscale } = projLayout; - maxscale = maxscale === -1 ? Infinity : maxscale; - const max = Math.max(minscale, maxscale); - const min = Math.min(minscale, maxscale); + var minscale = projLayout.minscale; + var maxscale = projLayout.maxscale === -1 ? Infinity : projLayout.maxscale; + var max = Math.max(minscale, maxscale); + var min = Math.min(minscale, maxscale); return [100 * min, 100 * max]; }; diff --git a/src/plots/geo/zoom.js b/src/plots/geo/zoom.js index f5768063fc3..2013b6a7eae 100644 --- a/src/plots/geo/zoom.js +++ b/src/plots/geo/zoom.js @@ -133,10 +133,10 @@ function zoomNonClipped(geo, projection) { function handleZoomstart() { d3.select(this).style(zoomstartStyle); - const { bottom, left, right, top } = this.getBoundingClientRect() + var rect = this.getBoundingClientRect() mouse0 = d3.event.sourceEvent ? d3.mouse(this) - : [(left + right) / 2, (bottom + top) / 2]; + : [(rect.left + rect.right) / 2, (rect.bottom + rect.top) / 2]; rotate0 = projection.rotate(); translate0 = projection.translate(); lastRotate = rotate0; @@ -144,10 +144,10 @@ function zoomNonClipped(geo, projection) { } function handleZoom() { - const { bottom, left, right, top } = this.getBoundingClientRect() + var rect = this.getBoundingClientRect() mouse1 = d3.event.sourceEvent ? d3.mouse(this) - : [(left + right) / 2, (bottom + top) / 2]; + : [(rect.left + rect.right) / 2, (rect.bottom + rect.top) / 2]; if(outside(mouse0)) { zoom.scale(projection.scale()); zoom.translate(projection.translate()); @@ -216,10 +216,10 @@ function zoomClipped(geo, projection) { zoom.on('zoomstart', function() { d3.select(this).style(zoomstartStyle); - const { bottom, left, right, top } = this.getBoundingClientRect() - let mouse0 = d3.event.sourceEvent + var rect = this.getBoundingClientRect() + var mouse0 = d3.event.sourceEvent ? d3.mouse(this) - : [(left + right) / 2, (bottom + top) / 2]; + : [(rect.left + rect.right) / 2, (rect.bottom + rect.top) / 2]; var rotate0 = projection.rotate(); var lastRotate = rotate0; var translate0 = projection.translate(); @@ -228,10 +228,10 @@ function zoomClipped(geo, projection) { zoomPoint = position(projection, mouse0); zoomOn.call(zoom, 'zoom', function() { - const { bottom, left, right, top } = this.getBoundingClientRect() - let mouse1 = d3.event.sourceEvent + var rect = this.getBoundingClientRect() + var mouse1 = d3.event.sourceEvent ? d3.mouse(this) - : [(left + right) / 2, (bottom + top) / 2]; + : [(rect.left + rect.right) / 2, (rect.bottom + rect.top) / 2]; projection.scale(view.k = d3.event.scale); From 84cd037acf7138f9a6fa684626dc2acf6c57ec9c Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Sat, 22 Feb 2025 10:30:52 -0700 Subject: [PATCH 10/11] Switch to getBBox and fix zoom.event call --- src/plots/geo/geo.js | 2 +- src/plots/geo/zoom.js | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/plots/geo/geo.js b/src/plots/geo/geo.js index 555f031ca11..d3b7ee4ec13 100644 --- a/src/plots/geo/geo.js +++ b/src/plots/geo/geo.js @@ -488,7 +488,7 @@ proto.updateFx = function(fullLayout, geoLayout) { bgRect.call(zoom); // TODO: Figure out how to restrict when this transition occurs. Or is it a no-op if nothing has changed? // Trigger transition to handle if minscale attribute isn't 0 - zoom.event(bgRect.transition()) + zoom.event(bgRect) bgRect.on('dblclick.zoom', zoomReset); if(!gd._context._scrollZoom.geo) { bgRect.on('wheel.zoom', null); diff --git a/src/plots/geo/zoom.js b/src/plots/geo/zoom.js index 2013b6a7eae..6cfe1e8f0df 100644 --- a/src/plots/geo/zoom.js +++ b/src/plots/geo/zoom.js @@ -133,10 +133,10 @@ function zoomNonClipped(geo, projection) { function handleZoomstart() { d3.select(this).style(zoomstartStyle); - var rect = this.getBoundingClientRect() + var rect = this.getBBox() mouse0 = d3.event.sourceEvent ? d3.mouse(this) - : [(rect.left + rect.right) / 2, (rect.bottom + rect.top) / 2]; + : [rect.x + rect.width / 2, rect.y + rect.height / 2]; rotate0 = projection.rotate(); translate0 = projection.translate(); lastRotate = rotate0; @@ -144,10 +144,10 @@ function zoomNonClipped(geo, projection) { } function handleZoom() { - var rect = this.getBoundingClientRect() + var rect = this.getBBox() mouse1 = d3.event.sourceEvent ? d3.mouse(this) - : [(rect.left + rect.right) / 2, (rect.bottom + rect.top) / 2]; + : [rect.x + rect.width / 2, rect.y + rect.height / 2]; if(outside(mouse0)) { zoom.scale(projection.scale()); zoom.translate(projection.translate()); @@ -216,10 +216,10 @@ function zoomClipped(geo, projection) { zoom.on('zoomstart', function() { d3.select(this).style(zoomstartStyle); - var rect = this.getBoundingClientRect() + var rect = this.getBBox() var mouse0 = d3.event.sourceEvent ? d3.mouse(this) - : [(rect.left + rect.right) / 2, (rect.bottom + rect.top) / 2]; + : [rect.x + rect.width / 2, rect.y + rect.height / 2]; var rotate0 = projection.rotate(); var lastRotate = rotate0; var translate0 = projection.translate(); @@ -228,10 +228,10 @@ function zoomClipped(geo, projection) { zoomPoint = position(projection, mouse0); zoomOn.call(zoom, 'zoom', function() { - var rect = this.getBoundingClientRect() + var rect = this.getBBox() var mouse1 = d3.event.sourceEvent ? d3.mouse(this) - : [(rect.left + rect.right) / 2, (rect.bottom + rect.top) / 2]; + : [rect.x + rect.width / 2, rect.y + rect.height / 2]; projection.scale(view.k = d3.event.scale); From d9fca8b2cd1117d78b13248a1cb477e2c3a89766 Mon Sep 17 00:00:00 2001 From: Cameron DeCoster Date: Sat, 22 Feb 2025 11:33:18 -0700 Subject: [PATCH 11/11] Add draft log --- draftlogs/7371_add.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 draftlogs/7371_add.md diff --git a/draftlogs/7371_add.md b/draftlogs/7371_add.md new file mode 100644 index 00000000000..f134f571ff9 --- /dev/null +++ b/draftlogs/7371_add.md @@ -0,0 +1 @@ + - Add `minscale`, `maxscale` geo plot attributes [[#7371](https://github.com/plotly/plotly.js/pull/7371)]