Skip to content

Commit db50907

Browse files
author
Martin Journois
committed
Popup update ; with examples
1 parent a3d373c commit db50907

6 files changed

Lines changed: 429 additions & 27 deletions

File tree

examples/Popups.ipynb

Lines changed: 331 additions & 0 deletions
Large diffs are not rendered by default.

folium/element.py

Lines changed: 80 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -210,20 +210,20 @@ def __init__(self, width="100%", height=None, ratio="60%", figsize=None):
210210
211211
Parameters
212212
----------
213-
width : str, default "100%"
214-
The width of the Figure.
215-
It may be a percentage or pixel value (like "300px").
216-
height : str, default None
217-
The height of the Figure.
218-
It may be a percentage or a pixel value (like "300px").
219-
ratio : str, default "60%"
220-
A percentage defining the aspect ratio of the Figure.
221-
It will be ignored if height is not None.
222-
figsize : tuple of two int, default None
223-
If you're a matplotlib addict, you can overwrite width and
224-
height. Values will be converted into pixels in using 60 dpi.
225-
For example figsize=(10, 5) will result in
226-
width="600px", height="300px".
213+
width : str, default "100%"
214+
The width of the Figure.
215+
It may be a percentage or pixel value (like "300px").
216+
height : str, default None
217+
The height of the Figure.
218+
It may be a percentage or a pixel value (like "300px").
219+
ratio : str, default "60%"
220+
A percentage defining the aspect ratio of the Figure.
221+
It will be ignored if height is not None.
222+
figsize : tuple of two int, default None
223+
If you're a matplotlib addict, you can overwrite width and
224+
height. Values will be converted into pixels in using 60 dpi.
225+
For example figsize=(10, 5) will result in
226+
width="600px", height="300px".
227227
"""
228228
super(Figure, self).__init__()
229229
self._name = 'Figure'
@@ -295,6 +295,9 @@ def to_dict(self, depth=-1, **kwargs):
295295
out['script'] = self.script.to_dict(depth=depth-1, **kwargs)
296296
return out
297297

298+
def get_root(self):
299+
return self
300+
298301
def render(self, **kwargs):
299302
"""TODO : docstring here."""
300303
for name, child in self._children.items():
@@ -451,6 +454,69 @@ def _repr_html_(self, **kwargs):
451454
out = self._parent._repr_html_(**kwargs)
452455
return out
453456

457+
class IFrame(Element):
458+
def __init__(self, html=None, width="100%", height=None, ratio="60%", figsize=None):
459+
"""Create a Figure object, to plot things into it.
460+
461+
Parameters
462+
----------
463+
html : str, default None
464+
Eventual HTML code that you want to put in the frame.
465+
width : str, default "100%"
466+
The width of the Figure.
467+
It may be a percentage or pixel value (like "300px").
468+
height : str, default None
469+
The height of the Figure.
470+
It may be a percentage or a pixel value (like "300px").
471+
ratio : str, default "60%"
472+
A percentage defining the aspect ratio of the Figure.
473+
It will be ignored if height is not None.
474+
figsize : tuple of two int, default None
475+
If you're a matplotlib addict, you can overwrite width and
476+
height. Values will be converted into pixels in using 60 dpi.
477+
For example figsize=(10, 5) will result in
478+
width="600px", height="300px".
479+
"""
480+
super(IFrame, self).__init__()
481+
self._name = 'IFrame'
482+
483+
self.width = width
484+
self.height = height
485+
self.ratio = ratio
486+
if figsize is not None:
487+
self.width = str(60*figsize[0])+'px'
488+
self.height = str(60*figsize[1])+'px'
489+
490+
if isinstance(html, text_type) or isinstance(html, binary_type):
491+
self.add_children(Element(html))
492+
elif html is not None:
493+
self.add_children(html)
494+
495+
def render(self, **kwargs):
496+
"""Displays the Figure in a Jupyter notebook.
497+
498+
Parameters
499+
----------
500+
501+
"""
502+
html = super(IFrame,self).render(**kwargs)
503+
html = "data:text/html;base64," + base64.b64encode(html.encode('utf8')).decode('utf8') # noqa
504+
505+
if self.height is None:
506+
iframe = (
507+
'<div style="width:{width};">'
508+
'<div style="position:relative;width:100%;height:0;padding-bottom:{ratio};">'
509+
'<iframe src="{html}" style="position:absolute;width:100%;height:100%;left:0;top:0;">'
510+
'</iframe>'
511+
'</div></div>').format # noqa
512+
iframe = iframe(html=html,
513+
width=self.width,
514+
ratio=self.ratio)
515+
else:
516+
iframe = ('<iframe src="{html}" width="{width}" '
517+
'height="{height}"></iframe>').format
518+
iframe = iframe(html=html, width=self.width, height=self.height)
519+
return iframe
454520

455521
class MacroElement(Element):
456522
"""This is a parent class for Elements defined by a macro template.

