PablocFonseca / streamlit-aggrid

Implementation of Ag-Grid component for Streamlit
https://pypi.org/project/streamlit-aggrid/
MIT License
1.06k stars 202 forks source link

Accessing `selected_rows` from a second grid in the view #117

Closed mabergerx closed 6 months ago

mabergerx commented 2 years ago

I have two AgGrids in my view with which I interact using other components like a dropdown and a button.

One grid is where the main data is being presented, and the individual rows can be chosen via checkboxes. Once the rows are chosen, a user can click on a button to change the underlying data and trigger the rendering of the second grid, which shows a certain selection of rows from the main view.

Retrieving the selected rows from the main grid goes just fine, and I can successfully render the second grid using the selected rows from the main grid. However, when I try to access the selected rows in the second grid, using all kinds of update modes, I can't get hold of the selected rows without the app re-running. This results in me never being able to retrieve the second selection.

Here is the code:

def filter_and_persist_df(df):
    df = df[df["subcategory"] == "Unknown"]
    st.session_state['full_df_categorized_to_show'] = df

def configure_aggrid(source_df, height, key, wrap=False, refresh_mode=GridUpdateMode.SELECTION_CHANGED):
    gb = GridOptionsBuilder.from_dataframe(source_df)
    gb.configure_pagination(paginationAutoPageSize=True)
    gb.configure_side_bar()
    gb.configure_selection("multiple", use_checkbox=True, groupSelectsChildren=True,
                           groupSelectsFiltered=True)
    gridOptions = gb.build()
    return AgGrid(source_df, gridOptions=gridOptions,
                  enable_enterprise_modules=True,
                  fit_columns_on_grid_load=True, editable=False, theme='material', height=height,
                  update_mode=refresh_mode, key=key)

try:
    full_df_categorized_to_show = st.session_state['full_df_categorized_to_show']

    with column1:
        main_table = configure_aggrid(full_df_categorized_to_show, height=800, key=None)

    with column2:

        subcategory_selector = st.selectbox(
            'Select the right subcategory for the transactions',
            subcats)

        # Logic for handling selected transaction rows

        selected_rows_main = main_table['selected_rows']
        button_disabled = len(selected_rows_main) < 1

        classify_button = st.button("Categorize", disabled=button_disabled)

        if classify_button:
            st.session_state["expander_expanded"] = True
            selected_ids = [item["id"] for item in selected_rows_main]
            full_df_categorized_to_show.loc[
                full_df_categorized_to_show["id"].isin(selected_ids), ["subcategory"]] = subcategory_selector
            filter_and_persist_df(full_df_categorized_to_show)

    st.write("Found similar datapoints:")
    neighbour_ids = [int(id) for id in retrieve_neighbour_ids(selected_ids)]
    source_df = st.session_state['full_df_categorized_to_show']
    neighbours_df = source_df.loc[source_df["id"].isin(neighbour_ids)]
    neighbours_table = configure_aggrid(neighbours_df, 500, key=None, wrap=False,
                                        refresh_mode=GridUpdateMode.SELECTION_CHANGED)
    if "selected_neighbours" not in st.session_state:
        st.session_state["selected_neighbours"] = neighbours_table["selected_rows"].copy()
    selected_neighbours = neighbours_table["selected_rows"]

except KeyError:
    st.title("Upload a file to proceed")

I can't quite pinpoint the way to actually get the second selected rows without the app re-running, like I seem to able to have in the main grid. Does it have to do something with something in the state?

Thank you very much in advance!

GGA-PERSO commented 2 years ago

@mabergerx I was not able to reproduce your issue on my own data example :
image

here the code

st.subheader('initial df') st.write(df1) st.write(df2)

gb = GridOptionsBuilder.from_dataframe(df1)
gb.configure_selection('single', use_checkbox=False) gridOptions = gb.build()

gb2 = GridOptionsBuilder.from_dataframe(df2)
gb2.configure_selection('single', use_checkbox=False) gridOptions2 = gb2.build()

st.subheader(' if you select a row from 1st grid it keeps rows with same id and then if i select a row on 2nd grid I can correctly display the selected row below')
grid_response = AgGrid(df1, height=100, gridOptions = gridOptions, data_return_mode=DataReturnMode.FILTERED, update_mode=GridUpdateMode.MODEL_CHANGED, enable_enterprise_modules=True)

line_df1_selected = grid_response['selected_rows'] selected_ids = [row["id"] for row in line_df1_selected] neighbours_df = df2.loc[df2["id"].isin(selected_ids)]

grid_response2 = AgGrid(neighbours_df, height=100, gridOptions = gridOptions2, data_return_mode=DataReturnMode.FILTERED, update_mode=GridUpdateMode.MODEL_CHANGED, enable_enterprise_modules=True)

line_df2_selected = grid_response2['selected_rows'] st.write(line_df2_selected)