如何在使用Pythonplotly-dash单击按钮时添加一行引用交互式变量的数据

问题描述 投票:0回答:1

我在 Dash 应用程序中有许多交互式输入和输出数据。我创建了一个按钮,如果单击它,它应该创建,然后随后将(稍后单击)一行数据添加到表中。

这是我的代码的简化版本:

app = dash.Dash(external_stylesheets=[dbc.themes.CERULEAN])

app.layout = html.Div([
    dbc.Row(dbc.InputGroup([dbc.InputGroupText("Top"), dbc.Input(id='T',placeholder="Project Name")],className="mb-3")),
    dbc.Row(dbc.InputGroup([dbc.InputGroupText("Base"), dbc.Input(id='B',placeholder="Project Name")],className="mb-3")),
    
    dbc.Row([
        html.Div([
            dbc.Button("Add current data to sensitivity table", id='add-row', style={'font-family':'arial','marginTop':'5px','marginRight':'10px'}, className="d-grid gap-2 col-8", size="sm"),
        ])
    ]),
        
    dbc.Row([
        dt.DataTable(id='sensitivity',columns=[{'name': col, 'id': col} for col in ['TR', 'BR']], data=[]),
        dcc.Store(id='button-clicks', data=0)
    ]),
])

@app.callback(
    Output('button-clicks', 'data'),
    Input('add-row', 'n_clicks'),
)

def update_button_clicks(n_clicks):
    if n_clicks is None:
        return 0
    return n_clicks

@app.callback(
    Output('sensitivity','data'),
    Input('button-clicks', 'data'),
    State(component_id='T', component_property='value'),
    State(component_id='B', component_property='value'),
)

def sensitivityTable(n_clicks,T,B):
    if n_clicks == 0:
        return dash.no_update

    new_row_data = {
        'Top':T, 
        'Base':B
    }

    if current_data is None:
        current_data = []
    current_data = dash.callback_context.outputs_list[0]['data']
        
    sensitivity_updated_data = current_data + [new_row_data]

    return sensitivity_updated_data


if __name__ == '__main__':
    app.run_server(port=8054,debug=True) 
    

预期结果是,单击按钮时,会添加从当前输入值获取的一行数据。

但是我收到属性错误:“str”对象没有属性“value”

我一直在尝试解决这个问题,但到目前为止还没有运气——任何人都能够看到我哪里出了问题。如果有更好的方法来交互式添加引用一组变量的数据,那也很好。

python jupyter plotly-dash
1个回答
0
投票

以下更改:

import pandas as pd

import dash
from dash import dcc, html
from dash import Input, Output, State, callback
from dash import dash_table as dt

import dash_bootstrap_components as dbc

app = dash.Dash(external_stylesheets=[dbc.themes.CERULEAN])

app.layout = html.Div(
    [
        dbc.Row(
            dbc.InputGroup(
                [
                    dbc.InputGroupText("Top"),
                    dbc.Input(id="T", placeholder="Project Name"),
                ],
                className="mb-3",
            )
        ),
        dbc.Row(
            dbc.InputGroup(
                [
                    dbc.InputGroupText("Base"),
                    dbc.Input(id="B", placeholder="Project Name"),
                ],
                className="mb-3",
            )
        ),
        dbc.Row(
            [
                html.Div(
                    [
                        dbc.Button(
                            "Add current data to sensitivity table",
                            id="add-row",
                            style={
                                "font-family": "arial",
                                "marginTop": "5px",
                                "marginRight": "10px",
                            },
                            className="d-grid gap-2 col-8",
                            size="sm",
                        ),
                    ]
                )
            ]
        ),
        dbc.Row(
            [
                dt.DataTable(
                    id="sensitivity",
                    columns=[
                        {"name": col, "id": col} for col in ["TR", "BR"]
                    ],
                    data=[],
                ),
                dcc.Store(id="button-clicks", data=0),
            ]
        ),
    ], style={"margin": "20%"}
)


@app.callback(
    Output("button-clicks", "data"), Input("add-row", "n_clicks"),
)
def update_button_clicks(n_clicks):
    if n_clicks is None:
        return 0
    return n_clicks


@app.callback(
    Output("sensitivity", "data"),
    Input("button-clicks", "data"),
    State("sensitivity", "data"),
    State(component_id="T", component_property="value"),
    State(component_id="B", component_property="value"),
)
def sensitivityTable(n_clicks, current_data, T, B):
    if n_clicks == 0:
        return dash.no_update

    # Adjusted the keys to match column IDs
    new_row_data = {"TR": T, "BR": B}

    if current_data is None:
        current_data = []

    sensitivity_updated_data = current_data + [new_row_data]

    return sensitivity_updated_data


if __name__ == "__main__":
    app.run_server(port=8054, debug=True)

导致此应用行为:

我必须更改的代码问题是:

  1. current_data
    (数据表中数据的当前状态)可以使用
    State
    而不是
    dash.ctx
    (这是您引用的错误的来源)输入
  2. 您需要使用数据表的列作为向表中添加新行的键 - 输入
    T
    B
    将是每个添加行中的新数据
© www.soinside.com 2019 - 2024. All rights reserved.