{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# AG Grid\n", "使用[AG Grid](https://www.ag-grid.com/)创建网格的元素。\n", "\n", "可以使用`run_grid_method`和`run_column_method`方法与客户机上的AG Grid实例进行交互。\n", "\n", "- `options`:AG Grid选项的字典\n", "- `html_columns`:应该以HTML渲染的列的列表(默认:`[]`)\n", "- `theme`:AG Grid主题(默认:`'balham'`)\n", "- `auto_size_columns`:是否自动调整列宽以适应网格宽度(默认:`True`)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from nicegui import ui\n", "\n", "grid = ui.aggrid({\n", " 'defaultColDef': {'flex': 1},\n", " 'columnDefs': [\n", " {'headerName': 'Name', 'field': 'name'},\n", " {'headerName': 'Age', 'field': 'age'},\n", " {'headerName': 'Parent', 'field': 'parent', 'hide': True},\n", " ],\n", " 'rowData': [\n", " {'name': 'Alice', 'age': 18, 'parent': 'David'},\n", " {'name': 'Bob', 'age': 21, 'parent': 'Eve'},\n", " {'name': 'Carol', 'age': 42, 'parent': 'Frank'},\n", " ],\n", " 'rowSelection': 'multiple',\n", "}).classes('max-h-40')\n", "\n", "def update():\n", " grid.options['rowData'][0]['age'] += 1\n", " grid.update()\n", "\n", "ui.button('Update', on_click=update)\n", "ui.button('Select all', on_click=lambda: grid.run_grid_method('selectAll'))\n", "ui.button('Show parent', on_click=lambda: grid.run_column_method('setColumnVisible', 'parent', True))\n", "\n", "# ui.run()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 选择AG Grid行\n", "您可以在网格单元格中添加复选框,允许用户选择单个或多个行。\n", "\n", "要获取当前选定的行,请使用`get_selected_rows`方法。此方法返回一个由字典组成的行列表。\n", "\n", "如果`rowSelection`设置为`'single'`或者要获取第一个选定的行,您也可以使用`get_selected_row`方法。该方法返回一个单一行为字典,如果没有选定行则返回`None`。\n", "\n", "有关更多信息,请参阅[AG Grid文档](https://www.ag-grid.com/javascript-data-grid/row-selection/#example-single-row-selection)。" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from nicegui import ui\n", "\n", "grid = ui.aggrid({\n", " 'columnDefs': [\n", " {'headerName': 'Name', 'field': 'name', 'checkboxSelection': True},\n", " {'headerName': 'Age', 'field': 'age'},\n", " ],\n", " 'rowData': [\n", " {'name': 'Alice', 'age': 18},\n", " {'name': 'Bob', 'age': 21},\n", " {'name': 'Carol', 'age': 42},\n", " ],\n", " 'rowSelection': 'multiple',\n", "}).classes('max-h-40')\n", "\n", "async def output_selected_rows():\n", " rows = await grid.get_selected_rows()\n", " if rows:\n", " for row in rows:\n", " ui.notify(f\"{row['name']}, {row['age']}\")\n", " else:\n", " ui.notify('No rows selected.')\n", "\n", "async def output_selected_row():\n", " row = await grid.get_selected_row()\n", " if row:\n", " ui.notify(f\"{row['name']}, {row['age']}\")\n", " else:\n", " ui.notify('No row selected!')\n", "\n", "ui.button('Output selected rows', on_click=output_selected_rows)\n", "ui.button('Output selected row', on_click=output_selected_row)\n", "\n", "# ui.run()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 使用迷你过滤器过滤行\n", "您可以在每列的标题中添加[迷你过滤器](https://ag-grid.com/javascript-data-grid/filter-set-mini-filter/)来过滤行。\n", "\n", "注意`\"agTextColumnFilter\"`如何匹配单个字符,例如`\"Alice\"`和`\"Carol\"`中的`\"a\"`,而`\"agNumberColumnFilter\"`则匹配整个数字,例如`\"18\"`和`\"21\"`,但不包括`\"1\"`。" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from nicegui import ui\n", "\n", "ui.aggrid({\n", " 'columnDefs': [\n", " {'headerName': 'Name', 'field': 'name', 'filter': 'agTextColumnFilter', 'floatingFilter': True},\n", " {'headerName': 'Age', 'field': 'age', 'filter': 'agNumberColumnFilter', 'floatingFilter': True},\n", " ],\n", " 'rowData': [\n", " {'name': 'Alice', 'age': 18},\n", " {'name': 'Bob', 'age': 21},\n", " {'name': 'Carol', 'age': 42},\n", " ],\n", "}).classes('max-h-40')\n", "\n", "# ui.run()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## AG Grid带有条件单元格格式化\n", "此演示展示了如何使用[`cellClassRules`](https://www.ag-grid.com/javascript-grid-cell-styles/#cell-class-rules)根据单元格的值有条件地格式化单元格。" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from nicegui import ui\n", "\n", "ui.aggrid({\n", " 'columnDefs': [\n", " {'headerName': 'Name', 'field': 'name'},\n", " {'headerName': 'Age', 'field': 'age', 'cellClassRules': {\n", " 'bg-red-300': 'x < 21',\n", " 'bg-green-300': 'x >= 21',\n", " }},\n", " ],\n", " 'rowData': [\n", " {'name': 'Alice', 'age': 18},\n", " {'name': 'Bob', 'age': 21},\n", " {'name': 'Carol', 'age': 42},\n", " ],\n", "})\n", "\n", "# ui.run()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 从Pandas DataFrame创建网格\n", "您可以使用`from_pandas`方法从Pandas DataFrame创建一个AG Grid。此方法接受一个Pandas DataFrame作为输入,并返回一个AG Grid。" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import pandas as pd\n", "from nicegui import ui\n", "\n", "df = pd.DataFrame(data={'col1': [1, 2], 'col2': [3, 4]})\n", "ui.aggrid.from_pandas(df).classes('max-h-40')\n", "\n", "# ui.run()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 将列渲染为HTML\n", "您可以通过将列索引列表传递给`html_columns`参数来将列渲染为HTML。" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from nicegui import ui\n", "\n", "ui.aggrid({\n", " 'columnDefs': [\n", " {'headerName': 'Name', 'field': 'name'},\n", " {'headerName': 'URL', 'field': 'url'},\n", " ],\n", " 'rowData': [\n", " {'name': 'Google', 'url': 'https://google.com'},\n", " {'name': 'Facebook', 'url': 'https://facebook.com'},\n", " ],\n", "}, html_columns=[1])\n", "\n", "# ui.run()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 响应AG Grid事件\n", "所有AG Grid事件都通过AG Grid全局监听器传递给NiceGUI。这些事件可以使用`.on()`方法进行订阅。" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from nicegui import ui\n", "\n", "ui.aggrid({\n", " 'columnDefs': [\n", " {'headerName': 'Name', 'field': 'name'},\n", " {'headerName': 'Age', 'field': 'age'},\n", " ],\n", " 'rowData': [\n", " {'name': 'Alice', 'age': 18},\n", " {'name': 'Bob', 'age': 21},\n", " {'name': 'Carol', 'age': 42},\n", " ],\n", "}).on('cellClicked', lambda event: ui.notify(f'Cell value: {event.args[\"value\"]}'))\n", "\n", "# ui.run()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## AG Grid中使用复杂对象\n", "您可以通过用句点分隔字段名来在AG Grid中使用嵌套的复杂对象。(这就是为什么`rowData`中的键不允许包含句点的原因。)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from nicegui import ui\n", "\n", "ui.aggrid({\n", " 'columnDefs': [\n", " {'headerName': 'First name', 'field': 'name.first'},\n", " {'headerName': 'Last name', 'field': 'name.last'},\n", " {'headerName': 'Age', 'field': 'age'}\n", " ],\n", " 'rowData': [\n", " {'name': {'first': 'Alice', 'last': 'Adams'}, 'age': 18},\n", " {'name': {'first': 'Bob', 'last': 'Brown'}, 'age': 21},\n", " {'name': {'first': 'Carol', 'last': 'Clark'}, 'age': 42},\n", " ],\n", "}).classes('max-h-40')\n", "\n", "# ui.run()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## AG Grid中使用动态行高\n", "您可以通过将一个函数传递给`getRowHeight`参数来设置个别行的高度。" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from nicegui import ui\n", "\n", "ui.aggrid({\n", " 'columnDefs': [{'field': 'name'}, {'field': 'age'}],\n", " 'rowData': [\n", " {'name': 'Alice', 'age': '18'},\n", " {'name': 'Bob', 'age': '21'},\n", " {'name': 'Carol', 'age': '42'},\n", " ],\n", " ':getRowHeight': 'params => params.data.age > 35 ? 50 : 25',\n", "}).classes('max-h-40')\n", "\n", "# ui.run()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 运行行方法\n", "您可以使用`run_row_method`方法在个别行上运行方法。此方法接受行`ID`、方法名称和方法参数作为参数。行`ID`可以是行索引(作为字符串)或`getRowId`函数的值。\n", "\n", "以下演示展示了如何使用它来更新单元格值。请注意,当值更新时,行选择会被保留。如果使用`update`方法更新网格,情况将不会如此。" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from nicegui import ui\n", "\n", "grid = ui.aggrid({\n", " 'columnDefs': [\n", " {'field': 'name', 'checkboxSelection': True},\n", " {'field': 'age'},\n", " ],\n", " 'rowData': [\n", " {'name': 'Alice', 'age': 18},\n", " {'name': 'Bob', 'age': 21},\n", " {'name': 'Carol', 'age': 42},\n", " ],\n", " ':getRowId': '(params) => params.data.name',\n", "})\n", "ui.button('Update',\n", " on_click=lambda: grid.run_row_method('Alice', 'setDataValue', 'age', 99))\n", "\n", "# ui.run()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 过滤返回值\n", "您可以通过传递定义JavaScript函数的字符串来过滤方法调用的返回值。此演示运行了网格方法`\"getDisplayedRowAtIndex\"`并返回结果的`\"data\"`属性。" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from nicegui import ui\n", "\n", "grid = ui.aggrid({\n", " 'columnDefs': [{'field': 'name'}],\n", " 'rowData': [{'name': 'Alice'}, {'name': 'Bob'}],\n", "})\n", "\n", "async def get_first_name() -> None:\n", " row = await grid.run_grid_method('(g) => g.getDisplayedRowAtIndex(0).data')\n", " ui.notify(row['name'])\n", "\n", "ui.button('Get First Name', on_click=get_first_name)\n", "\n", "# ui.run()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "py311", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.7" } }, "nbformat": 4, "nbformat_minor": 2 }