I have to generate static html webpages with ipyleaflet, and I would like to add a custom legend. It's basicaly a WidgetControl containing a Ipywidget Accordion. It's displaying well in my Jupyter notebook, but when I am embeding it into an html webpage the WidgetControl doesn't show up.
I am using the embed_data function as described in this page : https://ipywidgets.readthedocs.io/en/7.6.5/embedding.html Here is the code :
import json
from ipywidgets import Accordion, HTML
from ipywidgets.embed import embed_data
mapnik = basemap_to_tiles(basemaps.OpenStreetMap.Mapnik)
mapnik.base = True
m = L.Map(layers=[mapnik], center=default_center, zoom=5.5, zoom_snap=0.25, scroll_wheel_zoom=True, zoom_control=False,
layout=Layout(width='800px', height='500px'))
html_legende = 'Legend text'
html_widget_legend= HTML(value='<div style="line-height: normal;">' + html_legende + '</div>',
placeholder='Some HTML',
description='Some HTML')
accordion = Accordion()
accordion.children = [html_widget_legend]
accordion.layout ={'width': '250px', 'max_height': '450px'}
accordion.set_title(0, 'Legend title')
accordion.selected_index = None
widget_control1 = WidgetControl(widget=accordion, position='topleft')
m.add_control(widget_control1)
data = embed_data(views=[s1])
html_template = """
<html>
<head>
<title>Widget export</title>
<!-- Load RequireJS, used by the IPywidgets for dependency management -->
<script
src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"
integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA="
crossorigin="anonymous">
</script>
<!-- Load IPywidgets bundle for embedding. -->
<script
data-jupyter-widgets-cdn="https://cdn.jsdelivr.net/npm/"
src="https://unpkg.com/@jupyter-widgets/html-manager@*/dist/embed-amd.js"
crossorigin="anonymous">
</script>
<!-- The state of all the widget models on the page -->
<script type="application/vnd.jupyter.widget-state+json">
{manager_state}
</script>
</head>
<body>
<h1>Widget export</h1>
<div id="map-widget">
<!-- This script tag will be replaced by the view's DOM tree -->
<script type="application/vnd.jupyter.widget-view+json">
{widget_views[0]}
</script>
</div>
</body>
</html>
"""
manager_state = json.dumps(data['manager_state'])
widget_views = [json.dumps(view) for view in data['view_specs']]
rendered_template = html_template.format(manager_state=manager_state, widget_views=widget_views)
with open('export.html', 'w') as fp:
fp.write(rendered_template)
When I open the html file with Firefox and Chrome's inspectors I get two js errors, with different explanations :
Firefox :
TypeError: e is undefined
F/o/o.paths[e]< embed-amd.js:26
o embed-amd.js:26
F embed-amd.js:26
promise callback*F embed-amd.js:26
loadClass embed-amd.js:16
loadClass embed-amd.js:16
loadViewClass embed-amd.js:16
state_change embed-amd.js:16
promise callback*create_view embed-amd.js:16
create_child_view embed-amd.js:2
add_control_model Map.js:194
update embed-amd.js:2
render_leaflet Map.js:233
promise callback*render_leaflet Map.js:231
promise callback*render Map.js:227
state_change embed-amd.js:16
create_view embed-amd.js:16
I embed-amd.js:26
I embed-amd.js:26
I embed-amd.js:26
I embed-amd.js:26
I embed-amd.js:26
promise callback*I embed-amd.js:26
<anonymous> embed-amd.js:29
execCb require.min.js:1
check require.min.js:1
enable require.min.js:1
init require.min.js:1
o require.min.js:1
setTimeout handler*req.nextTick< require.min.js:1
o require.min.js:1
requirejs require.min.js:1
<anonymous> embed-amd.js:29
<anonymous> embed-amd.js:29
embed-amd.js:16:585209
loadViewClass embed-amd.js:16
state_change embed-amd.js:16
(Asynchrone : promise callback)
create_view embed-amd.js:16
create_child_view embed-amd.js:2
add_control_model Map.js:194
update embed-amd.js:2
render_leaflet Map.js:233
(Asynchrone : promise callback)
render_leaflet Map.js:231
render Map.js:227
state_change embed-amd.js:16
create_view embed-amd.js:16
I embed-amd.js:26
I embed-amd.js:26
I embed-amd.js:26
I embed-amd.js:26
I embed-amd.js:26
(Asynchrone : promise callback)
I embed-amd.js:26
<anonyme> embed-amd.js:29
execCb require.min.js:1
check require.min.js:1
enable require.min.js:1
init require.min.js:1
o require.min.js:1
(Asynchrone : setTimeout handler)
nextTick require.min.js:1
o require.min.js:1
requirejs require.min.js:1
<anonyme> embed-amd.js:29
<anonyme> embed-amd.js:29
Uncaught (in promise) TypeError: t is undefined
addControl leaflet-src.js:4824
add_control_model Map.js:197
promise callback*add_control_model Map.js:196
update embed-amd.js:2
render_leaflet Map.js:233
promise callback*render_leaflet Map.js:231
promise callback*render Map.js:227
state_change embed-amd.js:16
create_view embed-amd.js:16
I embed-amd.js:26
I embed-amd.js:26
I embed-amd.js:26
I embed-amd.js:26
I embed-amd.js:26
promise callback*I embed-amd.js:26
<anonymous> embed-amd.js:29
execCb require.min.js:1
check require.min.js:1
enable require.min.js:1
init require.min.js:1
o require.min.js:1
setTimeout handler*req.nextTick< require.min.js:1
o require.min.js:1
requirejs require.min.js:1
<anonymous> embed-amd.js:29
<anonymous> embed-amd.js:29
leaflet-src.js:4824:4
Chrome :
embed-amd.js:16 TypeError: Cannot read property 'indexOf' of undefined
at embed-amd.js:26
at o (embed-amd.js:26)
at embed-amd.js:26
at async xc.loadViewClass (embed-amd.js:16)
at async https:/unpkg.com/@jupyter-widgets/html-manager@*/dist/embed-amd.js:16
at async Promise.all (index 1)
loadViewClass @ embed-amd.js:16
leaflet-src.js:4824 Uncaught (in promise) TypeError: Cannot read property 'addTo' of undefined
at n.addControl (leaflet-src.js:4824)
at Map.js:197
at async Promise.all (index 1)
Has anyone got these kind of problem ?