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

Cannot dynamically add and remove panes #838

Open
MarcSkovMadsen opened this issue Dec 3, 2019 · 7 comments
Labels

Comments

@MarcSkovMadsen
Copy link

@MarcSkovMadsen MarcSkovMadsen commented Dec 3, 2019

System Info

  • Panel: 0.7.0
  • Bokeh: 1.4.0
  • Python: 3.7.4
  • OS: Windows 8.1
  • Browser: Chrome

Issue

I'm trying to create a multipage app that dynamically adds and removes a "page" pane depending on the user navigating to a specific pane.

Stack Trace

2019-12-03 09:52:31,097 Cannot apply patch to 1046 which is not in the document anymore
2019-12-03 09:52:31,105 Cannot apply patch to 1046 which is not in the document anymore
2019-12-03 09:52:31,109 Cannot apply patch to 1046 which is not in the document anymore
2019-12-03 09:52:31,113 Cannot apply patch to 1046 which is not in the document anymore
2019-12-03 09:52:32,032 Cannot apply patch to 1046 which is not in the document anymore

Minimal Reproducing Example

None yet. I plan to add one later.

Screenshots or screencasts of the bug in action

multi_page_app problems

Discussion

I can see from bokeh/bokeh#7738 that I am pushing the limits of Bokeh. But I think a multipage app is a reasonable requirement for a modern analytics apps.

At least the ones I build often have a lot of charts and tables requested by the users and multiple work flows. It's nice to be able to seperate them into multiple pages.

I guess there are workarounds like Tabs and Pipelines that should work. I have not tried those.

I guess another workaround is not to build a single page application but split the pages into multiple panel apps served by panel as multiple files. But then the user cannot move back and forth between pages without loosing state.

But It's a common design to have some kind of menubar to move between pages. So I think it should be supported.

@philippjfr

This comment has been minimized.

Copy link
Member

@philippjfr philippjfr commented Dec 3, 2019

You can also simulate pages by adding a Row/Column as a root and swapping out the contents.

@philippjfr

This comment has been minimized.

Copy link
Member

@philippjfr philippjfr commented Dec 3, 2019

2019-12-03 09:52:31,097 Cannot apply patch to 1046 which is not in the document anymore

This is a warning which can safely be ignored. We should definitely find a way to suppress these but I don't think they represent any actual issue.

@MarcSkovMadsen

This comment has been minimized.

Copy link
Author

@MarcSkovMadsen MarcSkovMadsen commented Dec 3, 2019

Hi @philippjfr

What do you mean by "as a root"?

@MarcSkovMadsen

This comment has been minimized.

Copy link
Author

@MarcSkovMadsen MarcSkovMadsen commented Dec 3, 2019

Hi @philippjfr

Thanks for commenting

I am swapping out content (i believe :-)).

The app.sidebar and app.main in the below image are columns. The navigator.selected_page depends on the navigator.page parameter. And the navigator.menu consists of buttons that update the navigator.page when a button is clicked.

image

image

I will try to make a small, reproducible example. I think that is the easiest to discuss. But note that as far as I read bokeh/bokeh#7738 swapping out content of Columns/ Rows can be problematic.

@philippjfr

This comment has been minimized.

Copy link
Member

@philippjfr philippjfr commented Dec 3, 2019

The bokeh devs have warned me that swapping out content can be problematic but I haven't actually found (m)any issues with it in practice, except for the generally harmless "Cannot apply patch" warning so a minimal example would be good. I suspect it may actually be an issue with templates which can be fixed (or already has been fixed on master).

@MarcSkovMadsen MarcSkovMadsen changed the title Cannot dynamically added and remove panes Cannot dynamically add and remove panes Dec 3, 2019
@MarcSkovMadsen

This comment has been minimized.

Copy link
Author

@MarcSkovMadsen MarcSkovMadsen commented Dec 3, 2019

Hi @philippjfr

Here is an small example reproducable example. I can partially add/ remove pages.

The problem here is that I cannot navigate back to the about page. The other pages works fine.

multi_page_app problems_example

import panel as pn
import param

PAGES = {
    "About": pn.pane.Markdown("about " * 2500, sizing_mode="stretch_width", name="About"),
    "Holoviews": pn.pane.Markdown(
        "holoviews " * 2500, sizing_mode="stretch_width", name="Holoviews"
    ),
    "Plotly": pn.pane.Markdown("plotly " * 2500, sizing_mode="stretch_width", name="Plotly"),
}

CSS = """\
body {
    margin: 0px;
    width: 100vh-500px;
}
"""


def main() -> pn.Pane:
    pn.config.raw_css.append(CSS)
    navigator = pn.widgets.RadioBoxGroup(name="RadioBoxGroup", options=list(PAGES))
    sidebar = pn.Column(navigator, pn.layout.VSpacer(), width=300, background="lightgray")

    @pn.depends(navigator.param.value)
    def page(page):
        print("---------")
        print(page)
        print(PAGES[page])
        return PAGES[page]

    content = pn.Column(page, sizing_mode="stretch_both")

    app = pn.Row(sidebar, content, sizing_mode="stretch_both")
    return app


if __name__.startswith("bk_script"):
    main().servable()
@MarcSkovMadsen

This comment has been minimized.

Copy link
Author

@MarcSkovMadsen MarcSkovMadsen commented Dec 3, 2019

A fix of the above script is to use the watch api instead of the reactive/ depends api.

multi_page_app problems_solution

import panel as pn
import param

PAGES = {
    "About": pn.pane.Markdown("about " * 2500, sizing_mode="stretch_width", name="About"),
    "Holoviews": pn.pane.Markdown(
        "holoviews " * 2500, sizing_mode="stretch_width", name="Holoviews"
    ),
    "Plotly": pn.pane.Markdown("plotly " * 2500, sizing_mode="stretch_width", name="Plotly"),
}

CSS = """\
body {
    margin: 0px;
    width: 100vh-500px;
}
"""


def main() -> pn.Pane:
    pn.config.raw_css.append(CSS)
    navigator = pn.widgets.RadioBoxGroup(name="RadioBoxGroup", options=list(PAGES))
    sidebar = pn.Column(navigator, pn.layout.VSpacer(), width=300, background="lightgray")
    content = pn.Column(PAGES["About"], sizing_mode="stretch_both")

    def page(event):
        print("---------")
        print(event)
        print(PAGES[event.new])
        content.clear()
        content.append(PAGES[event.new])

    navigator.param.watch(page, "value")

    app = pn.Row(sidebar, content, sizing_mode="stretch_both")
    return app


if __name__.startswith("bk_script"):
    main().servable()
@philippjfr philippjfr added type: bug and removed TRIAGE labels Dec 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.