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

Closed
MarcSkovMadsen opened this issue Dec 3, 2019 · 8 comments · Fixed by #967
Closed

Cannot dynamically add and remove panes #838

MarcSkovMadsen opened this issue Dec 3, 2019 · 8 comments · Fixed by #967
Labels
type: bug Something isn't correct or isn't working
Milestone

Comments

@MarcSkovMadsen
Copy link
Collaborator

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.

@MarcSkovMadsen MarcSkovMadsen added the TRIAGE Default label for untriaged issues label Dec 3, 2019
@philippjfr
Copy link
Member

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

@philippjfr
Copy link
Member

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
Copy link
Collaborator Author

Hi @philippjfr

What do you mean by "as a root"?

@MarcSkovMadsen
Copy link
Collaborator Author

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
Copy link
Member

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
Copy link
Collaborator Author

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
Copy link
Collaborator Author

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 Something isn't correct or isn't working and removed TRIAGE Default label for untriaged issues labels Dec 5, 2019
@philippjfr philippjfr added this to the v0.8.0 milestone Jan 19, 2020
@philippjfr
Copy link
Member

Appears to be the same issue as #853

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug Something isn't correct or isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants