Is it possible to load multiple callback outputs sequentially versus all at once?

I have a callback where I use a single pulldown menu selection input to update several graphs on one page using multiple outputs. This works, but takes a long time to run. Is there a way to have these graphs load sequentially? I don’t think it’s possible to tie a single input to multiple callbacks. I thought that would work but it doesn’t. So I need a way to get these graphs to load sequentially instead of all at once. Any ideas? Thanks.

# Callback for events data
@app.callback(
    [Output('events-shots', 'figure'), Output('events-assists', 'figure'), Output('events-progressive-passes', 'figure'),
     Output('events-crosses', 'figure'), Output('events-set-plays', 'figure'), Output('events-reception-box', 'figure')],
    [Input('team-dropdown', 'value')])
def event_graph(team):
    if team is not None:
        fig_shots = plotEvents('Shots', 'team', team, '127.0.0.1')
        fig_assists = plotEvents('Assists to Shots', 'team', team, '127.0.0.1')
        fig_crosses = plotEvents('Crosses', 'team', team, '127.0.0.1')
        fig_set_plays = plotEvents('Set Plays', 'team', team, '127.0.0.1')
        fig_progressive_passes = plotEvents('Progressive Passes Into Final 3rd', 'team', team, '127.0.0.1')
        fig_reception_box = plotEvents('Reception in the Box', 'team', team, '127.0.0.1')
        for x in [fig_shots, fig_assists,fig_crosses, fig_set_plays, fig_progressive_passes, fig_reception_box]:
            # Change modebar drawing item colour so that it stands out (vs. grey)
            x.update_layout(newshape=dict(line_color='#009BFF'))
        return fig_shots, fig_assists, fig_crosses, fig_set_plays, fig_progressive_passes, fig_reception_box

    else:
        fig = initial_figure_events()
        return fig, fig, fig, fig, fig, fig

Hi @doogra,

I’m not sure, but perhaps using dcc.Graph property loading_state you can concatenate different callbacks that trigger each other.

  1. ‘(team-dropdown’, ‘value)’ just trigger the first graph.

  2. (‘first graph’, ‘loading_state)’ as input in the second callback will check the first graph:

  • Prevent first callback
  • if loading_state != ‘is_loading’ then trigger the second graph
  1. the same for the rest of the graphics.

It is possible to use an input for multiple callbacks, but you can only target an output once. I guess you should be able to achieve what you want simply by chaining the callbacks, i.e. something like

# The first graph is triggered by the team-dropdown.
@app.callback(Output('events-shots', 'figure'), [Input('team-dropdown', 'value')])
def event_graph_shots(team):
    if team is None:
        return initial_fig_shots()
    fig_shots = plotEvents('Shots', 'team', team, '127.0.0.1')
    fig_shots.update_layout(newshape=dict(line_color='#009BFF'))
    return fig_shots

# The next graph is triggered by the previous graph.
@app.callback(Output('events-assists', 'figure'), [Input('events-shots', 'figure')], [State('team-dropdown', 'value')])
def event_graph_assists(_, team):
    if team is None:
        return initial_fig_assists()
    fig_assists = plotEvents('Assists to Shots', 'team', team, '127.0.0.1')
    fig_assists.update_layout(newshape=dict(line_color='#009BFF'))
    return fig_assists

# and so on the for remaining graphs

Depending on the size of the figures, this approach might not be sufficiently performant. If the figures are large, you might be better off using a separate component (e.g. a Store) to trigger the updates.

Thanks so much! Worked like a charm. And the user experience is a lot better than waiting for all of the graphs to load, which was taking about 12 seconds (not awful but not ideal). Now at least something shows up initially while the other graphs load below where the user can’t yet see them doing so.