Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Select widget is not being displayed in a full screen ipyleaflet map #141

Open
dfguerrerom opened this issue Apr 22, 2021 · 4 comments
Open

Comments

@dfguerrerom
Copy link

I'm trying to include some ipyvuetify widgets inside an ipyleaflet map, however, when I try to open the items in the Full-screen mode, they are not displayed.

from ipyleaflet import Map, WidgetControl, FullScreenControl
import ipyvuetify as v

map_=Map(center=[4,-74], zoom=5)
map_.add_control(FullScreenControl())

dropdown = v.Select(items=[1,2,3,4,5,])
widget_control = WidgetControl(widget=dropdown)
map_.add_control(widget_control)

map_

This is without full-screen mode
image

And this is how is displayed in the full-screen map
image

@mariobuikhuizen
Copy link
Collaborator

ipyvuetify injects a special element in the notebook to be able to display overlays (like the item list of a select). This element is probably not part of the DOM that is used in full-screen.
Screenshot 2021-08-31 at 12 37 34

@12rambau
Copy link
Contributor

I know that's an old one but I have news on this issue:

So when you use the fullscreen option of the map the div that contains the map get the maximum z-index via the user agent (https://stackoverflow.com/questions/18578244/displaying-elements-other-than-fullscreen-element-html5-fullscreen-api).

the rest of the component are shown without problem because they have the following structure:

<div class="leaflet-container ...">  <!-- that's the full screen element --> 
    <div class="leaflet-pane leaflet-map-pane"> <!-- that's the map -->
    <div class="leaflet-control-container>
        <div class="leaflet-top leaflet-left">...</div> <!-- that's where the components live -->
    </div>
</div>

According to what I've understand everything that live outside of the "fullscrened" component (in this case the "leaflet-container") will be hidden.
That's the case of the menus as they are living in the "overlay" component.

<div vuetify-overlay="true class="v-application ...">
    <div class="v-menu_content">...</div> <!-- this is where the menus are living they are just display or hidden depending on menu click with the "display" style -->
</div>

So @mariobuikhuizen the element is still part of the DOM the only issue is that it's outside of the computed "rendered_cell" <div> tag

That being said i don't have any solution or css trick to avoid this situation

@12rambau
Copy link
Contributor

Here is the start of a solution. I created a custom fullsreenControl that fake the fullscreen behaviour by manually setting the dimensions of the map. as I keep control over the z-index, I can set it under the one of the "overlay" component (802).

from ipywidgets import Button, Layout
from ipyleaflet import WidgetControl
from IPython.display import Javascript, display
import ipyvuetify as v

class FullScreenControl(WidgetControl):
    
    ICONS = ["expand", "compress"]
    METHODS = ["embed","fullscreen"]
    
    def __init__(self, **kwargs):
        
        self.zoomed = False
        
        # create a btn
        self.w_btn = Button( 
            tooltip="set fullscreen",
            icon=self.ICONS[self.zoomed],
            layout=Layout(width="30px", height="30px", line_height="30px", padding="0px"),
        )
        
        # overwrite the widget set in the kwargs (if any)
        kwargs["widget"] = self.w_btn
        kwargs["position"] = kwargs.pop("position", "topleft")
        kwargs["transparent_bg"] = True
        
        # create the widget
        super().__init__(**kwargs)
        
        # add javascrip behaviour
        self.w_btn.on_click(self._on_click)
        
        # template with js behaviour
        self.template = v.VuetifyTemplate(template="""
        <script>
            {methods: {
                jupyter_fullscreen() {
                    var element = document.getElementsByClassName("leaflet-container")[0];
                    element.style["position"] = "fixed";
                    element.style["width"] = "100vw";
                    element.style["height"] = "100vh";
                    element.style["z-index"] = 800;
                    element.style["top"] = 0;
                    element.style["left"] = 0;
                    window.dispatchEvent(new Event('resize'));
                },
                jupyter_embed() {
                    var element = document.getElementsByClassName("leaflet-container")[0];
                    element.style["position"] = "relative";
                    element.style["width"] = "";
                    element.style["height"] = "";
                    element.style["z-index"] = 400;
                    element.style["top"] = "";
                    element.style["left"] = "";
                    window.dispatchEvent(new Event('resize'));
                }
            }}
        </script>
        """)
        display(self.template)
        
        
    def _on_click(self, widget):
        
        # change the zoom state 
        self.zoomed = not self.zoomed
        
        # change icon
        self.w_btn.icon = self.ICONS[self.zoomed]
        
        # zoom 
        self.template.send({"method": self.METHODS[self.zoomed], "args": []})
        
        return
   
from ipyleaflet import Map, WidgetControl
import ipyvuetify as v

map_=Map(center=[4,-74], zoom=5)
map_.add_control(FullScreenControl(position="topleft"))

dropdown = v.Select(label="titi", items=["toto",2,3,4,5,], v_model=None)
widget_control = WidgetControl(widget=dropdown)
map_.add_control(widget_control)

map_

it works well in voila dashboard but lead to funny results in JupyterNotebook windows. @dfguerrerom I think I will include this component and refine it in sepal-ui directly

@12rambau
Copy link
Contributor

12rambau commented Feb 2, 2023

I think this is now solved. The solution is complex and involved CSS and JS tricks. I would suggest anyone coming here to use sepal-ui to use ipyvuetify on maps, we already took care of most of the issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants