You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
5.4 KiB
140 lines
5.4 KiB
from __future__ import annotations |
|
|
|
from typing import Dict, List, Optional, cast |
|
|
|
from .. import globals # pylint: disable=redefined-builtin |
|
from ..element import Element |
|
from ..functions.javascript import run_javascript |
|
|
|
try: |
|
import pandas as pd |
|
globals.optional_features.add('pandas') |
|
except ImportError: |
|
pass |
|
|
|
|
|
class AgGrid(Element, component='aggrid.js', libraries=['lib/aggrid/ag-grid-community.min.js']): |
|
|
|
def __init__(self, |
|
options: Dict, *, |
|
html_columns: List[int] = [], |
|
theme: str = 'balham', |
|
auto_size_columns: bool = True, |
|
) -> None: |
|
"""AG Grid |
|
|
|
An element to create a grid using `AG Grid <https://www.ag-grid.com/>`_. |
|
|
|
The `call_api_method` method can be used to call an AG Grid API method. |
|
|
|
:param options: dictionary of AG Grid options |
|
:param html_columns: list of columns that should be rendered as HTML (default: `[]`) |
|
:param theme: AG Grid theme (default: 'balham') |
|
:param auto_size_columns: whether to automatically resize columns to fit the grid width (default: `True`) |
|
""" |
|
super().__init__() |
|
self._props['options'] = options |
|
self._props['html_columns'] = html_columns |
|
self._props['auto_size_columns'] = auto_size_columns |
|
self._classes = ['nicegui-aggrid', f'ag-theme-{theme}'] |
|
|
|
@staticmethod |
|
def from_pandas(df: pd.DataFrame, *, |
|
theme: str = 'balham', |
|
auto_size_columns: bool = True, |
|
options: Dict = {}) -> AgGrid: |
|
"""Create an AG Grid from a Pandas DataFrame. |
|
|
|
:param df: Pandas DataFrame |
|
:param theme: AG Grid theme (default: 'balham') |
|
:param auto_size_columns: whether to automatically resize columns to fit the grid width (default: `True`) |
|
:param options: dictionary of additional AG Grid options |
|
:return: AG Grid element |
|
""" |
|
return AgGrid({ |
|
'columnDefs': [{'field': col} for col in df.columns], |
|
'rowData': df.to_dict('records'), |
|
'suppressDotNotation': True, |
|
**options, |
|
}, theme=theme, auto_size_columns=auto_size_columns) |
|
|
|
@property |
|
def options(self) -> Dict: |
|
return self._props['options'] |
|
|
|
def update(self) -> None: |
|
super().update() |
|
self.run_method('update_grid') |
|
|
|
def call_api_method(self, name: str, *args) -> None: |
|
"""Call an AG Grid API method. |
|
|
|
See `AG Grid API <https://www.ag-grid.com/javascript-data-grid/grid-api/>`_ for a list of methods. |
|
|
|
:param name: name of the method |
|
:param args: arguments to pass to the method |
|
""" |
|
self.run_method('call_api_method', name, *args) |
|
|
|
def call_column_api_method(self, name: str, *args) -> None: |
|
"""Call an AG Grid Column API method. |
|
|
|
See `AG Grid Column API <https://www.ag-grid.com/javascript-data-grid/column-api/>`_ for a list of methods. |
|
|
|
:param name: name of the method |
|
:param args: arguments to pass to the method |
|
""" |
|
self.run_method('call_column_api_method', name, *args) |
|
|
|
async def get_selected_rows(self) -> List[Dict]: |
|
"""Get the currently selected rows. |
|
|
|
This method is especially useful when the grid is configured with ``rowSelection: 'multiple'``. |
|
|
|
See `AG Grid API <https://www.ag-grid.com/javascript-data-grid/row-selection/#reference-selection-getSelectedRows>`_ for more information. |
|
|
|
:return: list of selected row data |
|
""" |
|
result = await run_javascript(f'return getElement({self.id}).gridOptions.api.getSelectedRows();') |
|
return cast(List[Dict], result) |
|
|
|
async def get_selected_row(self) -> Optional[Dict]: |
|
"""Get the single currently selected row. |
|
|
|
This method is especially useful when the grid is configured with ``rowSelection: 'single'``. |
|
|
|
:return: row data of the first selection if any row is selected, otherwise `None` |
|
""" |
|
rows = await self.get_selected_rows() |
|
return rows[0] if rows else None |
|
|
|
async def get_client_data(self) -> List[Dict]: |
|
"""Get the data from the client including any edits made by the client. |
|
|
|
This method is especially useful when the grid is configured with ``'editable': True``. |
|
|
|
See `AG Grid API <https://www.ag-grid.com/javascript-data-grid/accessing-data/>`_ for more information. |
|
|
|
Note that when editing a cell, the row data is not updated until the cell exits the edit mode. |
|
This does not happen when the cell loses focus, unless ``stopEditingWhenCellsLoseFocus: True`` is set. |
|
|
|
:return: list of row data |
|
""" |
|
result = await run_javascript(f''' |
|
const rowData = []; |
|
getElement({self.id}).gridOptions.api.forEachNode(node => rowData.push(node.data)); |
|
return rowData; |
|
''') |
|
return cast(List[Dict], result) |
|
|
|
async def load_client_data(self) -> None: |
|
"""Obtain client data and update the element's row data with it. |
|
|
|
This syncs edits made by the client in editable cells to the server. |
|
|
|
Note that when editing a cell, the row data is not updated until the cell exits the edit mode. |
|
This does not happen when the cell loses focus, unless ``stopEditingWhenCellsLoseFocus: True`` is set. |
|
""" |
|
client_row_data = await self.get_client_data() |
|
self.options['rowData'] = client_row_data |
|
self.update()
|
|
|