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

reactive data for ipydatagrid #511

Closed
tharwan opened this issue Feb 21, 2024 · 2 comments
Closed

reactive data for ipydatagrid #511

tharwan opened this issue Feb 21, 2024 · 2 comments

Comments

@tharwan
Copy link

tharwan commented Feb 21, 2024

Hi, we were trying to update the table contents of ipydatagrid via a reactive variable. Our initial approach did not work:

import solara as sl
import pandas as pd
from ipydatagrid import DataGrid

meta = pd.DataFrame(columns=['name', 'region', "source"], 
    data=[["forecast", "de", "ws"], ["actual", "de", "ws"], ["intraday", "de", "ws"]])
selected_meta = sl.reactive(pd.DataFrame(columns=meta.columns))

@sl.component
def page():
    
    def handle_select(sel):
        selection_text.set(str(sel))
        selected_meta.value = pd.concat([selected_meta.value, meta[meta.index == sel[0]["r1"]]])
    
    dg1 = DataGrid.element(dataframe=meta, selection_mode="row", on_selections=handle_select)
    dg2 = DataGrid.element(dataframe=selected_meta.value, selection_mode="row")

our initial fix was to use effect:

import solara as sl
import pandas as pd
from ipydatagrid import DataGrid

meta = pd.DataFrame(columns=['name', 'region', "source"], 
    data=[["forecast", "de", "ws"], ["actual", "de", "ws"], ["intraday", "de", "ws"]])
selected_meta = sl.reactive(pd.DataFrame(columns=meta.columns))

@sl.component
def page():
    
    def handle_select(sel):
        selection_text.set(str(sel))
        selected_meta.value = pd.concat([selected_meta.value, meta[meta.index == sel[0]["r1"]]])

    def update_dg_2():
        wdg2 = sl.get_widget(dg2)
        wdg2.data = selected_meta.value
    
    dg1 = DataGrid.element(dataframe=meta, selection_mode="row", on_selections=handle_select)
    dg2 = DataGrid.element(dataframe=selected_meta.value, selection_mode="row")

    sl.use_effect(update_dg_2, dependencies=[selected_meta.value])

which does work, but out of curiosity we also tried the following

import solara as sl
import pandas as pd
from ipydatagrid import DataGrid

meta = pd.DataFrame(columns=['name', 'region', "source"], 
    data=[["forecast", "de", "ws"], ["actual", "de", "ws"], ["intraday", "de", "ws"]])
selected_meta = sl.reactive(pd.DataFrame(columns=meta.columns))

@sl.component
def page():
    
    def handle_select(sel):
        selection_text.set(str(sel))
        selected_meta.value = pd.concat([selected_meta.value, meta[meta.index == sel[0]["r1"]]])
    
    dg1 = DataGrid.element(dataframe=meta, selection_mode="row", on_selections=handle_select)
    dg2 = DataGrid.element(dataframe=selected_meta.value, data=selected_meta.value, selection_mode="row")

which works as well.

Since pydatagrid is mentioned in the docs we were a bit surprised that such a workaround was needed in the first place.

Is any of the two solutions preferable?
What would be the best way to support this in pydatagrid?

Best,

Florian

@maartenbreddels
Copy link
Contributor

Hi Florian,

lets start by saying that I am impressed with what you managed to figure out, and your creative solutions.

our initial fix was to use effect:

Yes, this is the preferred solution. I always planned to provide an example for ipydatagrid because of this issue, it's a nice example of how to deal with a library that has a constructor with arguments named differently from the traits, and where the updates are done via a differently named property (not even a trait).

If ipydatagrid would be more symmetric (e.g. its .data property would be named .dataframe - as mentioned in the docs) everything would be fine). The solution in your last example is creative, but I can imagine that in the future this will trigger warnings (data is not an argument of the DataGrid ctor).

Maybe we can ask the ipydatagrid maintainers to add a dataframe property?

In the meantime, this is an elegant solution, what do you think?:

from typing import Callable, Dict, List, cast
import solara
import solara as sl
import pandas as pd
from ipydatagrid import DataGrid as DataGridWidget

meta = pd.DataFrame(columns=['name', 'region', "source"], 
    data=[["forecast", "de", "ws"], ["actual", "de", "ws"], ["intraday", "de", "ws"]])
selected_meta = sl.reactive(pd.DataFrame(columns=meta.columns))
selection_text = sl.reactive("")



@solara.component
def DataGrid(dataframe, selection_mode: str, on_selections: Callable[[List[Dict]], None] = None, **kwargs):
    el = DataGridWidget.element(dataframe=dataframe, selection_mode=selection_mode, on_selections=on_selections, **kwargs)
    def update():
        widget = cast(DataGridWidget, solara.get_widget(el))
        widget.data = dataframe
    solara.use_effect(update, dependencies=[dataframe])


@sl.component
def Page():
    
    def handle_select(sel):
        print(sel)
        selected_meta.value = pd.concat([selected_meta.value, meta[meta.index == sel[0]["r1"]]])
    DataGrid(dataframe=meta, selection_mode="row", on_selections=handle_select)
    DataGrid(dataframe=selected_meta.value, selection_mode="row")

Also, do you think we should add this to https://solara.dev/docs/howto/ipywidget-libraries or maybe add an example at https://solara.dev/examples or both?

Regards,

Maarten

@tharwan
Copy link
Author

tharwan commented Feb 28, 2024

Looks great thanks!

@tharwan tharwan closed this as completed Feb 28, 2024
maartenbreddels added a commit that referenced this issue Mar 1, 2024
We also give specific examples for ipyaggrid and ipydatagrid which
are quite popular with solara.

Based on discussion on discord and:
 #512
 #511
maartenbreddels added a commit that referenced this issue Mar 10, 2024
We also give specific examples for ipyaggrid and ipydatagrid which
are quite popular with solara.

Based on discussion on discord and:
 #512
 #511
maartenbreddels added a commit that referenced this issue Apr 15, 2024
We also give specific examples for ipyaggrid and ipydatagrid which
are quite popular with solara.

Based on discussion on discord and:
 #512
 #511
maartenbreddels added a commit that referenced this issue Apr 15, 2024
We also give specific examples for ipyaggrid and ipydatagrid which
are quite popular with solara.

Based on discussion on discord and:
 #512
 #511
maartenbreddels added a commit that referenced this issue Apr 15, 2024
We also give specific examples for ipyaggrid and ipydatagrid which
are quite popular with solara.

Based on discussion on discord and:
 #512
 #511
maartenbreddels added a commit that referenced this issue Apr 15, 2024
We also give specific examples for ipyaggrid and ipydatagrid which
are quite popular with solara.

Based on discussion on discord and:
 #512
 #511
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

2 participants