Thank you @jgomes_eu
I know about dcc.Loading
component, but I think that unfortunately, it won’t solve my case.
Let’s say I have dashboard layout e.g.
class Chart1:
def __init__(self):
self.data = self._get_data()
def _get_data(self):
"some SQL query"
return pd.read_sql(.....)
def figure(self):
return px.bar(self.data)
class Chart2:
def __init__(self):
self.data = self._get_data()
def _get_data(self):
"some SQL query"
return pd.read_sql(.....)
def figure(self):
return px.pie(self.data)
class Chart3:
def __init__(self):
self.data = self._get_data()
def _get_data(self):
"some SQL query"
return pd.read_sql(.....)
def figure(self):
return px.line(self.data)
app = dash.Dash()
def get_layout():
return html.Div([
html.Div(id='title'),
dcc.Dropdown(['DE', 'PL', 'US'], 'US', id='country-dropdown'),
html.Div(dcc.Graph(id='chart1'),
html.Div(dcc.Graph(id='chart2'),
html.Div(dcc.Graph(id='chart3'),
html.Div(dcc.Graph(id='chart4')
]
@app.callback(
Output('page-content', 'children'),
Input('url', 'pathname'))
def display(pathname):
if pathname == 'test':
return get_layout()
@app.callback(Output('chart1', 'figure'),
Input('country-dropdown', 'value')):
def render_chart_1(country):
chart = Chart1()
chart.data = data[data['country'] == country]
return chart.figure()
@app.callback(Output('chart2', 'figure'),
Input('country-dropdown', 'value')):
def render_chart_2(country):
chart = Chart2()
chart.data = data[data['country'] == country]
return chart.figure()
@app.callback(Output('chart3', 'figure'),
Input('country-dropdown', 'value')):
def render_chart_3(country):
chart = Chart3()
chart.data = data[data['country'] == country]
return chart.figure()
@app.callback(Output('chart4', 'figure'),
Input('chart4', 'id')):
def render_chart_1(id):
chart = Chart4()
return chart.figure()
Here is some very very basic example. So as you see I have a lot of Chart objects, which every single one
has its own logic of fetching data from the database and how the figure object should look like.
I want at the stage when the application is starting to render only the dashboard layout:
@app.callback(
Output('page-content', 'children'),
Input('url', 'pathname'))
def display(pathname):
if pathname == 'test':
return get_layout()
So use will see after 1-second dashboard layout with empty chart containers (dcc.Graph)
and after that, I want that every single chart will be instantiated in a separate thread.
So for example for the first chart it will take 3 seconds to get data from DB and render it so after 3 seconds empty container dcc.Graph(‘chart1’) will re-render with proper figure (with data)
for chart 2 it will take 1 second, and the same story for others.
So in the end I don’t want user to wait till every single chart will be ready to show (data will be fetched from database),
and only after that he will see the dashboard (even if there will be a loading spinner). But I want that he will see dashboard without charts, and whenever the given chart will be ready it will show up on the dashboard.
I was looking on long_callbacks, but I would say that multiprocessing is not a need for that.
Probably there should be some way to separate dashboard initialization without figures from figures initialization.
From what I understand, the only way to do that is that every single chart needs to have seperate callback (so then it will spawn separate thread)
I hope that I explained it better now.