Dropdown menus that feed off each other

I’m trying to create three Drop down menus, that feed off hierarchical data. Dropdown 1 (the top most tier) is feeding off Series of products, while Dropdown 2 (second in hierarchy) feeds of Models and, lastly, Dropdown 3 (last in hierarchy) feeds off of Issues. So, to be clear, a Series has many models, which, in turn, each of these has many issues.

The idea is to create three Dropdown menus that can filter each other once a value is selected in of those. I already created the callback function that filters downward in hierarchy, but I come to a problem trying to create a workaround around when I try to work out the logic in the other direction. As in, if I filter by model, I would like for the Series and Issue model to display the correct values. Here’s my code:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objs as go
import webbrowser as wb
import datetime
from analytics import Analytics

app = dash.Dash()

#Analytics class, reads last 90 days of data as data
analytics = Analytics()
analytics.dateSelector()
data = analytics.otherFilters()

#Date Values for the Date Range widget
dates = {}
for val in range(0, len(analytics.dateRange), 10):
dates[val] = analytics.dateRange[val]

#Series Values for Dropdown
series = [{‘label’: ‘All’, ‘value’: ‘all’}]
for val in analytics.seriesVals:
series.append({‘label’: val, ‘value’: val})

#Model Values for Dropdown
models = [{‘label’: ‘All’, ‘value’: ‘all’}]
for val in analytics.modelsVals:
models.append({‘label’: val, ‘value’: val})

#Issue Values for Dropdown
issues = [{‘label’: ‘All’, ‘value’: ‘all’}]
for val in analytics.issuesVals:
issues.append({‘label’: val, ‘value’: val})

app.layout = html.Div(
[
html.Div(
[
html.H1(
‘Dashboard’
)
]
),
html.Div(
[
html.Label(‘Select the Date Range’,
style = {
‘margin’: ‘20px’
}
),
dcc.RangeSlider(
marks = dates,
max = 90,
min = 0,
pushable = True,
allowCross = False,
id = ‘date-selector’

            ),
            html.Label('Select the Series',
                style = {
                    'margin': '20px'
                }
            ),
            dcc.Dropdown(
                options = series,
                value = 'all',
                id = 'series-selector',
                #multi = True
            ),
            html.Label('Select the Model',
                style = {
                    'margin': '20px'
                }
            ),
            dcc.Dropdown(
                options = models,
                value = 'all',
                id = 'model-selector',
                #multi = True
            ),
            html.Label('Select the Issue',
                style = {
                    'margin': '20px'
                }
            ),
            dcc.Dropdown(
                options = issues,
                value = 'all',
                id = 'issue-selector',
                #multi = True
            )
        ]
    ),
    html.Div(
        [
            dcc.Graph(
                id = 'hist'
            )
        ]
    )
]

)

@app.callback(
[Output(‘model-selector’, ‘options’),
Output(‘issue-selector’, ‘options’)],
[Input(‘series-selector’, ‘value’)]
)
def models_issues_updater(selSeries):
data = analytics.otherFilters(serieVals = selSeries)
models = [{‘label’: val, ‘value’: val} for val in analytics.modelsVals]
models.append({‘label’: ‘All’, ‘value’: ‘all’})
issues = [{‘label’: val, ‘value’: val} for val in analytics.issuesVals]
issues.append({‘label’: ‘All’, ‘value’: ‘all’})
return models, issues

if name == ‘main’:
app.run_server(debug = True)

1 Like