ComeçarComece de graça

Estendendo a cadeia

Seu menu suspenso condicional foi um sucesso! Isso deixou o dashboard mais limpo e proporcionou uma experiência de uso bem melhor. Ao demonstrar o produto, a pessoa interessada perguntou se você poderia implementar algumas melhorias.

Primeiro, ela quer selecionar um valor padrão para a categoria secundária, para que sempre apareça algo no gráfico. Você tem uma ideia de como fazer isso inserindo um callback encadeado adicional entre os dois primeiros criados.

Segundo, ela quer um título abaixo do gráfico que lembre aos usuários a qual categoria principal pertence a categoria secundária escolhida. Em vez de criar outro callback, você acha que dá para conseguir isso enviando a categoria principal escolhida para uma saída adicional.

Este exercício faz parte do curso

Construindo Dashboards com Dash e Plotly

Ver curso

Instruções do exercício

  • Crie um callback abaixo da linha 37 que seja acionado pelo valor do dropdown major_cat_dd e envie saída tanto para as options do dropdown minor_cat_dd quanto para o elemento chosen_major_cat_title.
  • Crie outro callback abaixo da linha 52 que defina um value padrão para o dropdown minor_cat_dd quando sua propriedade options for atualizada.

Exercício interativo prático

Experimente este exercício completando este código de exemplo.

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)
Editar e executar o código