On user input, my app does the following:
- logs into server
- gets Data
- generates a Tabs component with a Tab for each value of a list of values from the Data
Now, I want to execute the next step for each Tab and update tab-specific set of figures:
- populate each Tab with a set of Figures which are tab-specific and are generated from the Data
What is the proper way of doing this? Should this be done with another chained Callback, or a normal function and how should the Data be passed between functions given that its generation is computationally expensive?
PS: Dynamic callback generation for each tab may not be good as it is suggested here, since I would need to pass large quantity of data to each generated callback.
The current code looks like:
app = dash.Dash()
def generate_tabs(available_segments):
tabs_html = []
for segment in available_segments:
tabs_html.append(dcc.Tab(id = segment, label=segment, children=[
html.Div([
dcc.Graph(className='plot1-{}'.format(segment)),
dcc.Graph(className='plot2-{}'.format(segment))
],className='grid-container')
]))
return tabs_html
app.layout = html.Div([
html.Div([
dcc.Input(id='username-input', type='text', placeholder='Username'),
dcc.Input(id='password-input', type='password', placeholder='Password'),
html.Button('Login', id='login-button')
],id='menu-panel'),
dcc.Tabs(id="tabs")
])
# 1. Login, get data and generate layout
@app.callback(
[dash.dependencies.Output('tabs', 'children')],
[dash.dependencies.Input('login-button', 'n_clicks')],
[dash.dependencies.State('username-input', 'value'),
dash.dependencies.State('password-input', 'value')],
)
def main_callback(button_clicks, uname, passw):
[segments, data] = login_and_get_data(uname,passw)
figures = generate_figures(segments,data)
return generate_tabs(segments)
# 2. Populate layout - For each segment: Output to plot{i}-segment using the generated figures
@app.callback(
[dash.dependencies.Output('plot1-{}'.format(segment), 'figure'),
dash.dependencies.Output('plot2-{}'.format(segment), 'figure')],
[dash.dependencies.Input("""execute when called by the main_callback""")],
[dash.dependencies.State("""figures and segments - from main_callback""")]
)
def populate_figures(button_clicks, uname, passw):
# For each segment output respective figures to respective ids
if __name__ == '__main__': app.run_server(debug=True)