De keten uitbreiden
Je voorwaardelijke dropdown was een doorslaand succes! Dat maakte het dashboard overzichtelijker en zorgde voor een veel betere gebruikerservaring. Bij de demo vroeg de stakeholder of je een paar updates kunt doorvoeren.
Ten eerste willen ze een standaardwaarde kiezen voor de minor category, zodat er altijd iets in de grafiek verschijnt. Je weet hoe je dit kunt doen door een extra gekoppelde callback in te voegen tussen de eerste twee die je hebt gemaakt.
Ten tweede willen ze een titel onder de grafiek die gebruikers herinnert aan de major category waartoe de gekozen minor category behoort. In plaats van nog een callback denk je dat dit kan door de gekozen major category naar een extra output te sturen.
Deze oefening maakt deel uit van de cursus
Dashboards bouwen met Dash en Plotly
Oefeninstructies
- Maak een callback onder regel
37die wordt geactiveerd door de waarde van de dropdownmajor_cat_dden die output levert aan zowel deoptionsvan de dropdownminor_cat_ddals het elementchosen_major_cat_title. - Maak nog een callback onder regel
52die een standaardvalueinstelt voor de dropdownminor_cat_ddwanneer de eigenschapoptionsdaarvan wordt bijgewerkt.
Interactieve oefening met praktijkervaring
Probeer deze oefening door deze voorbeeldcode aan te vullen.
from dash import Dash, dcc, html, Input, Output, callback
import plotly.express as px
import pandas as pd
import random
ecom_sales = pd.read_csv('/usr/local/share/datasets/ecom_sales.csv')
major_categories = list(ecom_sales['Major Category'].unique())
minor_categories = list(ecom_sales['Minor Category'].unique())
logo_link = 'https://assets.datacamp.com/production/repositories/5893/datasets/fdbe0accd2581a0c505dab4b29ebb66cf72a1803/e-comlogo.png'
ecom_country = ecom_sales.groupby('Country')['OrderValue'].agg(['sum', 'count']).reset_index().rename(columns={'count':'Sales Volume', 'sum':'Total Sales ($)'})
app = Dash()
app.layout = [
html.Img(src=logo_link, style={'margin':'30px 0px 0px 0px'}),
html.H1('Sales breakdowns'),
html.Div([
html.H2('Controls'),
html.Br(),
html.H3('Major Category Select'),
dcc.Dropdown(
id='major_cat_dd',
options=[{'label':category, 'value':category} for category in major_categories],
style={'width':'200px', 'margin':'0 auto'}),
html.Br(),
html.H3('Minor Category Select'),
dcc.Dropdown(
id='minor_cat_dd',
style={'width':'200px', 'margin':'0 auto'})],
style={'width':'350px', 'height':'350px', 'display':'inline-block',
'vertical-align':'top', 'border':'1px solid black', 'padding':'20px'}),
html.Div([
dcc.Graph(id='sales_line'),
html.H3(id='chosen_major_cat_title')],
style={'width':'700px', 'height':'650px','display':'inline-block'})
]
# Create a callback to set minor values and HTML output
@callback(
Output('____', '____'),
Output('____', 'children'),
Input('major_cat_dd', 'value'))
def update_minor_dd(major_cat_dd):
major_minor = ecom_sales[['Major Category', 'Minor Category']].drop_duplicates()
relevant_minor_options = major_minor[major_minor['Major Category'] == major_cat_dd]['Minor Category'].values.tolist()
minor_options = [{'label':x, 'value':x} for x in relevant_minor_options]
if not major_cat_dd:
major_cat_dd = 'None Selected'
major_cat_title = f'This is in the Major Category of: {major_cat_dd}'
return minor_options, major_cat_title
# Create a callback to set a default minor category value
@callback(
Output('____', '____'),
Input('____', '____'))
def select_minor_cat(options):
chosen_val = 'None'
if options:
vals = [x['value'] for x in options]
chosen_val = random.choice(vals)
return chosen_val
@callback(
Output('sales_line', 'figure'),
Input('minor_cat_dd', 'value'))
def update_line(minor_cat):
minor_cat_title = 'All'
ecom_line = ecom_sales.copy()
if minor_cat:
minor_cat_title = minor_cat
ecom_line = ecom_line[ecom_line['Minor Category'] == minor_cat]
ecom_line = ecom_line.groupby('Year-Month')['OrderValue'].agg('sum').reset_index(name='Total Sales ($)')
line_graph = px.line(ecom_line, x='Year-Month', y='Total Sales ($)', title=f'Total Sales by Month for Minor Category: {minor_cat_title}')
return line_graph
if __name__ == '__main__':
app.run(debug=True)