关于Dash Python中布局更改的问题

Question for layout change in Dash Python

提问人:stat_man 提问时间:9/25/2023 更新时间:9/25/2023 访问量:27

问:

我正在开发 Dash 应用程序,用于显示具有过滤功能的表格。

因为我有很多变量,所以我想使用 callback 来创建变量过滤器。

它将是这样的:

enter image description here

应用过滤器后,它将是这样的:

enter image description here

但是,问题是在应用过滤器之前已经显示了选定的过滤器部分。

enter image description here

下面是布局代码:

layout = html.Div(id="Data", children=[
            getMenu('Data'),
        dbc.Row(
            className="area_content",
            children=[
                dbc.Col([
                    panel_left.content,
                ], width={'size' :3}, className="area_L"),
                dbc.Col([
                    dbc.Card(
                            [
                                dbc.CardHeader(html.H3("Used filter")),
                                dbc.CardBody(
                                            html.Div(id="filter_container", children=[]),
                                            )])],width={'size' :3} ,className="filter"),
                dbc.Col([
                    panel_description.content,
                    panel_contents.content
                ], width={'size' :6,"order": "last"}, className="area_R")
            ],style={'width':'100%'}
        )
    ])

和回调代码:

@appDash.callback(
    Output('filter_container', 'children', allow_duplicate=True),
    Input('add_filter_btn', 'n_clicks'),
    [State('filter_container', 'children'),
    State("second_filter", "value"),
    State('filter_table', 'value')],
    prevent_initial_call='initial_duplicate'
)
    def add_filter(n_clicks, current_filter, selected_columns, selected_table):
        df = get_selected_dataframe(selected_table)
        columns = df.columns
        patched_children = Patch()
        added_columns = []  # Maintain a list of added columns

        if current_filter is None:
            current_filter = []  # Initialize as an empty list if it's None

        if n_clicks is not None and selected_columns:
            for child in current_filter:
                # Extract the selected column from the existing filters
                selected_col = child['props']['children'][1]['props']['value']
                added_columns.append(selected_col)
            for col in [selected_columns]:
                if col in added_columns:
                    # Skip adding the filter for the same column
                    continue

                column_type = df[col].dtype
                if column_type == 'object':
                    unique_values = df[col].unique()
                    new_filter = html.Div([
                        html.Br(),
                        dcc.Dropdown(
                            id={"type": "filter_column", "index": n_clicks},
                            value=col,
                            options=[{"label": col, "value": col} for col in columns],
                            disabled=True,
                        ),
                        dcc.Dropdown(
                            id={"type": "filter_cat", "table": selected_table, "index": col},
                            options=[{"label": str(val), "value": val} for val in unique_values],
                            placeholder="Select a value",
                            multi=True,
                        ),
                        dbc.Row(dbc.Button("X", id={"type": "remove_btn", "table": selected_table, "index": col}, color="primary"))
                    ])
                elif column_type in ['int64', 'float64']:
                    # For Integer & Float type, create slider filter
                    min_val = df[col].min()
                    max_val = df[col].max()
                    new_filter = html.Div([
                        html.Br(),
                        dcc.Dropdown(
                            id={"type": "filter_column", "index": n_clicks},
                            value=col,
                            options=[{"label": col, "value": col} for col in columns],
                            disabled=True,
                        ),
                        dcc.Input(
                                    id={"type": "filter_num_lower", "table": selected_table, "index": col},
                                    value=min_val,
                                    type="number",
                                    style={'width': '60px'}),
                                ' <= {} in [{}, {}]<= '.format(
                                    selected_columns,
                                    min_val,
                                    max_val),
                                dcc.Input(
                                    id={"type": "filter_num_upper", "table": selected_table, "index": col},
                                    value=max_val,
                                    type="number",
                                    style={'width': '60px'}
                                ),
                        dbc.Row(dbc.Button("X", id={"type": "remove_btn", "table": selected_table, "index": col}, color="primary"))
                    ])
                elif column_type == 'datetime64[ns]':
                    # For Integer & Float type, create slider filter
                    min_date = df[col].min()
                    max_date = df[col].max()
                    new_filter = html.Div([
                        html.Br(),
                        dcc.Dropdown(
                            id={"type": "filter_column", "index": n_clicks},
                            value=col,
                            options=[{"label": col, "value": col} for col in columns],
                            disabled=True,
                        ),
                        dcc.DatePickerRange(
                            id={"type": "filter_date", "table": selected_table, "index": col},
                            min_date_allowed=min_date,
                            max_date_allowed=max_date,
                            display_format='DD/MM/YYYY',
                            clearable=True,
                            start_date=min_date,
                            end_date=max_date
                        ),
                        dbc.Row(dbc.Button("X", id={"type": "remove_btn", "table": selected_table, "index": col}, color="primary"))
                    ])
                patched_children.append(new_filter)
                added_columns.append(col)  # Add the column to the list of added columns

        return patched_children

所以我认为 dbc.card 必须与回调交互,而不是 html。Div(id=filter_container)。

但是我该怎么做呢?

python 布局 回调 plotly-dash

评论


答: 暂无答案