posit-dev / py-shinywidgets

Render ipywidgets inside a PyShiny app
MIT License
41 stars 2 forks source link

iPyleaflet Layer callbacks fail to work #137

Open arky opened 4 months ago

arky commented 4 months ago

When using ipyleaflet, certain features such as geojson's on_hover fail to work.

Description

ipyleaflet WigetControl, HTML calls fail to work.

What I Did

Python Shiny Testcase

python 

import json
import os

import random
import requests

from ipyleaflet import Map, GeoJSON, WidgetControl, Popup
from ipywidgets import Text, HTML

from shiny import reactive
from shiny.express import ui, render, input
from shinywidgets import render_widget  

ui.panel_title("ipyleaflet WidgetControl Testcase")

if not os.path.exists('europe_110.geo.json'):
    url = 'https://github.com/jupyter-widgets/ipyleaflet/raw/master/examples/europe_110.geo.json'
    r = requests.get(url)
    with open('europe_110.geo.json', 'w') as f:
        f.write(r.content.decode("utf-8"))

with open('europe_110.geo.json', 'r') as f:
    data = json.load(f)

def random_color(feature):
    return {
        'color': 'black',
        'fillColor': random.choice(['red', 'yellow', 'green', 'orange']),
    }

def update_html(feature, **kwargs):
    html.value = """
        <h3><b>{}</b></h3>
    """.format(feature["properties"]["name"])

ui.page_opts(fillable=True)    

@render_widget  
def map():
    map = Map(center=(50.6252978589571, 0.34580993652344), zoom=3)

    geo_json = GeoJSON(
        data=data,
        style={
            'opacity': 1, 'dashArray': '9', 'fillOpacity': 0.1, 'weight': 1
     },
     hover_style={
            'color': 'white', 'dashArray': '0', 'fillOpacity': 0.5
        },
        style_callback=random_color
    )
    map.add(geo_json)

    html = HTML("""Hover over a state""")
    html.layout.margin = "0px 20px 20px 20px"
    control = WidgetControl(widget=html, position="topright")
    map.add(control)

    geo_json.on_hover(update_html)
    #geo_json.popup = HTML("hello, world")

    return map

Jupyter Testcase: The on_hover works as expected.

# %%

import json
import os

import random
import requests

from ipyleaflet import Map, GeoJSON, WidgetControl, Popup
from ipywidgets import Text, HTML

# %%
if not os.path.exists('europe_110.geo.json'):
    url = 'https://github.com/jupyter-widgets/ipyleaflet/raw/master/examples/europe_110.geo.json'
    r = requests.get(url)
    with open('europe_110.geo.json', 'w') as f:
        f.write(r.content.decode("utf-8"))

with open('europe_110.geo.json', 'r') as f:
    data = json.load(f)

# %%

map = Map(center=(50.6252978589571, 0.34580993652344), zoom=3)

geo_json = GeoJSON(
    data=data,
    style={
        'opacity': 1, 'dashArray': '9', 'fillOpacity': 0.1, 'weight': 1
 },
 hover_style={
        'color': 'white', 'dashArray': '0', 'fillOpacity': 0.5
    },
    style_callback=random_color
)
map.add(geo_json)

html = HTML("""Hover over a state""")
html.layout.margin = "0px 20px 20px 20px"
control = WidgetControl(widget=html, position="topright")
map.add(control)
geo_json.on_hover(update_html)
#geo_json.popup = HTML("hello, world")

map

# %%

def random_color(feature):
    return {
        'color': 'black',
        'fillColor': random.choice(['red', 'yellow', 'green', 'orange']),
    }

def update_html(feature, **kwargs):
    html.value = """
        <h3><b>{}</b></h3>
    """.format(feature["properties"]["name"])
arky commented 4 months ago

@cpsievert Could you please provide some suggestions on how to debug py-shinywidgets. There seems little information about how to go about figuring out the issues with ipyleaflet callbacks.