首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Dash回调阻止其他回调

Dash回调阻止其他回调
EN

Stack Overflow用户
提问于 2021-08-17 16:04:15
回答 2查看 3.3K关注 0票数 1

我对Dash相对来说是个新手,我觉得我对回调理解得很好。但是,我现在的情况是,似乎需要在一个回调中调用所有回调,因为当调用该回调时,我的程序工作正常。

当我有多个回调时,它们各自都能很好地工作;这意味着如果我注释掉一个回调,回调就会按需要工作。我能够使用context.triggered获得正确的功能,但我不想在一个大规模回调中得到所有的东西,我觉得这是我理解的一个问题。我尝试过限制回调的一个输入,但这仍然不起作用。我是否将整个应用程序布局传递给回调?

如果是,如何限制在I之外传递的内容?怎么回事?

以下是一个经过调整的工作实例:

代码语言:javascript
复制
import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import dash_table
from dash.dependencies import Input, Output, State
import plotly.express as px
from dash import callback_context, no_update
import webbrowser
from flask import request
chrome_path = 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s'
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/Mining-BTC-180.csv").drop('Unnamed: 0',axis=1)
selected_cols = ['Number-transactions', 'Output-volume(BTC)',
       'Market-price', 'Hash-rate', 'Cost-per-trans-USD', 'Mining-revenue-USD',
       'Transaction-fees-BTC']

class Parameter_Viewer():
    def __init__(self, df, **kwargs):

        revenue_plot = px.scatter(df, x="Date", y="Mining-revenue-USD",title='Mining-revenue-USD')
        Hash_plot = px.scatter(df, x="Date", y="Hash-rate",title='Hash-rate')
        parameter_table = dash_table.DataTable(
            id='db-table',
            columns=[{"name": i, "id": i} for i in selected_cols],
            data=df.to_dict('records'),
            #page_action="native",
            page_action='none',
            style_table={'height': '300px', 'overflowY': 'auto'},
            editable=True
        )
        app = dash.Dash()
        app.layout = html.Div(
            children=[
                #first row
                html.Div(
                    children=[
                        html.Div(children=[
                        html.H1("Parameter", className="menu-title"),
                        dcc.Dropdown(
                            id="parameter-filter",
                            options=[
                                {"label": parameter, "value": parameter} for parameter in df.columns
                            ],
                            value="Mining-revenue-USD",
                            clearable=False,
                            className="dropdown",
                        ),]),
                        html.Div(children=[
                        html.H1("Data Type", className="menu-title"),
                        dcc.Dropdown(
                            id="data-selector",
                            options=[
                                {"label": data_col, "value": data_col} for data_col in selected_cols
                            ],
                            value="Hash-rate",
                            clearable=False,
                            className="dropdown",
                        ),]),
                        html.Button("Close Viewer", id="Close_Btn")
                    ]
                ),
        html.Div(children=[
                html.H1(children="Database Analytics",),
                parameter_table]),
        html.Div(children=[
                html.Div(
                dcc.Graph(id='param-plot',figure=revenue_plot),
                style={"width":'50%', "margin": 0, 'display': 'inline-block'},className="six columns"),
                html.Div(
                dcc.Graph(id='param-plot2',figure=Hash_plot),
                style={"width":'50%', "margin": 0, 'display': 'inline-block'},className="six columns")],className="row")
        ])
        @app.callback(
            [Output("db-table", "data"), Output("param-plot", "figure"), Output("param-plot2", "figure")],
            [Input("parameter-filter", "value"),Input("data-selector", "value"),Input('db-table', 'data')])#,prevent_initial_call=True)
        def update_charts(parameter,data_type,table_data):
            changed_inputs = [x["prop_id"]for x in callback_context.triggered]
            if changed_inputs[0] == 'parameter-filter.value':
                df = pd.DataFrame.from_dict(table_data)
                ua_plot = px.scatter(df, x="Date", y=data_type)
                aa_plot = px.scatter(df, x="Date", y=parameter)
                return table_data, ua_plot, aa_plot
            elif changed_inputs[0] == 'db-table.data':
                df = pd.DataFrame.from_dict(table_data)
                ua_plot = px.scatter(df, x="Date", y=data_type)
                aa_plot = px.scatter(df, x="Date", y=parameter)
                return no_update, ua_plot, aa_plot
            else:
                return no_update,no_update,no_update
        @app.callback(Output("db-table", "data"),Input("Close_Btn", "n_clicks"),prevent_initial_call=True)
        def close_browser(n_clicks):
            print('In close callback\n')
            if n_clicks>0:
                self.shutdown()
            return no_update

        host='127.0.0.1'
        port='8050'
        url = 'http://{}:{}/'.format(host,port)
        webbrowser.get(chrome_path).open(url)
        app.run_server(debug=False)
    def shutdown(self):
            func = request.environ.get('werkzeug.server.shutdown')
            if func is None:
                raise RuntimeError('Not running with the Werkzeug Server')
            func()


Parameter_Viewer(df)```
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-08-23 09:27:58

更容易考虑回调的基本情况,然后再对它们进行扩展。根据我的经验,我通常构造回调的主要原因是处理由特定输入引起的特定输出。

例如。

如果输出O1是输入I1的效果,那么我将进行回调C1(I1→O1)。

如果输出O1是输入I1和I2的影响,则进行回调C1(I1,I2→O1)。

如果您碰巧有多个输出是一个输入的影响,那么您可以将这些输出组合在同一个回调中。

例如。

如果输出O1是输入I1的影响,而输出O2是输入I1的效果,那么就进行回调C1(I1→O1,O2)。

另外,请记住,Dash不允许多个回调具有相同的输出组件(例如,特定组件属性可以与一个且只有一个回调相关联)。在这种情况下,如果您的特定输出需要与另一个输出同时更新,但不一定是同一输入的影响,那么您仍然应该将输出合并到单个回调中。

例如。

如果输出O1是输入I1的影响,而输出O2必须用O1更新,那么我将创建一个回调C1(I1→O1,O2)。

我不知道为什么在注释中尝试使用State()而不是but (),因为State()在仍然必须被读取为输入的情况下使用State(),但不一定需要触发。

所以使用上面的逻辑,例如,

如果输出O1是输入I1的效果,而不是输入(我们现在称为状态) S1的效果,但仍然需要S1,那么我将进行回调C1(I1,S1→O1)。

通常情况下,有大量的回调具有许多输入和输出,只要回调不试图一次做太多不连贯的事情(否则,当您回过头来查看代码时,您将花费大量时间来记住您相信我的话:)。

票数 2
EN

Stack Overflow用户

发布于 2021-12-03 10:45:53

如果你像我一样是个初学者。你可能在寻找最有价值的信息,就我而言,在Daniel 的回答中:

Dash不允许多个回调具有相同的输出组件

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68820651

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档