Hi,
Imagine a dash web page with three numeric inputs with id=‘x’, ‘y’, and ‘z’. When the user changes the numeric value in any of them, a div with id=‘result’ should be updated with the result of some heavy calculation that depends on those three values. This is easily achieved by a method decorated with x, y, and z as input and result as output. So far everything is good. But now, imagine that we want a drop down menu where the user can load some hard coded values for x, y, and z. That can be done by a method which takes the drop down menu as input and x, y, and z as output.
Now to the problem: when the user selects one of the alternatives in the drop down menu, then the heavy calculation method will be fired three times instead of just once. How do you solve this? One solution would of course be to have a “start calculation” button so that the user would have to press it after changing one of the inputs. But I would like the heavy calculation to fire off as soon as user changes one value. I have thought about solutions involving hidden divs and global variables, but I can still not get it to work. Am I missing something?
In my actual real problem, the “heavy” calculation method takes around one second to run, but I have many more than 3 inputs, and it therefore takes a long time when user uses the dropdown compared to when user updates one of the inputs.
Below is a small example.
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import os
app = dash.Dash(__name__)
app.layout = html.Div(
children=[dcc.Input(id='x',
type="number",
value=0),
dcc.Input(id='y',
type="number",
value=0),
dcc.Input(id='z',
type="number",
value=0),
dcc.Dropdown(id='dropdown',
options=[{'label': f'Alt {i}',
'value': i} for i in range(2)],
value=0,
multi=False,
clearable=False
),
html.Div(id='result',
children='')
]
)
# CALLBACKS
@app.callback(
[Output(component_id='x',
component_property='value'),
Output(component_id='y',
component_property='value'),
Output(component_id='z',
component_property='value')],
[Input(component_id='dropdown',
component_property='value')])
def load_hard_coded_values(alt_index):
# Set x, y, and z to hard coded predefined values
if alt_index == 0:
return 1, 2, 3
else:
return 3, 2, 1
@app.callback(
Output(component_id='result',
component_property='children'),
[Input(component_id='x',
component_property='value'),
Input(component_id='y',
component_property='value'),
Input(component_id='z',
component_property='value')])
def update_calculation_output(x, y, z):
print(f'Performing lengthy calculation with ({x}, {y}, {z})....')
return x*y*z
if __name__ == '__main__':
app.run_server(debug=True, host=os.environ['COMPUTERNAME'], port=8050)