widgetti / solara

A Pure Python, React-style Framework for Scaling Your Jupyter and Web Apps
https://solara.dev
MIT License
1.89k stars 139 forks source link

ipyaggrid does not update when new dataframe is loaded via solara.FileDrop #431

Open MaWeffm opened 10 months ago

MaWeffm commented 10 months ago

Hi, nice work, I really like Solara!

I am implementing an exploration tool for data frames. The user can drag and drop a file into a file dropper element and the dataframe is displayed using ipyaggrid.

Whenever I load a different file, output elements such as solara.Markdown are updated (e.g. showing the size of the newly loaded data frame). But the table does not update to contain the new data, please see a minimal working example below. Am I missing something? Thank you for your support on this!

import ipyaggrid
import pandas as pd
import solara

from io import StringIO

filename = solara.reactive(None)
filesize = solara.reactive(0)
filecontent = solara.reactive(None)

df_dict = solara.reactive(None)

def generate_column_defs(dict_list):
    return [{'field': key, 'filter': True} for key in dict_list[0].keys()] if dict_list else []

@solara.component
def FileDropper():
    progress, set_progress = solara.use_state(0.)

    def on_progress(value):
        set_progress(value)

    def on_file(file: solara.components.file_drop.FileInfo):
        filename.value = file["name"]
        filesize.value = file["size"]
        f = file["file_obj"]
        # todo: adjust code below to account for different file types (csv, tsv, MS Excel ...)
        filecontent.value = pd.read_csv(StringIO(str(f.read(), "utf-8")), sep="\t")

    solara.FileDrop(
        label="Drag and drop a file here",
        on_file=on_file,
        on_total_progress=on_progress,
        lazy=True,
    )
    solara.ProgressLinear(value=progress)
    if progress == 100:
        solara.Markdown(f"Loaded {filesize.value:n} bytes")

@solara.component
def Page():
    with solara.Sidebar():
        with solara.Card():
            FileDropper()

    if filecontent.value is not None:
        df_dict.value = filecontent.value.to_dict(orient="records")

        grid_options = {
            "columnDefs": generate_column_defs(df_dict.value),
            "defaultColDef": {
                "sortable": True
            },
            "enableSorting": True,
            "rowSelection": "multiple",
            "enableRangeSelection": True,
            "enableFilter": True,
            "enableColumnResize": True
        }

        with solara.Card():
            solara.Markdown(f"size: {filecontent.value.shape[0]}")
            ipyaggrid.Grid.element(
                grid_data=df_dict.value,
                grid_options=grid_options,
                columns_fit="auto",
                theme="ag-theme-blue",
                quick_filter=True,
                export_mode="buttons",
                export_csv=True,
                export_excel=True,
                export_to_df=True,
                sync_grid=True
            )
suredream commented 9 months ago

@MaWeffm any updates? Consider to use ipyaggrid in solara as well.

maartenbreddels commented 7 months ago

Hi,

sorry for the late reply, this and other issues with ipyaggrid and ipydatagrid led to those docs: https://github.com/widgetti/solara/pull/531 I hope that explains I well, if not, let me know here or on that PR.

Regards,

Maarten