I am trying to build an interactive dashboard in the model of this financial report (Github here). The key difference is that instead of being built off static dataframes this report will let the user input ~30 different dcc.Input’s and dcc.Slider’s. I am building a new page for those inputs and calculating the key metrics (~10) there by calling another calculation.py file, storing the key metrics with dcc.Store, and then using the other pages to display the key metrics.
The key problems are:
(1) It seems that retrieving dcc.Store values requires a callback function for each unique retrieval – but given the number of times I’m retrieving stored values for infographics and metrics for several pages, it will become very messy.
(2) This particular app.py only returns the create_layout function for each unique page when clicked. But given the number of callback functions I’m adding it’s not running the interactive functionalities I need. How can I run the entire page – with all its functions – and not just the create_layout function?
Does the type of app I am trying to build require a single-page layout or is there an easier workaround? Thanks!
Hi @literallyunironic
Have you tried using a dict and storing all ~30 inputs in one dcc.Store?
I’m not sure I understand the issue in #2. Can you create a minimal example that shows the problem?
@AnnMarieW , thanks for your response.
- The dcc.Store would actually be more for the outputs of the function in calculation.py, of which there are about 10, and not for the 30 inputs which be kept on the inputs.py. These values will of course change as the sliders/input values change. Since I want to refer to these output values on multi-page pages on the report, at multiple locations on the layout for certain pages, do I need a callback function for every single time I want to display an dcc.Store value in an html/Plotly object? Or is just one use of it good enough – for all the times each value is used in the layout?
(2)
This is in app.py:
Update page
@app.callback(Output(“page-content”, “children”), [Input(“url”, “pathname”)])
def display_page(pathname):
if pathname == “/dash-financial-report/results-overview”:
return resultsOverview.create_layout(app)
if pathname ==‘dash-financial-report/inputs’:
return inputs.create_layout(app)
elif pathname == “/dash-financial-report/cash-flows”:
return cashFlows.create_layout(app)
elif pathname == “/dash-financial-report/fees”:
return feesMins.create_layout(app)
elif pathname == “/dash-financial-report/distributions”:
return distributions.create_layout(app)
elif pathname == “/dash-financial-report/news-and-reviews”:
return newsReviews.create_layout(app)
elif pathname == “/dash-financial-report/dcc.Stores”:
return dcc.Stores.create_layout(app)
elif pathname == “/dash-financial-report/full-view”:
return (
overview.create_layout(app),
inputs.create_layout(app),
resultsOverview.create_layout(app),
cashFlows.create_layout(app),
feesMins.create_layout(app),
distributions.create_layout(app),
newsReviews.create_layout(app)
)
else:
return overview.create_layout(app)
Currently inputs.py, for example, has the create_layout function which sets up all the interactive components, a callback function that saves the most recent selected values of the slider for when the user toggles between tabs, and another callback function that actually calculates the key values. Both the callback functions are linked to the slider values but since the session is based in app.py, my worry is this current setup doesn’t actually execute the entirety of inputs.py, and if so, what the easiest way of fixing this would be.
If you put the dcc.Store
in app.py, it will be available to all pages of a multi-page app.