folium/features.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,19 +131,21 @@ def render(self, **kwargs):
131131

132132

133133
class Vega(Element):
134-
def __init__(self, data, width='100%', height='100%',
134+
def __init__(self, data, width=None, height=None,
135135
left="0%", top="0%", position='relative'):
136136
"""
137137
TODO docstring here
138138
139139
"""
140140
super(Vega, self).__init__()
141141
self._name = 'Vega'
142-
self.data = data
142+
self.data = data.to_json() if hasattr(data,'to_json') else data
143+
if isinstance(self.data,text_type) or isinstance(data,binary_type):
144+
self.data = json.loads(self.data)
143145

144146
# Size Parameters.
145-
self.width = _parse_size(width)
146-
self.height = _parse_size(height)
147+
self.width = _parse_size(self.data.get('width','100%') if width is None else width)
148+
self.height = _parse_size(self.data.get('height','100%') if height is None else height)
147149
self.left = _parse_size(left)
148150
self.top = _parse_size(top)
149151
self.position = position
@@ -250,8 +252,8 @@ def __init__(self, data, style_function=None):
250252
{% macro script(this, kwargs) %}
251253
var {{this.get_name()}} = L.geoJson(
252254
{% if this.embed %}{{this.style_data()}}{% else %}"{{this.data}}"{% endif %})
253-
.addTo({{this._parent.get_name()}})
254-
.setStyle(function(feature) {return feature.properties.style;});
255+
.addTo({{this._parent.get_name()}});
256+
{{this.get_name()}}.setStyle(function(feature) {return feature.properties.style;});
255257
{% endmacro %}
256258
""") # noqa
257259

folium/folium.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,12 @@ def simple_marker(self, location=None, popup=None,
114114
if isinstance(popup, text_type) or isinstance(popup, binary_type):
115115
popup_ = Popup(popup, max_width=popup_width)
116116
elif isinstance(popup, tuple):
117-
popup_ = Popup(Vega(json.loads(popup[0].to_json()),
118-
width="100%", height="100%"),
119-
max_width=popup_width)
117+
popup_ = Popup(max_width=popup_width)
118+
Vega(
119+
json.loads(popup[0].to_json()),
120+
width="100%",
121+
height="100%",
122+
).add_to(popup_)
120123
else:
121124
popup_ = None
122125
marker = Marker(location,

folium/map.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ def __init__(self, location, popup=None, icon=None):
402402

403403

404404
class Popup(Element):
405-
def __init__(self, html, max_width=300):
405+
def __init__(self, html=None, max_width=300):
406406
super(Popup, self).__init__()
407407
self._name = 'Popup'
408408
self.header = Element()
@@ -414,7 +414,7 @@ def __init__(self, html, max_width=300):
414414
self.script._parent = self
415415

416416
if isinstance(html, Element):
417-
self.add_children(html)
417+
self.html.add_children(html)
418418
elif isinstance(html, text_type) or isinstance(html, binary_type):
419419
self.html.add_children(Html(text_type(html)))
420420

tests/test_folium.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,8 @@ def test_geo_json_str(self):
358358
# Verify the geo_json object
359359
obj_temp = jinja2.Template("""
360360
var {{ this.get_name() }} = L.geoJson({{ json.dumps(this.data) }})
361-
.addTo({{ this._parent.get_name() }})
362-
.setStyle(function(feature) {return feature.properties.style;});
361+
.addTo({{ this._parent.get_name() }});
362+
{{ this.get_name() }}.setStyle(function(feature) {return feature.properties.style;});
363363
""")
364364
obj = obj_temp.render(this=geo_json, json=json)
365365
assert ''.join(obj.split())[:-1] in out

0 commit comments

Comments
 (0)