Hi,
I’m trying to create a ReactiveHTML component that uses MapLibre.
I cannot get to work at all using the latest version of Panel.
Here is a simple code to reproduce the issue:
from panel.reactive import ReactiveHTML
class MapLibre(ReactiveHTML):
_template = """
<div id="map-container" style="width: 100%; height: 100%;"></div>
"""
_scripts = {
"init": """
var map = new maplibregl.Map({
container: "map-container" ,
style: 'https://demotiles.maplibre.org/style.json', // stylesheet location
center: [-74.5, 40], // starting position [lng, lat]
zoom: 9 // starting zoom
});
""",
"render": """
self.init()
""",
}
_extension_name = "maplibre"
__javascript__ = ["https://unpkg.com/maplibre-gl@3.1.0/dist/maplibre-gl.js"]
__css__ = ["https://unpkg.com/maplibre-gl@3.1.0/dist/maplibre-gl.css"]
if __name__.startswith("bokeh"):
import panel as pn
pn.extension("maplibre")
map = MapLibre(sizing_mode="stretch_both")
app = pn.Column(map, sizing_mode="stretch_both")
app.servable()
when running the file via panel serve
, I’m getting the following error:
Error rendering Bokeh items: Error: Container 'map-container' not found.
If I try with Panel 0.14, I get the same error by default, but I can get it to work by getting the element manually onto which to attach the MapLibre instance:
from panel.reactive import ReactiveHTML
class MapLibre(ReactiveHTML):
_template = """
<div id="map-container" style="width: 100%; height: 100%;"></div>
"""
_scripts = {
"init": """
var e = Array.from(document.querySelectorAll("div")).filter(x=> x.id.includes("map"))[0]
var map = new maplibregl.Map({
container: e,
style: 'https://demotiles.maplibre.org/style.json', // stylesheet location
center: [-74.5, 40], // starting position [lng, lat]
zoom: 9 // starting zoom
});
""",
"render": """
self.init()
""",
}
_extension_name = "maplibre"
__javascript__ = ["https://unpkg.com/maplibre-gl@3.1.0/dist/maplibre-gl.js"]
__css__ = ["https://unpkg.com/maplibre-gl@3.1.0/dist/maplibre-gl.css"]
if __name__.startswith("bokeh"):
import panel as pn
pn.extension("maplibre")
map = MapLibre(sizing_mode="stretch_both")
app = pn.Column(map, sizing_mode="stretch_both")
app.servable()
But this hack does not work with Panel 1.x as the elements are in a shadow dom that I can’t access.
Any idea on how to make it work?