How to prevent reload of preceding cells when changing widget value and/or make ipywidgets work?
hmanz opened this issue · comments
Hello. Thanks again for making Mercury, it's been great for dashboards!
One thing that I need help with is how to let the user update tables or plots without reloading all the previous cells (and making the screen do the grey-out with circle loading mouse) every time. The issue with this is that if the user made changes to previous cells, all those changes get reset when those previous cells are reloaded.
For updating tables, what I've done is just use itables
with the SearchBuilder
extension, which allows the user to add a filter and update the table without reloading all the previous cells in the notebook. It's also much faster than the mercury widgets. As a side note, isn't the table widget just a wrapper for itables
? Why shouldn't we just use itables
instead of the table widget?
For plots I can't use itables
, so there seems to be two potential solutions:
- Make mercury widgets just update the cell they apply to and not reload previous cells.
- Make
ipywidgets
work, because when I try using a dropdown ipywidget, it doesn't load in Mercury. This also has the added bonus of letting us put widgets next to the content/cells they apply to, instead of on the sidebar where it's not clear which content they apply to.
Thank you to all the contributors on this project :)
Hi @hmanz,
Thanks for using Mercury. Mercury is reloading cells only below updated widget, so you can try to move code that shouldn't be loaded at the top of the notebook. Please let me know if it works for you.
Hi @pplonski. Thank you for your response! Maybe I am doing something wrong, because in my case if I have an itables
table in a previous cell, changing the widget value for a lower cell will reset the itables
table. Here is a simple example using only mercury widgets:
import pandas as pd
import mercury as mr
# Example DataFrame
df = pd.DataFrame(
{
"name": ["Karol", "Szymon", "Piotr", "Ola"],
"second name": ["Falkowski", "Niewiński", "Płoński", "Płońska"],
"age": [20, 25, 38, 36],
}
)
mr.Table(data=df, width="200px", text_align="center")
my_selection = mr.Select(value = "a", choices = ["a", "b", "c"], label = "Select option")
print(my_selection.value)
Then run the dashboard, click on one of the table columns to sort it, and then try changing the my_selection
value to something other than "a". You will see that the table resets to the unsorted state.
Thanks @hmanz, I see what is the issue. Only cells below updated widget are recomputed, but we refresh whole html of the notebook, that's why you loose the itable selection. What you can do, you can try to write code that will control what data is displayed in itables, for example:
import pandas as pd
import mercury as mr
df = pd.DataFrame(
{
"name": ["Karol", "Szymon", "Piotr", "Ola"],
"second name": ["Falkowski", "Niewiński", "Płoński", "Płońska"],
"letter": ["a", "b", "c", "a"],
}
)
my_selection = mr.Select(value = "a", choices = ["a", "b", "c"], label = "Select option")
mr.Table(data=df[df.letter==my_selection.value], width="200px", text_align="center")
In the above example, you control the data in itables with Mercury widgets. Please let me know if it works for you.
Thanks for your response @pplonski. Unfortunately I don't think this solution will work because in my use case the selection widget has nothing to do with the table. In other words, in my notebook I have a table that is separate from the selection widget, and the selection widget is altering a different cell further down. So it seems the solution is either to somehow not refresh the entire html of the notebook and only refresh the cells below the changed widget, or to add support for usage of ipywidgets within a cell and not just the sidebar. I think the latter is better because then we can also place widgets next to the content they apply to, making it more intuitive for the user. Thanks!