Working with Multiple Dropdown Menus to Filter Data from Spreadsheet

I’m using multiple dropdown menus in this application but need some help with the coding logic. The user will use 4 dropdown menus to filter through large amounts of data. Then, based on what the user selects from the dropdown menu that data will be displayed in 2 pie charts comparing data from version 1 STATUS results and version 2 STATUS results.

For example, there are multiple applications the user can choose from in the first dropdown menu so for the server and release date dropdown menus there should only be information showing that relates to that application chosen.

The order of dropdown menus needs to be:

  1. Application
  2. Server
  3. Benchmark
  4. Release date

I will attach a link to a google spreadsheet to view sample data.
Sample Data

1 Like

Hi,

Please take a look on this example in the docs, where the options in the second component is updated according to changes in the first component.

You can easily filter your dataframe to provide options matching values that are only related to the application.

Please follow up if you have specific problems adapting the example to your case. It should be pretty straightforward.

2 Likes

Thanks for the comment! I am interested in knowing how the coding logic would work when it comes to updating the two pie charts after the user has gone through and selected from the dropdown menus?

For example, the user selects the following from the dropdown menus:
1.application == FAF
2. Server == SRV303
3. Benchmark == windows 2012
4. Release date == 8/15/2021

I want one pie chart to display the STATUS1 results and the other pie chart to display STATUS2 results. Comparing what updates have been made to the software from version 1 to version 2.

To update both charts based on the dropdown values, you’ll need to implement a callback. This callback could have a structure like this:

@callback(
    Output("graph1", "figure"),
    Output("graph2", "figure"),
    [
        Input("application", "value"),
        Input("server", "value"),
        Input("benchmark", "value"),
        Input("release-date", "value")
    ]
)
def update_graphs(application, server, benchmark, release_date):
    if application is None or server is None or benchmark is None or release_date is None:
        raise PreventUpdate
    df_subset = df.query("Application == @application & # ....")
    fig1 = px.pie(df_subset, # ...)
    fig2 = px.pie(df_subset, # ...)
    return fig1, fig2

The first conditional is important to make sure that you are not using a None in the query, which may occur in situations where the selection is empty (you can always update the options and the default value together though). Besides, the pie charts will be updated whenever a selection is changed and all values are defined.

Hope this helps!

1 Like

Thanks for the code example! So for the dropdown menus, I want them to be in one row side by side, and then below that would be the two pie charts. So would the dropdown menus be in one div and the two pie charts be in another div?

Thanks again for your help!

So for the dropdown menus, I want them to be in one row side by side, and then below that would be the two pie charts. So would the dropdown menus be in one div and the two pie charts be in another div?

Yes, but not only that, as by default all elements will be stacked vertically. I would recommend you to take a look on libraries like dash-bootstrap-components and dash-mantine-components if you are not familiar with basic CSS styling. You are also welcome to ask another question if you can’t figure this out, there are threads out here with similar questions.

Here is what I was able to come up with. Am I on the right track?

#app layout
#------------------------------------------------------
#Dropdown menus
#------------------------------------------------------
app = dash.Dash(__name__)
app.layout = html.Div([
    html.Div([
        html.Div([
            dcc.Dropdown(id='applicationdropdown',
                options=[{'label':x, 'value':x} for x in dff.sort_values('Application')['Application'].unique()],
                value='FAF',
                multi=False,
                clearable=False
            ),
        ],className='six columns'),
        
        html.Div([
            dcc.Dropdown(id='serverdropdown',
                options=[{'label':x, 'value':x} for x in dff.sort_values('Server')['Server'].unique()],
                value='SRV303',
                multi=False,
                clearable=False
            ),
        ],className='six columns'),
          
        html.Div([
        dcc.Dropdown(id='benchmarkdropdown',
            options=[{'label':x, 'value':x} for x in dff.sort_values('Release Date')['Release Date'].unique()],
            value='windows2012',
            multi=False,
            clearable=False
        ),
        ],className='six columns'),

        html.Div([
        dcc.Dropdown(id='releasedatedropdown',
            options=[{'label':x, 'value':x} for x in dff.sort_values('STIG')['STIG'].unique()],
            value='21-08-15',
            multi=False,
            clearable=False
        ),
        ],className='six columns'),
    ],className='row'),

#Pie charts
#------------------------------------------------------

    html.Div([
        html.Div([
            html.H4('Status Results 1'),
            dcc.Graph(id='peichart1'),
        ],className='six columns'),

        html.Div([
            html.H4('Status Results 2'),
            dcc.Graph(id='peichart2'),
        ],className='six columns'),

    ],className='row'),

]) #end of  app layout div

#dashboard callouts
#------------------------------------------------------
@app.callback(
    Output("peichart1", "figure"),
    Output("piechart2", "figure"),
    [
        Input("applicationdropdown", "value"),
        Input("serverdropdown", "value"),
        Input("benchmarkdropdown", "value"),
        Input("releasedatedropdown", "value")
    ]
)
def update_graphs(application, server, benchmark, release_date):
    if application is None or server is None or benchmark is None or release_date is None:
        raise PreventUpdate
    df_subset = df.query("Application == @application & # ....")
    fig1 = px.pie(df_subset, # ...)
    fig2 = px.pie(df_subset, # ...)
    return fig1, fig2


if __name__ == '__main__':
    app.run_server(debug=True)

Hard to say without the CSS where you define those classes. Please take a look on the documentation of Dash Bootstrap Components that I linked in my previous answer.