How to add/create a custom loader with Dash plotly?

Question:

I want to pass my gif to the loader component instead of using the default figures. Does anybody know how to do that?

This is my code :

dcc.Loading(
    id="loading-1",
    type="default",
    children=html.Div(id="loading-output-1"),
)

and I am trying to accomplish something like this :

dcc.Loading(
    id="loading-1",
    type="assets/dashboard_loader.gif",
    children=html.Div(id="loading-output-1"),
)

Can somebody please guide me ?

Asked By: JohnnySilverhand

||

Answers:

The type property specifies what the spinner looks like, but is limited to a set of values dash core components provides:

type (a value equal to: ‘graph’, ‘cube’, ‘circle’, ‘dot’, ‘default’; default ‘default’): Property that determines which spinner to show one of ‘graph’, ‘cube’, ‘circle’, ‘dot’, or ‘default’.

So your approach is currently not possible, but there is a workaround.

The html structure of the default spinner looks something like this:

<div class="dash-spinner dash-default-spinner">
  <div class="dash-default-spinner-rect1"></div>
  <div class="dash-default-spinner-rect2"></div>
  <div class="dash-default-spinner-rect3"></div>
  <div class="dash-default-spinner-rect4"></div>
  <div class="dash-default-spinner-rect5"></div>
</div>

Each of these rectangle divs inside .dash-spinner are used for the default type animation. We don’t care about these rectangles or anything that’s inside of .dash-spinner, because we only want the gif animation.

So what we could do here is to hide all .dash-spinner children and add an animated background to .dash-spinner.

We can do so with css

.dash-spinner {
  background-image: url("http://i.stack.imgur.com/SBv4T.gif");
  background-size: contain;
  background-repeat: no-repeat;
}

.dash-spinner * {
  display: none !important;
}

For including css see the documentation here.

Minimal and reproducible example based on the example given in the documentation here:

from dash import Dash
import time
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output


app = Dash(__name__)
app.layout = html.Div(
    children=[
        html.H3("Edit text input to see loading state"),
        dcc.Input(id="loading-input-1", value="Input triggers local spinner"),
        dcc.Loading(
            id="loading-1", type="default", children=html.Div(id="loading-output-1")
        ),
    ],
)


@app.callback(
    Output("loading-output-1", "children"),
    Input("loading-input-1", "value"),
    prevent_initial_call=True,
)
def input_triggers_spinner(value):
    time.sleep(2)
    return value


if __name__ == "__main__":
    app.run_server()

Gif was taken from this related answer here.

Answered By: Bas van der Linden

You can also create a new class in the css instead of overriding. That way, you can also specify the size of the gif.
css:

.gif-loading {
  margin: 1rem auto;
  width: 1280px;
  height: 720px;
  text-align: center;
  font-size: 10px;
  background-image: url("loading.gif");
  background-size: contain;
  background-repeat: no-repeat;
}

and then refer to it in the main file

dcc.Loading(
            id="loading-1", type="default", className='gif-loading', children=html.Div(id="loading-output-1")
        ),