šŸ“£ Loading states and Loading component

Sorry about that - the correct version is uploaded now as @Marc-Andre mentioned (thanks!). The other problem mentioned above wasnā€™t actually a problem - it should all work as expected, regardless of serve_locally=true.

Iā€™m on Windows and Iā€™ve installed:

dash==0.37.0rc2
dash-core-components==0.43.0rc3
dash-html-components==0.14.0rc21
dash-renderer==0.18.0rc4

This installed plotly 3.6.1

However, when I try to run the example, I get a file not found error:

FileNotFoundError: [WinError 2] The system cannot find the file specified 'C:\\Users\\....\\lib\\site-packages\\dash_core_components\\plotly-1.44.1.min.js'

Do I still not have the correct versions installed or am I running into something else?

(Iā€™m using virtualenv to create my virtual environment.)

Nevermind. I re-read the thread and now see that I misunderstood the above post. Loading states requires dash-core-components==0.44.0rc3 .

So for anyone new to this, the required components are:

dash==0.37.0rc2
dash_html_components==0.14.0rc21
dash-core-components==0.44.0rc3

Very nice job with this! It is enhancements like this that give Dash a huge edge over some of the other vendors like Tableau, Qlik, PowerBI, etc.

2 Likes

Hi there.

Great job!

Now, how can we create new ā€œloading componentsā€ that would be render inside the dcc.Loading wrapper? I donā€™t mean just styling them with css, but display our own defined html, or eventually even react/js in case we want to. The react option is not so important for us, but the html one it is.

Hello!
I am trying to use the Loading components while a graph is updating this way:

html.Div(children=[dcc.Loading(id='loading-1',
                                           children=html.Div(dcc.Graph(id=dcc_ids['cumulative_performance']),
                                                             className='chart_div'),
                                           type='spinner')]),

With the corresponding callback being:

@dash_app.callback(
    Output('cumulative_performance', "children"),
    [Input('param1', 'value'),
     Input('param2', 'value'),
     Input('param3', 'value'),
     ])
def my_function(param1, param2, param3):

I do see the spinner and that is so great but my chart never displaysā€¦ I am probably doing something wrongā€¦

Could you assist please??

NB: I am a huge Dash fan and take the opportunity to thank you for this framework !!

Cheers

Hi!

It is pretty! Thank you!

Is there a way to use loading_state property as callback input?
Problem:
I have a custom spinner (similar to the one here. I would like to show it depending on loading_state.is_loading and the state of the background task at the same time.

Cheers

2 Likes

Loading component does not render on first load if using dcc.Location.
See https://github.com/plotly/dash-core-components/issues/488

Hi all, trying to use the loading component for the first time, but I havenā€™t quite got it working yet. my layout and callback are as follows:

dcc.Loading(
    id="loading-1",
    children=[html.Div([dcc.Graph(id='themes-plot',
                                  figure = data_plots.empty_plot())
                                ],
                                style ={'width': '84%'}
                                )],
    type="default"),


@app.callback(Output("themes-plot", "children"), [Input('submit-button', "value")])
def input_triggers_spinner(value):
    time.sleep(1)
    return value

When you click the submit-button data a callback runs to filter and process the data which is then displayed in the themes-plot graph. Initially the graph displays and empty plot until updated by the callback, which takes a few seconds.

The above appears to display everything correctly and the graph updates correctly, but no spinner appears.

Could this be related to the fact that there is already a call back outputting to the themes-plot component?

Thanks!

1 Like

Hi,

After trying again and re-writing the code it finally works for me:
The div below includes the chart and a parameter for the chart.
The other parameters are inherited from a tab component.

html.Div([
            dcc.Loading(id='loading-1',
                        children=[html.Div(dcc.Graph(id='chart_id'),
                                           className='chart_div') #custom css class
                                  ],
                        type='spinner'),
            dcc.RadioItems(
                options=[
                    {'label': 'l1', 'value': 'v1'},
                    {'label': 'l2', 'value': 'v2'},
                    {'label': 'l3', 'value': 'v3'},
                    {'label': 'l4', 'value': 'v4'},
                    {'label': 'l5', 'value': 'v5'},
                    {'label': 'l6', 'value': 'v6'},
                    {'label': 'l7', 'value': 'v7'}],
                value='v7',
                id='input3',
            ),
        ],
            className='seven columns',
            style={"padding-left": '20'}
        ),], 
           className='row', 
)

