1

为了避免在没有可绘制的信息时显示空的图形轴,我用 a 替换了一个dcc.Graph返回对象,它得到了一个或html.Div()的输出回调。[][dcc.Graph(...)]

现在,我想对 selectedData 启用其他操作(如果 Div 有子图)。以前我可以这样做:

@app.callback(Output('something', 'children'), 
              [Input('graph', 'selectedData')])
def do_stuff(selectedData):
    pass

现在我已经将布局项从 a 更改dcc.Graph(...)为 a html.Div([dcc.Graph(...)]),我不知道如何访问selectedData

@app.callback(Output('something', 'children'), 
              [Input('graph_div', 'children')])
def do_stuff(children):
    if len(children) > 0:
        graph = children[0]
    # wheres the selectedData now?

或者,如果有办法将 Inputid直接获取到嵌套dcc.Graphid? 当我尝试此操作时,我收到一条错误消息,指出应用程序的布局中不存在具有此 ID 的组件。

4

2 回答 2

2

对于每个组件,应该可以在 Dash 中注册一个回调,

这是一个简单的示例,它复制了您正在尝试做的事情,

import dash
import dash_core_components as dcc
from dash.dependencies import Input, Output

app = dash.Dash(__name__)

app.layout = html.Div([
    html.Div(id="graph-div",
        children=[
            dcc.Graph(
                id='graph',
                figure={
                    'data': [
                        {
                            'x': [1, 2, 3, 4],
                            'y': [4, 1, 3, 5],
                            'text': ['a', 'b', 'c', 'd'],
                            'customdata': ['c.a', 'c.b', 'c.c', 'c.d'],
                            'name': 'Trace 1',
                            'mode': 'markers',
                            'marker': {'size': 12}
                        },
                        {
                            'x': [1, 2, 3, 4],
                            'y': [9, 4, 1, 4],
                            'text': ['w', 'x', 'y', 'z'],
                            'customdata': ['c.w', 'c.x', 'c.y', 'c.z'],
                            'name': 'Trace 2',
                            'mode': 'markers',
                            'marker': {'size': 12}
                        }
                    ],
                    'layout': {
                        'clickmode': 'event+select'
                    }
                }
            ),
        ]
    ),
    html.Div(id="output")
])

@app.callback(Output('output', 'children'), 
              [Input('graph', 'selectedData')])
def do_stuff(selectedData):
    print(selectedData)

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

如果您可以发布一个简单的可重新创建的代码,它将更容易调试。

更新:

如果您正在动态尝试加载组件,您可能会遇到上述问题,

https://community.plot.ly/t/dcc-tabs-filling-tabs-with-dynamic-content-how-to-organize-the-callbacks/6377/2

解决此问题的一种简单方法是设置此应用程序配置, app.config['suppress_callback_exceptions']=True

这是工作示例,

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd


#
#https://stackoverflow.com/questions/57580240/access-selecteddata-from-html-div-children
#


graph_layout = dcc.Graph(
                id='graph',
                figure={
                    'data': [
                        {
                            'x': [1, 2, 3, 4],
                            'y': [4, 1, 3, 5],
                            'text': ['a', 'b', 'c', 'd'],
                            'customdata': ['c.a', 'c.b', 'c.c', 'c.d'],
                            'name': 'Trace 1',
                            'mode': 'markers',
                            'marker': {'size': 12}
                        },
                        {
                            'x': [1, 2, 3, 4],
                            'y': [9, 4, 1, 4],
                            'text': ['w', 'x', 'y', 'z'],
                            'customdata': ['c.w', 'c.x', 'c.y', 'c.z'],
                            'name': 'Trace 2',
                            'mode': 'markers',
                            'marker': {'size': 12}
                        }
                    ],
                    'layout': {
                        'clickmode': 'event+select'
                    }
                }
            )
app = dash.Dash(__name__)

app.config['suppress_callback_exceptions']=True 

app.layout = html.Div([
    dcc.Dropdown(id="toggle-graph",
        options=[
            {'label': 'on', 'value': 'on'},
            {'label': 'off', 'value': 'off'},
        ],
        value='on'
    ) , 
    html.Div(id="graph-div",
        children=[

        ]
    ),
    html.Div(id="output")
])


@app.callback(Output('graph-div', 'children'), 
              [Input('toggle-graph', 'value')])
def do_stuff(value):
    if(value == 'on'):
        return graph_layout
    else:
        return []


@app.callback(Output('output', 'children'), 
              [Input('graph', 'selectedData')])
def do_stuff(selectedData):
    print(selectedData)

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

于 2019-08-21T15:17:12.357 回答
1

看起来我需要的是一种切换图形显示的方法,而不是有条件地返回整个图形对象:

@app.callback(Output('graph', 'style'), [Input('drop-down', 'value')])
def toggle_container(dropdown_value):
    if something
        return {'display': 'none'}
    else:
        return {'display': 'block'}
于 2019-08-21T15:32:44.360 回答