Skip to content

Commit 97d89a8

Browse files
committed
more intelligent maxZoom behavior
1 parent d28506f commit 97d89a8

File tree

1 file changed

+57
-3
lines changed

1 file changed

+57
-3
lines changed

dash_cytoscape/CyLeaflet.py

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,21 @@
1616
except ImportError:
1717
dl = None
1818

19+
# Max zoom of default Leaflet tile layer
20+
LEAFLET_DEFAULT_MAX_ZOOM = 18
21+
22+
# Empirically-determined max zoom values for Cytoscape
23+
# which correspond to max zoom values of Leaflet
24+
LEAF_TO_CYTO_MAX_ZOOM_MAPPING = {
25+
16: 0.418,
26+
17: 0.837,
27+
18: 1.674,
28+
19: 3.349,
29+
20: 6.698,
30+
21: 13.396,
31+
22: 26.793,
32+
}
33+
1934

2035
class CyLeaflet(html.Div):
2136
def __init__(
@@ -25,6 +40,7 @@ def __init__(
2540
leaflet_props=None,
2641
width="600px",
2742
height="480px",
43+
max_zoom=None,
2844
):
2945
# Throw error if `dash_leaflet` package is not installed
3046
if dl is None:
@@ -42,7 +58,7 @@ def __init__(
4258
leaflet_props = leaflet_props or {}
4359
elements = cytoscape_props.get("elements", [])
4460
cytoscape_props, leaflet_props = self.set_default_props_and_overrides(
45-
cytoscape_props, leaflet_props
61+
cytoscape_props, leaflet_props, max_zoom
4662
)
4763

4864
super().__init__(
@@ -84,7 +100,14 @@ def __init__(
84100
},
85101
)
86102

87-
def set_default_props_and_overrides(self, user_cytoscape_props, user_leaflet_props):
103+
def set_default_props_and_overrides(
104+
self, user_cytoscape_props, user_leaflet_props, max_zoom
105+
):
106+
# Try to figure out Leaflet maxZoom from Leaflet children,
107+
# then convert to Cytoscape max zoom
108+
leaflet_max_zoom = max_zoom or self.get_leaflet_max_zoom(user_leaflet_props)
109+
cytoscape_max_zoom = self.get_cytoscape_max_zoom(leaflet_max_zoom)
110+
88111
# Props where we want to override values supplied by the user
89112
# These are props which are required for CyLeaflet to work properly
90113
cytoscape_overrides = {
@@ -113,7 +136,7 @@ def set_default_props_and_overrides(self, user_cytoscape_props, user_leaflet_pro
113136
# if a value is not supplied by the user
114137
cytoscape_defaults = {
115138
"boxSelectionEnabled": True,
116-
"maxZoom": 1.67,
139+
"maxZoom": cytoscape_max_zoom,
117140
}
118141
leaflet_defaults = {
119142
"children": dl.TileLayer(),
@@ -133,6 +156,37 @@ def set_default_props_and_overrides(self, user_cytoscape_props, user_leaflet_pro
133156

134157
return cytoscape_props, leaflet_props
135158

159+
# Try to figure out Leaflet maxZoom from Leaflet children
160+
# If not possible, return the maxZoom of the default Leaflet tile layer
161+
def get_leaflet_max_zoom(self, user_leaflet_props):
162+
if "children" not in user_leaflet_props or user_leaflet_props["children"] == []:
163+
return LEAFLET_DEFAULT_MAX_ZOOM
164+
165+
if isinstance(user_leaflet_props["children"], list):
166+
leaflet_children = user_leaflet_props["children"]
167+
else:
168+
leaflet_children = [user_leaflet_props["children"]]
169+
170+
max_zooms = [
171+
c.maxZoom
172+
for c in leaflet_children
173+
if isinstance(c, dl.TileLayer) and hasattr(c, "maxZoom")
174+
]
175+
176+
return max_zooms[0] if max_zooms else LEAFLET_DEFAULT_MAX_ZOOM
177+
178+
# Given a maxZoom value for Leaflet, map it to the corresponding maxZoom value for Cytoscape
179+
# If the value is out of range, return the closest value
180+
def get_cytoscape_max_zoom(self, leaflet_max_zoom):
181+
leaflet_max_zoom = leaflet_max_zoom or 0
182+
leaflet_max_zoom = min(
183+
leaflet_max_zoom, max(LEAF_TO_CYTO_MAX_ZOOM_MAPPING.keys())
184+
)
185+
leaflet_max_zoom = max(
186+
leaflet_max_zoom, min(LEAF_TO_CYTO_MAX_ZOOM_MAPPING.keys())
187+
)
188+
return LEAF_TO_CYTO_MAX_ZOOM_MAPPING[leaflet_max_zoom]
189+
136190

137191
if dl is not None:
138192
clientside_callback(

0 commit comments

Comments
 (0)