@dash_app.callback(
Output('chart_id', "figure"),
[Input('input1', 'value'),
 Input('input2', 'value'),
 Input('input3', 'value'),
 ])
 def func(input1, input2, input3):

Hope this will help you,

Cheers

2 Likes

Hi,

Really like the feature! Awesome stuff. I was wondering if you could help me with an issue Iā€™m having.

Iā€™m currently working on a multi-page app. Hereā€™s an example of the index page:

index.py

html.Div(
            [
                dcc.Location(id='url', refresh=False),
                html.Div(id="navigation_bar"),
                dcc.Dropdown(id = "options"), # users pick options which edit the query
                dcc.Loading(id="loading",children=[html.Div(id='page-content')])
            ]
        )

@app.callback(
    Output('page-content', 'children'),
    [Input('url', 'pathname')]
def update_page(pathname):
     if pathname == "dashboard":
            return dashboard_layout
     else:
            display another layout

The page-content div sets a new layout every time the url changes. Each layout has its own dropdowns, graphs, tabs, etc which are populated by data from a SQL query. The query is based on the option a user picks in the options dropdown. The data from the query is then stored in a flask-cache on Redis so that all the pages can access it.

When the layout first loads, it takes a long time because the query is expensive. Subsequent steps are very quick because the queried data comes from a cache.

My issue right now is that the spinner appears for inexpensive processes (like changing a tab or clicking a dropdown) after the first data load. I would prefer if the spinner displayed only on the first time the query is run as stored in the cache.

Is there a way for me to set a ā€œspinner on first loadā€ option? Or do you see a better way for me to do this?

Please let me know.
Thanks!

2 Likes

Hi @mdylan2

you could use the decorator @app.first_callback that is alread available above your expensive first callbacks.

Cheers,

1 Like

Hi @PNhd

Iā€™m a little unsure what you mean by @app.first_callback. Is that a Dash function?

1 Like

@PNhd @mdylan2
Im facing the same issueā€¦ I want the load component only to be triggered by one input, and not whenever a change is being made on the page.

The thing is in the documentation (https://dash.plot.ly/dash-core-components/loading_component), load 1 is triggered by input one, and not both inputsā€¦ thats what id expectā€¦

The question is, is it meant to be triggered whenever a change is made or is this some sort of bug?

1 Like

@mdylan2 so my work around was:
instead of having the my output div as a child for the load button, I put it independently in the app.layout, and in the callback, I had multiple outputs: namely the load button and the intended output div.

Hope that helps!

4 Likes

Oh I see, so you define the loading component div and output div separately and update them simultaneously in a multi-output callback.

Thatā€™s a smart workaround! Thanks!

1 Like

I am having the same question. Anybody has any answers for it? Thanks.

Is there any way currently to get the Loading animation to display only after a few seconds? I have a callback that sometimes takes 3+ seconds to load, so this new component could be quite useful in those cases, but most of the time the callback only takes an invisible millisecond to load.

With dcc.Loading now, those millisecond updates now become visible as dcc.Loading seems to load its animation at any slightest delay which it detects.

1 Like

Finally, I placed

dcc.Loading(loading_state={'is_loading':True})]

so it ā€˜is loadingā€™ permanently. I toggle the visibility of the whole div in a callback.

I hope it helps.

2 Likes

Is it possible to get the actual State of the component to see if its loading as part of a callback?

Something along the lines of:
State('input-1', 'data-dash-is-loading')]

3 Likes

Iā€™m still working on the details and donā€™t have a fully working example yet, but with the CSS approach it looks like CSS transitions will help. Something like this:

#root {
    visibility: visible;
    transition-property: visibility;
    transition-delay: 0s;
}

#root[data-dash-is-loading="true"] {
    visibility: hidden;
    transition-delay: 5s;
}

will hide element #root if itā€™s been loading for more than 5 seconds.

Maybe someone who knows more about JS and CSS than me (which is any web developer) would be able to turn that into a full example.

2 Likes