Zacznij terazZacznij za darmo

Rozbudowa dashboardu sprzedażowego

Firma e-commerce jest zachwycona twoją pracą i wciąż wpada na nowe, kreatywne pomysły. Tym razem chce otrzymać rozbudowany dashboard, który łączy wszystko, co do tej pory zbudowano, w jeden interaktywny interfejs.

Na liście życzeń znalazły się:

  • Wykres liniowy miesięcznej sprzedaży filtrowany według głównych i podrzędnych kategorii.
  • Lista rozwijana dla każdej kategorii, w której opcje podrzędne aktualizują się na podstawie wybranej kategorii głównej.
  • Tabela z zagregowanymi statystykami dla wybranych kategorii.
  • Wykres słupkowy całkowitej sprzedaży według krajów.
  • Kolejny wykres słupkowy pokazujący sprzedaż w podkategoriach, który aktualizuje się po najechaniu kursorem na wykres krajów.

Wszystkie elementy masz już gotowe – teraz czas złożyć je razem!

To ćwiczenie jest częścią kursu

Tworzenie dashboardów z Dash i Plotly

Zobacz kurs

Instrukcje do ćwiczenia

  • Włącz paginację dla grid, ustawiając parametr pagination poniżej linii 23.
  • Ogranicz każdą stronę do 6 wierszy, ustawiając parametr paginationPageSize poniżej linii 26.
  • Wstaw obiekt grid do listy app.layout poniżej linii 49.

Interaktywne ćwiczenie praktyczne

Spróbuj tego ćwiczenia, uzupełniając ten przykładowy kod.

from dash import Dash, dcc, html, Input, Output, callback
import plotly.express as px
import pandas as pd
from dash_ag_grid import AgGrid
ecom_sales = pd.read_csv('/usr/local/share/datasets/ecom_sales.csv')
logo_link = 'https://assets.datacamp.com/production/repositories/5893/datasets/fdbe0accd2581a0c505dab4b29ebb66cf72a1803/e-comlogo.png'
major_categories = list(ecom_sales['Major Category'].unique())
large_tb = ecom_sales.groupby(['Major Category', 'Minor Category'])['OrderValue'].agg(['sum', 'count', 'mean']).reset_index().rename(columns={'count':'Sales Volume', 'sum':'Total Sales ($)', 'mean':'Average Order Value ($)'})
ecom_country = ecom_sales.groupby('Country')['OrderValue'].agg('sum').reset_index(name='Total Sales ($)')
bar_fig_country = px.bar(ecom_country, x='Total Sales ($)', y='Country', width=500, height=450, title='Total Sales by Country (Hover to filter the Minor Category bar chart!)', custom_data=['Country'], color='Country', color_discrete_map={'United Kingdom':'lightblue', 'Germany':'orange', 'France':'darkblue', 'Australia':'green', 'Hong Kong':'red'})
money_fmt = {"function": ("params.value.toLocaleString('en-US', {style: 'currency', currency: 'USD'})")}

column_defs = [
  {"field": "Major Category"},
  {"field": "Total Sales ($)", "valueFormatter": money_fmt},
  {"field": "Average Order Value ($)", "valueFormatter": money_fmt},
  {"field": "Sales Volume"}
]

grid = AgGrid(
  columnDefs=column_defs,
  rowData=large_tb.to_dict("records"),
  # Turn on pagination
  dashGridOptions={
    "____": ____,        
    # Show 6 rows per page
    "____": ____}       
)

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':'360px', 'display':'inline-block', 'vertical-align':'top', 'border':'1px solid black', 'padding':'20px'}),
  html.Div([
    html.H3(id='chosen_major_cat_title'),
    dcc.Graph(id='sales_line')],
    style={'width':'700px', 'height':'380px','display':'inline-block', 'margin-bottom':'5px'}),
  # Insert the AG Grid
  ____,
  html.Div([
    html.Div(dcc.Graph(id='major_cat', figure=bar_fig_country), style={'display':'inline-block'}),
    html.Div(dcc.Graph(id='minor_cat'), style={'display':'inline-block'})],
    style={'width':'1000px', 'height':'650px','display':'inline-block'})
]

@callback(
   Output('minor_cat_dd', 'options'),
   Output('chosen_major_cat_title', 'children'),
   Input('major_cat_dd', 'value'))

def update_dd(major_cat_dd):
    major_minor = ecom_sales[['Major Category', 'Minor Category']].drop_duplicates()
    relevant_minor = major_minor[major_minor['Major Category'] == major_cat_dd]['Minor Category'].values.tolist()
    minor_options = [dict(label=x, value=x) for x in relevant_minor]
    if not major_cat_dd:
        major_cat_dd = 'ALL'
    major_cat_title = f'This is in the Major Category of : {major_cat_dd}'
    return minor_options, major_cat_title

@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}', height=350)
    return line_graph

@callback(
    Output('minor_cat', 'figure'),
    Input('major_cat', 'hoverData'))

def update_min_cat_hover(hoverData):
    hover_country = 'Australia'
    if hoverData:
        hover_country = hoverData['points'][0]['customdata'][0]
    minor_cat_df = ecom_sales[ecom_sales['Country'] == hover_country]
    minor_cat_agg = minor_cat_df.groupby('Minor Category')['OrderValue'].agg('sum').reset_index(name='Total Sales ($)')
    ecom_bar_minor_cat = px.bar(minor_cat_agg, x='Total Sales ($)', y='Minor Category', orientation='h', height=450, width=480,title=f'Sales by Minor Category for: {hover_country}')
    ecom_bar_minor_cat.update_layout({'yaxis':{'dtick':1, 'categoryorder':'total ascending'}, 'title':{'x':0.5}})
    return ecom_bar_minor_cat


if __name__ == '__main__':
    app.run(debug=True)
Edytuj i uruchom kod