-
Notifications
You must be signed in to change notification settings - Fork 142
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: document better how to use classical ipywidgets in components
We also give specific examples for ipyaggrid and ipydatagrid which are quite popular with solara. Based on discussion on discord and: #512 #511
- Loading branch information
1 parent
19ba886
commit f38d6af
Showing
4 changed files
with
330 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
solara/website/pages/documentation/examples/libraries/ipyaggrid.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
""" | ||
# ipyaggrid | ||
[IPyAgGrid](https://github.com/widgetti/ipyaggrid) is a Jupyter widget for the [AG-Grid](https://www.ag-grid.com/) JavaScript library. | ||
It is a feature-rich datagrid designed for enterprise applications. | ||
To use it in a Solara component, requires a bit of manual wiring up of the dataframe and grid_options, as the widget does not have traits for these. | ||
For more details, see [the IPywidget libraries Howto](https://solara.dev/docs/howto/ipywidget-libraries). | ||
""" | ||
|
||
from typing import cast | ||
|
||
import ipyaggrid | ||
import plotly.express as px | ||
|
||
import solara | ||
|
||
df = px.data.iris() | ||
species = solara.reactive("setosa") | ||
filter_species = solara.reactive(True) | ||
|
||
|
||
@solara.component | ||
def AgGrid(df, grid_options): | ||
"""Convenient component wrapper around ipyaggrid.Grid""" | ||
|
||
def update_df(): | ||
widget = cast(ipyaggrid.Grid, solara.get_widget(el)) | ||
widget.grid_options = grid_options | ||
widget.update_grid_data(df) # this also updates the grid_options | ||
|
||
# when df changes, grid_data will be update, however, ... | ||
el = ipyaggrid.Grid.element(grid_data=df, grid_options=grid_options) | ||
# grid_data and grid_options are not traits, so letting them update by reacton/solara has no effect | ||
# instead, we need to get a reference to the widget and call .update_grid_data in a use_effect | ||
solara.use_effect(update_df, [df, grid_options]) | ||
return el | ||
|
||
|
||
@solara.component | ||
def Page(): | ||
grid_options = { | ||
"columnDefs": [ | ||
{"headerName": "Sepal Length", "field": "sepal_length"}, | ||
{"headerName": "Species", "field": "species"}, | ||
] | ||
} | ||
|
||
df_filtered = df.query(f"species == {species.value!r}") if filter_species.value else df | ||
|
||
solara.Select("Filter species", value=species, values=["setosa", "versicolor", "virginica"]) | ||
solara.Checkbox(label="Filter species", value=filter_species) | ||
AgGrid(df=df_filtered, grid_options=grid_options) |
55 changes: 55 additions & 0 deletions
55
solara/website/pages/documentation/examples/libraries/ipydatagrid.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
""" | ||
# ipydatagrid | ||
[ipydatagrid](https://github.com/bloomberg/ipydatagrid) is a Jupyter widget developed by Bloomberg which describes itself as a | ||
"Fast Datagrid widget for the Jupyter Notebook and JupyterLab". | ||
To use it in a Solara component requires a bit of manual wiring up of the dataframe, as this widget does not use a trait for this | ||
(and the property name does not match the constructor argument). | ||
For more details, see [the IPywidget libraries Howto](https://solara.dev/docs/howto/ipywidget-libraries). | ||
""" | ||
|
||
from typing import Dict, List, cast | ||
|
||
import ipydatagrid | ||
import plotly.express as px | ||
|
||
import solara | ||
|
||
df = px.data.iris() | ||
species = solara.reactive("setosa") | ||
filter_species = solara.reactive(True) | ||
|
||
|
||
@solara.component | ||
def DataGrid(df, **kwargs): | ||
"""Convenient component wrapper around ipydatagrid.DataGrid""" | ||
|
||
def update_df(): | ||
widget = cast(ipydatagrid.DataGrid, solara.get_widget(el)) | ||
# This is needed to update the dataframe, see | ||
# https://solara.dev/docs/howto/ipywidget-libraries for details | ||
widget.data = df | ||
|
||
el = ipydatagrid.DataGrid.element(dataframe=df, **kwargs) # does NOT change when df changes | ||
# we need to use .data instead (on the widget) to update the dataframe | ||
solara.use_effect(update_df, [df]) | ||
return el | ||
|
||
|
||
@solara.component | ||
def Page(): | ||
selections: solara.Reactive[List[Dict]] = solara.use_reactive([]) | ||
df_filtered = df.query(f"species == {species.value!r}") if filter_species.value else df | ||
|
||
with solara.Card("ipydatagrid demo", style={"width": "700px"}): | ||
solara.Select("Filter species", value=species, values=["setosa", "versicolor", "virginica"]) | ||
solara.Checkbox(label="Filter species", value=filter_species) | ||
DataGrid(df=df_filtered, selection_mode="row", selections=selections.value, on_selections=selections.set) | ||
if selections.value: | ||
with solara.Column(): | ||
solara.Text(f"Selected rows: {selections.value!r}") | ||
solara.Button("Clear selections", on_click=lambda: selections.set([])) |