Closed aditya00j closed 5 years ago
Hi @aditya00j, really glad you're enjoying dash-bootstrap-components
At the moment it is a bit hard to use the Spinner
. I would recommend you look at the Loading
component in dash-core-components, see the docs here. We are planning to provide our own version of this that uses Bootstrap spinners.
You can do something manually with our Spinner
component, but it is harder because you have to implement things asynchronously. As a starting point I would suggest looking at this example.
More generally using some kind of task queue like Celery or Redis Queue to run tasks in the background would let you add spinners to the layout while tasks are running. That's quite a lot of overhead for just adding a spinner though, so I would recommend using the Loading component for now, and we'll work on making it Bootstrap specific like I mentioned.
Hi, Thanks for your reply! The Loading component was my backup, I just wanted to use the bootstrap components as much as possible. A similar functionality with spinner would be a very useful feature to add!
Hi, @tcbegley , any news on this regard?
Edit: For example, I would like an "apply" button that gets an spinner inside of it while the calculations are not done.
Hi @GitHunter0,
What you're describing can be achieved with a couple of dcc.Store
components and some careful callback definitions, see the example below.
This is only really suitable if the computation takes a few seconds. For anything that takes longer I would recommend you look into running that computation asynchronously in the backend. This can be achieved manually (see for example this example) or these days you can make use of background callbacks.
Anyway, here's the simple example. When the button is clicked, we log an id in the start store and disable the button. The start store triggers the computation. The computation callback updates the value of the button text which means the spinner will spin while the callback is running. It also updates the complete store which reenables the button.
import time
from uuid import uuid4
import dash_bootstrap_components as dbc
import numpy as np
import plotly.graph_objs as go
from dash import Dash, Input, Output, State, dcc, html
from dash.exceptions import PreventUpdate
app = Dash(external_stylesheets=[dbc.themes.BOOTSTRAP], prevent_initial_callbacks='initial_duplicate')
app.layout = dbc.Container(
[
dcc.Store(id="start", data=""),
dcc.Store(id="complete", data=""),
dbc.Button(dbc.Spinner(html.Span("Compute", id="button-label")), id="button"),
dcc.Graph(id="graph"),
],
className="p-5",
)
@app.callback(
Output("button", "disabled", allow_duplicate=True),
Output("start", "data"),
Input("button", "n_clicks"),
)
def register_start(n):
if n:
return True, str(uuid4())
raise PreventUpdate
@app.callback(Output("button", "disabled", allow_duplicate=True), Input("complete", "data"), State("start", "data"))
def enable_button(complete_value, start_value):
return complete_value != start_value
@app.callback(
Output("graph", "figure"),
Output("button-label", "children"),
Output("complete", "data"),
Input("start", "data")
)
def make_graph(data):
# fake slow computation
time.sleep(2)
x = np.random.random(10)
y = np.random.random(10)
return go.Figure(data=go.Scatter(x=x, y=y, mode="markers")), "Compute", data
if __name__ == "__main__":
app.run_server(debug=True)
Hey @tcbegley , thanks a lot for the detailed feedback.
Hi, Sorry for using GitHub issues to ask a newbie question, but I couldn't find another contact info to get in touch. First of all thanks to all the developers for dbc, they have been immensely useful for me to provide a consistent user experience for our Dash apps.
I am a novice in HTML/CSS/Javascript programming, so I tend to focus on finding pythonic ways to implement all the functionality in my Dash apps. This might be the reason I am not able to figure out how to use the Spinner component. Can somebody give me a simple example of how to replace a specific dbc component by a spinner while the component is loading or performing an action? Here is my toy code:
If instead of replacing the button, it's easier to show the spinner somewhere else (on its side for example), that would be fine for me as well. I just need to give the user a visual indication that the function is computing.
Sorry again for putting this in an issue, I know that's not what the issues are for :) Cheers!