Dash DataTable 组件在列标题下提供自由文本过滤器。
如何将此过滤器替换为包含所有可供选择的唯一值的下拉过滤器?
Excel 中有现成的东西:
或者在 DataTables JavaScript 组件中进行一些简单的修改
我知道我可以在通过回调与 DataTable 交互的 DataTable 之外使用下拉过滤器,但我希望下拉过滤器成为 DataTable 列标题的一部分。从这个意义上说,我不想使用以下解决方案:在破折号中从下拉列表中过滤行后显示数据表
答案更新:2023
import pandas as pd
import dash
from dash import Dash, Input, Output, dcc, html, dash_table, State
# Sample filter & data
place_holder = None
df_filter = pd.DataFrame(
{
"Person": [place_holder],
"Age": [place_holder],
"Gender": [place_holder],
"Occupation": [place_holder],
}
)
df_data = pd.DataFrame(
{
"Person": ["Alice", "Brian", "Chris", "David", "Emily"],
"Age": [25, 30, 36, 25, 36],
"Gender": ["Female", "Male", "Male", "Male", "Female"],
"Occupation": ["Engineer", "Doctor", "Lawyer", "Artist", "Artist"],
}
)
app = Dash(__name__)
app.layout = html.Div(
[
html.H1("DataTable with Header Dropdowns for Filtering"),
html.H2("Filtering Table"),
html.Div(
[
dash_table.DataTable(
id="table-filter",
columns=[
{"name": i, "id": i, "presentation": "dropdown"}
for i in df_filter.columns
],
data=df_filter.to_dict("records"),
editable=True,
dropdown={
col: {
"options": [
{"label": str(i), "value": str(i)}
for i in df_data[col].unique()
],
}
for col in df_data.columns
},
)
]
),
dash_table.DataTable(
id="table-data",
columns=[{"name": i, "id": i} for i in df_data.columns],
data=df_data.to_dict("records"),
style_table={"overflowX": "scroll"},
css=[{"selector": "tr:first-child", "rule": "display: none",},],
),
html.Div(id="table-output"),
],
# NOTE The margin of 5% set here needs to match the CSS width set in custom.css
# and depends on the total number of columns (so that the filter table sits
# flush with the header-hidden data table below it being filtered).
style={"textAlign": "center", "margin": "5%"},
)
# Callback for updating table based on dropdown selection
@app.callback(
Output("table-data", "data"),
[Input("table-filter", "data_timestamp")],
[State("table-filter", "data"), State("table-data", "data")],
)
def update_table(timestamp, filter_rows, current_data):
if timestamp is None:
raise dash.exceptions.PreventUpdate
data = df_data.copy()
cols = data.columns
for col, value in filter_rows[0].items():
if value is not None:
data = data[data.astype(str)[col] == value]
return data.to_dict("records")
app.run_server(debug=True)
结果: 但请注意,目前无法为 Dash DataTables 中的下拉菜单设置
multi=True
(就像针对 dash.dcc.Dropdown
组件一样)。如果需要这种过滤功能,最好使用 Dash DataTables 的内置过滤功能,或者参见下面的选项 #2。
import dash
import pandas as pd
from dash import dash_table as dt
from dash import dcc
from dash import html
from dash.dependencies import Input
from dash.dependencies import Output
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/solar.csv")
app = dash.Dash(__name__)
states = df.State.unique().tolist()
app.layout = html.Div(
children=[
dcc.Dropdown(
id="filter_dropdown",
options=[{"label": st, "value": st} for st in states],
placeholder="-Select a State-",
multi=True,
value=df.State.values,
),
dt.DataTable(
id="table-container",
columns=[{"name": i, "id": i} for i in df.columns],
data=df.to_dict("records")
)
]
)
@app.callback(
Output("table-container", "data"),
Input("filter_dropdown", "value")
)
def display_table(state):
dff = df[df.State.isin(state)]
return dff.to_dict("records")
if __name__ == "__main__":
app.run_server(debug=True)
→ 选择红色 ❌ 至
Clear all
一种选择是将以下 CSS 添加到本地
./assets/custom.css
文件中:
.Select--multi .Select-value {
display: none;
}
这将导致以下行为:
(您可以在下拉列表上方添加一些标题或其他内容,以指示“选择一个州”等)
注意:在此实现案例中,您可能需要将参数
添加到row_deletable=True
。然而,我刚刚测试了这个,它不会自动用选项重新填充下拉列表,因此,需要发明更多代码来解决这个问题,我认为这是可能的。但你明白了。dt.DataTable