I have seen this example of Progress
& Interval
components for displaying the progress in Dash:
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
progress = html.Div(
[
dcc.Interval(id="progress-interval", n_intervals=0, interval=500),
dbc.Progress(id="progress"),
]
)
@app.callback(
[Output("progress", "value"), Output("progress", "children")],
[Input("progress-interval", "n_intervals")],
)
def update_progress(n):
# check progress of some background process, in this example we'll just
# use n_intervals constrained to be in 0-100
progress = min(n % 110, 100)
# only add text after 5% progress to ensure text isn't squashed too much
return progress, f"{progress} %" if progress >= 5 else ""
However, I cannot find any example that would actually show how to properly link the progress bar to some background process.
If, for example, I have a callback with a regular for
loop, how can I show the progress of this for
loop (i.e. if I'm on 10th element from 100, I want it to be displayed as 10% in the progress bar)?
You can nest Progress components to make a progress bar with multiple bars. Make sure you set bar=True on each of the children. Set striped=True for a striped progress bar.
Set striped=True for a striped progress bar. If you have set striped=True, you can also set animated=True to get animated stripes. Typically to use Progress effectively, you will want to use a dcc.Interval component to periodically monitor some background process and update the progress accordingly.
To add a text label to the progress bar, use the label prop. Set the height of the progress bar using the style argument. Use the color argument along with one of Bootstrap's contextual color names to set the background color of the progress bar. You can nest Progress components to make a progress bar with multiple bars.
Add Bootstrap style progress bars to your app with the Progress component, featuring support for stacked bars, animated backgrounds, and text labels. Use the value argument of Progress to set progress.
@Valeria, I created a tutorial on the progress bar and the spinner, which focuses on the formatting of the loaders. https://youtu.be/t1bKNj021do
But for the linking of the progress bar with a background process, this person was nice enough to create a sample app and code. https://github.com/tcbegley/dash-rq-demo
I was able to use a for-loop to update the progress bar.
But i had to:
dcc.Interval
for when the dashboard should look for a new value.Insted of using a global progress_memory
and Queue
, this could probably be grouped nicely using classes.
import dash
import time
import threading
import dash_bootstrap_components as dbc
from queue import Queue
progress_queue = Queue(1)
progress_memeory = 0
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = dash.html.Div(children=[
dash.html.H1(children='Test Progress Bar Using Loop'),
dash.dcc.Interval(id='clock', interval=1000, n_intervals=0, max_intervals=-1),
dbc.Progress(value=0, id="progress_bar"),
dash.html.Button("Start Work", id='start_work', n_clicks=0)
])
@app.callback(
[dash.Output("progress_bar", "value")],
[dash.Input("clock", "n_intervals")])
def progress_bar_update(n):
global progress_memeory
if not progress_queue.empty():
progress_bar_val = progress_queue.get()
progress_memeory = progress_bar_val
else:
progress_bar_val = progress_memeory
return(progress_bar_val,)
@app.callback([
dash.Output("start_work", "n_clicks")],
[dash.Input("start_work", "n_clicks")])
def start_bar(n):
if n==0:
return(0,)
threading.Thread(target=start_work, args=(progress_queue,)).start()
return(0,)
def start_work(output_queue):
for i in range(101):
time.sleep(0.5)
if output_queue.empty():
output_queue.put(i)
return(None)
if __name__ == '__main__':
app.run_server(debug=True, use_reloader=False)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With