Skip to content

Commit

Permalink
allow updating a table with a dataframe
Browse files Browse the repository at this point in the history
  • Loading branch information
falkoschindler committed Aug 16, 2024
1 parent 9b8cfe3 commit 96f83e7
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 14 deletions.
39 changes: 30 additions & 9 deletions nicegui/elements/table.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Callable, Dict, List, Literal, Optional, Union
from typing import Any, Callable, Dict, List, Literal, Optional, Tuple, Union

from typing_extensions import Self

Expand Down Expand Up @@ -116,6 +116,34 @@ def from_pandas(cls,
:param on_select: callback which is invoked when the selection changes
:return: table element
"""
rows, columns = cls._df_to_rows_and_columns(df)
return cls(
rows=rows,
columns=columns,
row_key=row_key,
title=title,
selection=selection,
pagination=pagination,
on_select=on_select,
)

def update_from_pandas(self, df: 'pd.DataFrame', *, clear_selection: bool = True) -> None:
"""Update the table from a Pandas DataFrame.
See `from_pandas()` for more information about the conversion of non-serializable columns.
:param df: Pandas DataFrame
:param clear_selection: whether to clear the selection (default: True)
"""
rows, columns = self._df_to_rows_and_columns(df)
self.rows[:] = rows
self.columns[:] = columns
if clear_selection:
self.selected.clear()
self.update()

@staticmethod
def _df_to_rows_and_columns(df: 'pd.DataFrame') -> Tuple[List[Dict], List[Dict]]:
def is_special_dtype(dtype):
return (pd.api.types.is_datetime64_any_dtype(dtype) or
pd.api.types.is_timedelta64_dtype(dtype) or
Expand All @@ -131,14 +159,7 @@ def is_special_dtype(dtype):
'You can convert them to strings using something like '
'`df.columns = ["_".join(col) for col in df.columns.values]`.')

return cls(
columns=[{'name': col, 'label': col, 'field': col} for col in df.columns],
rows=df.to_dict('records'),
row_key=row_key,
title=title,
selection=selection,
pagination=pagination,
on_select=on_select)
return df.to_dict('records'), [{'name': col, 'label': col, 'field': col} for col in df.columns]

@property
def rows(self) -> List[Dict]:
Expand Down
17 changes: 12 additions & 5 deletions tests/test_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,17 +171,24 @@ def replace_rows_with_daniel():
screen.should_contain('Daniel')


def test_create_from_pandas(screen: Screen):
df = pd.DataFrame({'name': ['Alice', 'Bob'], 'age': [18, 21], 42: 'answer'})
ui.table.from_pandas(df)
def test_create_and_update_from_pandas(screen: Screen):
df = pd.DataFrame({'name': ['Alice', 'Bob'], 'age': [18, 21]})
table = ui.table.from_pandas(df)

def update():
df.loc[2] = ['Lionel', 19]
table.update_from_pandas(df)
ui.button('Update', on_click=update)

screen.open('/')
screen.should_contain('Alice')
screen.should_contain('Bob')
screen.should_contain('18')
screen.should_contain('21')
screen.should_contain('42')
screen.should_contain('answer')

screen.click('Update')
screen.should_contain('Lionel')
screen.should_contain('19')


def test_problematic_datatypes(screen: Screen):
Expand Down

0 comments on commit 96f83e7

Please sign in to comment.