Search code examples
pythonplotlyplotly-dashdashboardplotly-python

How to make Dash dropdown options depend upon another DCC inputs selection


Lets say I have some code as follows below:

import pandas as pd
import plotly.express as px
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import helper
from datetime import date



app = dash.Dash(__name__)


# import data

app.layout = html.Div(children=[

    dcc.Dropdown(
        id='slct_dataset',
        options= ['dataset1', 'dataset2'],
        placeholder="Select a dataset",
        multi=False,
        style={'width': '40%'}
                 ),

    dcc.DatePickerRange(
        id='slct_date',
        #todo make: below below depend upon dataset selection
        min_date_allowed=date(1980, 1, 1),
        max_date_allowed=date(2021, 1, 1),
        initial_visible_month=date(2017, 8, 5),
        end_date=date(2017, 8, 25)

    ),


    html.Div(id='output_container', children=[], style={
        'textAlign': 'center'
    }),
    html.Br(),

    dcc.Graph(id='my_graph', figure={})

])

#callback to produce graph
@app.callback(
    [
        Output(component_id='output_container', component_property='children'),
        Output(component_id='my_series_graph', component_property='figure')
    ],
    [
        Input(component_id='slct_dataset', component_property='value'),
        Input(component_id='slct_date', component_property='start_date'),
        Input(component_id='slct_date', component_property='end_date')
    ]
)

def update_graph(dataset_slctd, start_date_slctd, end_date_slctd):
    
    container = 'Dataset: {}'.format(dataset_slctd) +\
                '. Start date: {}'.format(start_date_slctd) + \
                '. End date: {}'.format(end_date_slctd) 


    dff = helper.get_dataset(dataset_slctd, start_date_slctd, end_date_slctd)

    dff['Datetime'] = dff.index
    fig = px.line(dff, x='Datetime', y='Value', title=dataset_slctd)

    return container, fig


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

Right now I have min and max date allowed hard coded as this min_date_allowed=date(1980, 1, 1) in date picker range. How can I define a date range dynamically based on the selection of a dataset in the first dropdown? Eg. lets say I have 01-01-2000/01-01-2001 as my min/max dataset for dataset1, and I have 02-02-2000/02-02-2001 as my min/max daterange for dataset2. How can I make my datepickerrange dynamically update based on whether I select dataset1 or dataset2 in my slct_dataset dropdown? As I understand this might depend on using a callback, but I can't really find what the standard way to do this is. Let me know if any more information can make the question more clear- I basically took the code I am actually writing and simplified it as much as possible so hopefully its clear what Im trying to do here. thanks for the help.


Solution

  • You can take the dropdown as an input to a callback and output to the date ranges of the datepicker based on the selected value. The signature should look like this:

    @app.callback(
        [
            Output(component_id='slct_date', component_property='min_date_allowed'),
            Output(component_id='slct_date', component_property='max_date_allowed'),
        ],
        [
            Input(component_id='slct_dataset', component_property='value'),
        ]
    )