Dash 数据表下拉过滤器

dzi*_*iou 5 python plotly-dash

Dash DataTable 组件在列标题下提供了一个自由文本过滤器。

Dash 自由文本过滤器

如何用包含所有可供选择的唯一值的下拉过滤器替换此过滤器?

Excel 中现成的东西:

Excel 下拉过滤器

或者在DataTables JavaScript 组件中进行一些简单的修改

数据表下拉过滤器

我知道我可以在通过回调与 DataTable 交互的 DataTable 之外使用下拉过滤器,但我希望下拉过滤器成为 DataTable 列标题的一部分。从这个意义上说,我不想使用以下解决方案:在破折号中从下拉列表中过滤行后显示数据表

joh*_*ins 4

选项#1:使用 Dash 的内置 DataTable 下拉属性

\n

答案更新时间:2023

\n

例如,使用如下简单的项目设置:

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app.py\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 assets\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 custom.css\n\n2 directories, 2 files\n
Run Code Online (Sandbox Code Playgroud)\n

其中assets/custom.css包含:

\n
.dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner td, .dash-table-container .dash-spreadsheet-container .dash-spreadsheet-inner th {\n    text-align: center !important;\n    width: 20%\n}\n
Run Code Online (Sandbox Code Playgroud)\n

app.py包含:

\n
import pandas as pd\nimport dash\nfrom dash import Dash, Input, Output, dcc, html, dash_table, State\n\n# Sample filter & data\nplace_holder = None\ndf_filter = pd.DataFrame(\n    {\n        "Person": [place_holder],\n        "Age": [place_holder],\n        "Gender": [place_holder],\n        "Occupation": [place_holder],\n    }\n)\ndf_data = pd.DataFrame(\n    {\n        "Person": ["Alice", "Brian", "Chris", "David", "Emily"],\n        "Age": [25, 30, 36, 25, 36],\n        "Gender": ["Female", "Male", "Male", "Male", "Female"],\n        "Occupation": ["Engineer", "Doctor", "Lawyer", "Artist", "Artist"],\n    }\n)\n\n\napp = Dash(__name__)\n\napp.layout = html.Div(\n    [\n        html.H1("DataTable with Header Dropdowns for Filtering"),\n        html.H2("Filtering Table"),\n        html.Div(\n            [\n                dash_table.DataTable(\n                    id="table-filter",\n                    columns=[\n                        {"name": i, "id": i, "presentation": "dropdown"}\n                        for i in df_filter.columns\n                    ],\n                    data=df_filter.to_dict("records"),\n                    editable=True,\n                    dropdown={\n                        col: {\n                            "options": [\n                                {"label": str(i), "value": str(i)}\n                                for i in df_data[col].unique()\n                            ],\n                        }\n                        for col in df_data.columns\n                    },\n                )\n            ]\n        ),\n        dash_table.DataTable(\n            id="table-data",\n            columns=[{"name": i, "id": i} for i in df_data.columns],\n            data=df_data.to_dict("records"),\n            style_table={"overflowX": "scroll"},\n            css=[{"selector": "tr:first-child", "rule": "display: none",},],\n        ),\n        html.Div(id="table-output"),\n    ],\n    # NOTE The CSS margin set below and also the width set in the\n    # custom.css file depends on the number of columns in this example.\n    # Alternative &/or additional CSS (e.g., overflow) would be probably\n    # best for data tables with many more columns.\n    style={"textAlign": "center", "margin": "5%"},\n)\n\n\n# Callback for updating table based on dropdown selection\n@app.callback(\n    Output("table-data", "data"),\n    [Input("table-filter", "data_timestamp")],\n    [State("table-filter", "data"), State("table-data", "data")],\n)\ndef update_table(timestamp, filter_rows, current_data):\n    if timestamp is None:\n        raise dash.exceptions.PreventUpdate\n\n    data = df_data.copy()\n    cols = data.columns\n\n    for col, value in filter_rows[0].items():\n        if value is not None:\n            data = data[data.astype(str)[col] == value]\n\n    return data.to_dict("records")\n\n\napp.run_server(debug=True)\n
Run Code Online (Sandbox Code Playgroud)\n

结果为:\n视频屏幕截图记录显示带有类似 Excel 下拉列过滤功能的 dash 应用程序\n但请注意,目前无法multi=True在 Dash DataTables 中设置下拉菜单(就像组件一样dash.dcc.Dropdown)。如果需要这种过滤功能,最好使用Dash DataTables 的内置过滤功能,或者参见下面的选项 #2。

\n

选项#2:使用 Dash 数据表之外的下拉菜单

\n
import dash\nimport pandas as pd\n\nfrom dash import dash_table as dt\nfrom dash import dcc\nfrom dash import html\nfrom dash.dependencies import Input\nfrom dash.dependencies import Output\n\ndf = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/solar.csv")\n\napp = dash.Dash(__name__)\n\nstates = df.State.unique().tolist()\n\napp.layout = html.Div(\n    children=[\n        dcc.Dropdown(\n            id="filter_dropdown",\n            options=[{"label": st, "value": st} for st in states],\n            placeholder="-Select a State-",\n            multi=True,\n            value=df.State.values,\n        ),\n        dt.DataTable(\n            id="table-container",\n            columns=[{"name": i, "id": i} for i in df.columns],\n            data=df.to_dict("records")\n        )\n    ]\n)\n\n\n@app.callback(\n    Output("table-container", "data"), \n    Input("filter_dropdown", "value")\n)\ndef display_table(state):\n    dff = df[df.State.isin(state)]\n    return dff.to_dict("records")\n\n\nif __name__ == "__main__":\n    app.run_server(debug=True)\n\n
Run Code Online (Sandbox Code Playgroud)\n

应用首次显示

\n

\xe2\x86\x92 选择红色\xe2\x9d\x8cClear all

\n

清除表

\n

从下拉列表中选择的选项

\n

如果您不希望所选选项始终存在/显示:

\n

一种选择是将以下 CSS 添加到本地./assets/custom.css文件:

\n
.Select--multi .Select-value {\n    display: none;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这将导致以下行为:

\n

未显示选项

\n

(您可以在下拉列表上方添加一些标题或其他内容,以指示“选择一个州”等。)

\n

选项实际上仍然被选择

\n
\n

注意:在此实现案例中,您可能希望另外将参数添加row_deletable=Truedt.DataTable. 然而,我刚刚测试了这个,它不会自动用选项重新填充下拉列表,因此,需要发明更多代码来解决这个问题,我认为这是可能的。但你明白了。

\n
\n