Hello,
I have a page of tables that filter each other down based on the active cell clicked on the one above. See below:
I’d like to choose an active cell in the bottom table and have a full screen modal pop out that displays different graphs and tables pertaining to the active cell I chose.
Currently, when I click the active cell, the modal doesn’t pop out but just expands the app page itself. I’m not sure how to integrate a modal in an app page with other objects and have it pop out. Below is the code I’m using.
fullscreen = [ddk.Header([
ddk.Title('Demand Forecasting Model Overview'),
]),
ddk.Block(
children=[
ddk.ControlCard(
[ddk.CardHeader(title="Item/Snapshot Dropdown"),
ddk.ControlItem(children = [
dcc.Dropdown(
options = [{'label':i, 'value':i}
for i in snapshot
],
multi=False,
value = '2021-01-31',
id='snapshot_dropdown_modal',
),
]
)]
),
ddk.Card(
width=100,
children =[
ddk.Graph(
id='snapshot_timeseries_modal'
),
]),
ddk.Card(
width=100,
children=[
ddk.Graph(
id='snapshot_timeseries_bias_modal'
),
]),
ddk.Card(
width = 100,
children=[
ddk.Graph(
id='timeseries_modal'
)
]),
ddk.Card(
width=100,
children =[
ddk.Graph(
id='timeseries2_modal'
)
]),
ddk.Card(
width=100,
children=[
ddk.Graph(
id='tna_figure_modal'
)
]),
ddk.Card(
width=100,
children=[
ddk.Graph(
id='promo_figure_modal'
)
]),
]),
ddk.Block(
children=[
ddk.Card(
width=100,
children=[dbc.Label('Forecaster Notes'),
ddk.DataTable(id="notes_table_modal",
columns=[],
data=[],
filter_action = 'native',
sort_action = 'native')
])
]),
ddk.Block(
width = 50,
children = [
ddk.Card(
width=100,
children =[
ddk.Graph(
id='CoV_modal'
),
]),
]
),
ddk.Block(
width = 50,
children = [
ddk.Card(width = 100,
children = [
ddk.Graph(
id='BIAS_modal'
),
])
]
)
]
#############################################ACTUAL LAYOUT##############################################################
layout = ddk.App(show_editor=True,
children = [
ddk.Block(
#width = 99,
children=[
ddk.DataCard(
id='HW',
label="The hierarchy walk page allows a user to discover what business line, category, sub-category and item is driving the MAPE or BIAS. Each level of the hierarchy can be filtered by the the level above.",
value='Hierarchy Walk Page',
),
ddk.ControlCard(
[
ddk.ControlItem(children=[
dcc.Dropdown(
options = [{'label':i, 'value':i}
for i in ['home_delivery', 'shop_sales']
],
multi=False,
value = 'home_delivery',
id='location_dropdown',
),
dcc.Dropdown(
options = [{'label':i, 'value':i}
for i in model
],
multi=False,
value = 'stats_model',
id='model_dropdown'
),
],
)]
),
ddk.Card(children =[
ddk.Graph(
id='Business_Line_modal'
),
]),
]
),
ddk.Block(
width = 100,
children=[
ddk.Card(
width=100,
children=[ddk.DataTable(id="bl_table",
columns=[],
data=[],
filter_action = 'native',
sort_action = 'native'),
]
),
ddk.Card(
width=100,
children=[
ddk.DataTable(id='cat_table',
columns = [],
data = [],
filter_action = 'native',
sort_action = 'native',)
]
),
ddk.Card(
width=100,
children=[
ddk.DataTable(id='subcat_table',
columns = [],
data = [],
filter_action = 'native',
sort_action = 'native',
),
]
),
ddk.Card(
width=100,
children=[
ddk.DataTable(id='item_table',
columns = [],
data = [],
filter_action = 'native',
sort_action = 'native',
),
]
)
]
),
ddk.Modal(
id="modal_",
hide_target=True
),
html.Div(
id="full_screen_render"
)
]
)
#CONTROL THE BUSINESS LINE GRAPH
@callback(
dash.dependencies.Output('Business_Line_modal', 'figure'),
dash.dependencies.Input('model_dropdown', 'value'),
dash.dependencies.Input('location_dropdown', 'value'),
)
def update_bl(model, location):
df1 = df_final[(df_final['location_type'] == location) & (df_final['model'] == model)]
bl = df1.groupby(['glbl_bus_ln_desc']).agg({'ord_qty':'sum',
'predictions':'sum',
'sales_dollars':'sum',
'predicted_sales':'sum',
'diff':'sum'}).reset_index()
bl.replace([np.inf, -np.inf], np.nan, inplace=True)
bl['sales_dollars'] = np.round(bl['sales_dollars'])
bl['predictions'] = np.round(bl['predictions'])
bl.dropna(inplace = True)
bl.loc[:, 'MAPE'] = np.round(bl.loc[:, 'diff']/ bl.loc[:, 'sales_dollars'], 4) * 100
bl.loc[:, 'BIAS'] = np.round((bl.loc[:,'predicted_sales']- bl.loc[:, 'sales_dollars'])/ bl.loc[:, 'sales_dollars'], 4) * 100
fig1 = go.Figure(data=[
go.Bar( name='MAPE', x=bl['glbl_bus_ln_desc'], y=bl['MAPE']),
go.Bar(name='BIAS', x=bl['glbl_bus_ln_desc'], y=bl['BIAS'])
])
fig1.update_layout(barmode='group', plot_bgcolor='rgb(0,0,0)',
title=go.layout.Title(
text=f"{location} MAPE AND BIAS",
font=dict(
family="Courier New, monospace",
size=22,
color="#111111"
)))
return fig1
#CONTROL THE BL TABLE
@callback(
Output('bl_table', 'data'),
Output('bl_table', 'columns'),
Input('location_dropdown', 'value'),
Input('model_dropdown', 'value')
#look up ignore initial
#look up design kit
)
def filter_table_bl(location, model_type):
if location == 'home_delivery':
df1 = df_final[(df_final['location_type']=='home_delivery') & (df_final['model'] == model_type)].copy()
else:
df1 = df_final[(df_final['location_type']=='shop_sales') & (df_final['model'] == model_type)].copy()
bl = df1.groupby(['location_type', 'glbl_bus_ln_desc']).agg({'ord_qty':'sum',
'predictions':'sum',
'sales_dollars':'sum',
'predicted_sales':'sum',
'diff':'sum'}).reset_index()
bl.replace([np.inf, -np.inf], np.nan, inplace=True)
bl['sales_dollars'] = np.round(bl['sales_dollars'])
bl.loc[:, 'sales_pct'] = bl['sales_dollars']/bl['sales_dollars'].sum()
bl['predictions'] = np.round(bl['predictions'])
bl.dropna(inplace = True)
bl.loc[:, 'MAPE'] = bl.loc[:, 'diff']/ bl.loc[:, 'sales_dollars']
bl.loc[:, 'MAPE_CONTRIBUTION'] = bl.loc[:, 'sales_pct']*bl.loc[:, 'MAPE']/(bl.loc[:, 'sales_pct']*bl.loc[:, 'MAPE']).sum()
bl.loc[:, 'BIAS'] = np.round((bl.loc[:,'predicted_sales']- bl.loc[:, 'sales_dollars'])/ bl.loc[:, 'sales_dollars'], 4)
bl.loc[:, 'BIAS_CONTRIBUTION'] = bl.loc[:, 'sales_pct']*bl.loc[:, 'BIAS']/(bl.loc[:, 'sales_pct']*bl.loc[:, 'BIAS']).sum()
bl = bl[['location_type','glbl_bus_ln_desc', 'sales_dollars', 'sales_pct', 'MAPE', 'MAPE_CONTRIBUTION', 'BIAS', 'BIAS_CONTRIBUTION']]
return bl.to_dict('records'), [{'id':c, 'name':c, 'type':'numeric', 'format': money} if c in money_cols else {'id':c, 'name':c, 'type':'numeric', 'format':percentage} if c in percentage_cols
else {'id':c, 'name':c} for c in bl.columns ]
@callback(
Output('cat_table', 'data'),
Output('cat_table', 'columns'),
Input('location_dropdown', 'value'),
Input('bl_table', 'active_cell'),
State('bl_table', 'data')
#look up ignore initial
#look up design kit
)
def filter_table_cat(location, active_cell, state_):
state_ = pd.DataFrame(state_)
print(state_)
cat = df.groupby(['location_type', 'glbl_bus_ln_desc', 'glbl_ctgry_desc']).agg({'ord_qty':'sum',
'predictions':'sum',
'sales_dollars':'sum',
'predicted_sales':'sum',
'diff':'sum'}).reset_index()
if ctx.triggered_id == 'location_dropdown':
filtered_df = cat[cat['location_type'] == location]
elif ctx.triggered_id == 'bl_table':
filtered_df = cat[(cat['glbl_bus_ln_desc'] == state_.iloc[active_cell['row'], active_cell['column']]) &
(cat['location_type'] == location)]
print(active_cell)
else:
filtered_df = cat
filtered_df.replace([np.inf, -np.inf], np.nan, inplace=True)
filtered_df['sales_dollars'] = np.round(filtered_df['sales_dollars'])
filtered_df['sales_pct'] = filtered_df.loc[:, 'sales_dollars']/filtered_df['sales_dollars'].sum()
filtered_df.loc[:, 'MAPE'] = np.round(filtered_df.loc[:, 'diff']/ filtered_df.loc[:, 'sales_dollars'],4)
filtered_df.loc[:, 'MAPE_CONTRIBUTION'] = filtered_df['sales_pct']*filtered_df.loc[:, 'MAPE']/(filtered_df['sales_pct']*filtered_df.loc[:, 'MAPE']).sum()
filtered_df.loc[:, 'BIAS'] = np.round((filtered_df.loc[:,'predicted_sales']- filtered_df.loc[:, 'sales_dollars'])/ filtered_df.loc[:, 'sales_dollars'], 4)
filtered_df.loc[:, 'BIAS_CONTRIBUTION'] = filtered_df.loc[:, 'sales_pct']*filtered_df.loc[:, 'BIAS']/(filtered_df.loc[:, 'sales_pct']*filtered_df.loc[:, 'BIAS']).sum()
bl_category_table = filtered_df[['location_type','glbl_bus_ln_desc','glbl_ctgry_desc', 'sales_dollars', 'sales_pct', 'MAPE', 'MAPE_CONTRIBUTION', 'BIAS', 'BIAS_CONTRIBUTION']]
data = filtered_df.to_dict('records')
return data, [{'id':c, 'name':c, 'type':'numeric', 'format': money} if c in money_cols else {'id':c, 'name':c, 'type':'numeric', 'format':percentage} if c in percentage_cols
else {'id':c, 'name':c} for c in bl_category_table.columns ]
@callback(
Output('subcat_table', 'data'),
Output('subcat_table', 'columns'),
Input('location_dropdown', 'value'),
Input('cat_table', 'active_cell'),
State('cat_table', 'data')
#look up ignore initial
#look up design kit
)
def filter_table_subcat(location, active_cell, state_):
state_ = pd.DataFrame(state_)
subcat = df.groupby(['location_type', 'glbl_bus_ln_desc', 'glbl_ctgry_desc', 'glbl_sub_ctgry_desc']).agg({'ord_qty':'sum',
'predictions':'sum',
'sales_dollars':'sum',
'predicted_sales':'sum',
'diff':'sum'}).reset_index()
if ctx.triggered_id == 'location_dropdown':
filtered_df = subcat[subcat['location_type'] == location]
elif ctx.triggered_id == 'cat_table':
filtered_df = subcat[(subcat['glbl_ctgry_desc'] == state_.iloc[active_cell['row'], active_cell['column']]) &
(subcat['location_type'] == location)]
print(active_cell)
print(subcat[subcat['glbl_ctgry_desc'] == state_.iloc[active_cell['row'], active_cell['column']]])
else:
filtered_df = subcat
filtered_df.replace([np.inf, -np.inf], np.nan, inplace=True)
filtered_df['sales_pct'] = filtered_df['sales_dollars']/filtered_df['sales_dollars'].sum()
filtered_df.loc[:, 'MAPE'] = np.round(filtered_df.loc[:, 'diff']/ filtered_df.loc[:, 'sales_dollars'],4)
filtered_df.loc[:, 'MAPE_CONTRIBUTION'] = filtered_df['sales_pct']*filtered_df.loc[:, 'MAPE']
filtered_df.loc[:, 'BIAS'] = np.round((filtered_df.loc[:,'predicted_sales']- filtered_df.loc[:, 'sales_dollars'])/ filtered_df.loc[:, 'sales_dollars'], 4)
filtered_df.loc[:, 'BIAS_CONTRIBUTION'] = filtered_df.loc[:, 'sales_pct']*filtered_df.loc[:, 'BIAS']/(filtered_df.loc[:, 'sales_pct']*filtered_df.loc[:, 'BIAS']).sum()
filtered_df.loc[:, 'MAPE_CONTRIBUTION'] = filtered_df['sales_pct']*filtered_df.loc[:, 'MAPE']/(filtered_df['sales_pct']*filtered_df.loc[:, 'MAPE']).sum()
bl_subcategory_table = filtered_df[['location_type','glbl_bus_ln_desc', 'glbl_ctgry_desc', 'glbl_sub_ctgry_desc', 'sales_dollars', 'sales_pct', 'MAPE', 'MAPE_CONTRIBUTION', 'BIAS',
'BIAS_CONTRIBUTION']]
data = filtered_df.to_dict('records')
return data, [{'id':c, 'name':c, 'type':'numeric', 'format': money} if c in money_cols else {'id':c, 'name':c, 'type':'numeric', 'format':percentage} if c in percentage_cols
else {'id':c, 'name':c} for c in bl_subcategory_table.columns ]
@callback(
Output('item_table', 'data'),
Output('item_table', 'columns'),
Input('location_dropdown', 'value'),
Input('subcat_table', 'active_cell'),
State('subcat_table', 'data')
#look up ignore initial
#look up design kit
)
def filter_table_item(location, active_cell, state_):
state_ = pd.DataFrame(state_)
item = df.groupby(['location_type', 'glbl_bus_ln_desc', 'glbl_ctgry_desc', 'glbl_sub_ctgry_desc', 'item_desc', 'ord_base7']).agg({'ord_qty':'sum',
'predictions':'sum',
'sales_dollars':'sum',
'predicted_sales':'sum',
'diff':'sum'}).reset_index()
if ctx.triggered_id == 'location_dropdown':
filtered_df = item[item['location_type'] == location]
elif ctx.triggered_id == 'subcat_table':
filtered_df = item[(item['glbl_sub_ctgry_desc'] == state_.iloc[active_cell['row'], active_cell['column']]) &
(item['location_type'] == location)]
print(active_cell)
print(item[item['glbl_ctgry_desc'] == state_.iloc[active_cell['row'], active_cell['column']]])
else:
filtered_df = item
filtered_df.replace([np.inf, -np.inf], np.nan, inplace=True)
filtered_df['sales_dollars'] = np.round(filtered_df['sales_dollars'])
filtered_df['sales_pct'] = filtered_df['sales_dollars']/filtered_df['sales_dollars'].sum()
filtered_df.loc[:, 'MAPE'] = np.round(filtered_df.loc[:, 'diff']/ filtered_df.loc[:, 'sales_dollars'],4)
filtered_df.loc[:, 'MAPE_CONTRIBUTION'] = filtered_df['sales_pct']*filtered_df.loc[:, 'MAPE']/(filtered_df['sales_pct']*filtered_df.loc[:, 'MAPE']).sum()
filtered_df.loc[:, 'BIAS'] = np.round((filtered_df.loc[:,'predicted_sales']- filtered_df.loc[:, 'sales_dollars'])/ filtered_df.loc[:, 'sales_dollars'], 4)
filtered_df.loc[:, 'BIAS_CONTRIBUTION'] = filtered_df.loc[:, 'sales_pct']*filtered_df.loc[:, 'BIAS']/(filtered_df.loc[:, 'sales_pct']*filtered_df.loc[:, 'BIAS']).sum()
bl_item_table = filtered_df[['location_type','glbl_bus_ln_desc', 'glbl_ctgry_desc', 'glbl_sub_ctgry_desc', 'item_desc', 'ord_base7', 'sales_dollars', 'sales_pct',
'MAPE', 'MAPE_CONTRIBUTION', 'BIAS', 'BIAS_CONTRIBUTION']]
data = filtered_df.to_dict('records')
return data, [{'id':c, 'name':c, 'type':'numeric', 'format': money} if c in money_cols else {'id':c, 'name':c, 'type':'numeric', 'format':percentage} if c in percentage_cols
else {'id':c, 'name':c} for c in bl_item_table.columns ]
#BEGIN MODAL
###############################################################################
@callback(
Output("full_screen_render", "children"),
Input("item_table", "active_cell"),
# Input("close-body-scroll", "n_clicks"),
# State("modal_", "is_open"),
)
def toggle_modal(active_cell):
# if n1 or n2:
if (active_cell):
return fullscreen
else:
return None
@callback(
dash.dependencies.Output('snapshot_timeseries_modal', 'figure'),
dash.dependencies.Input("item_table", "active_cell"),
State("item_table", "data")
)
def time_series_show_snapshot(active_cell, state_):
state_ = pd.DataFrame(state_)
if ctx.triggered_id == 'item_table':
item = state_.iloc[active_cell['row'], active_cell['column']]
else:
item = "100188K"
# item= state_.iloc[active_cell['row'], active_cell['column']]
df_table = df_final[df_final['ord_base7']==item].groupby(['ord_base7', 'item_desc','model', 'snapshot']).agg({'diff':'sum',
'predicted_sales':'sum', 'sales_dollars':'sum'}).reset_index()
df_table.loc[:, 'MAPE'] = np.round(df_table.loc[:, 'diff']/ df_table.loc[:, 'sales_dollars'], 4)
df_table.loc[:, 'ACCURACY'] = 1 - df_table.loc[:,'MAPE']
df_table.loc[:, 'BIAS'] = np.round((df_table.loc[:,'predicted_sales']- df_table.loc[:, 'sales_dollars'])/ df_table.loc[:, 'sales_dollars'], 4)
# print("Data for time series", df_[['dmand_yr_mo', 'ord_base7', 'snapshot', 'model', 'location_type', 'sales_dollars']].sort_values('dmand_yr_mo'))
fig = px.bar(df_table, x="snapshot", y="MAPE",
color="model", barmode="group", title = item+" MAPE by Snapshot")
return fig
#CONTROL THE Time Series GRAPH
@callback(
dash.dependencies.Output('snapshot_timeseries_bias_modal', 'figure'),
dash.dependencies.Input('item_table', 'active_cell'),
State("item_table", "data")
)
def time_series_show_snapshot_bias(active_cell, state_):
state_ = pd.DataFrame(state_)
if ctx.triggered_id == 'item_table':
item = state_.iloc[active_cell['row'], active_cell['column']]
else:
item = "100188K"
df_table = df_final[df_final['ord_base7']==item].groupby(['ord_base7', 'item_desc','model', 'snapshot']).agg({'diff':'sum',
'predicted_sales':'sum', 'sales_dollars':'sum'}).reset_index()
df_table.loc[:, 'MAPE'] = np.round(df_table.loc[:, 'diff']/ df_table.loc[:, 'sales_dollars'], 4)
df_table.loc[:, 'ACCURACY'] = 1 - df_table.loc[:,'MAPE']
df_table.loc[:, 'BIAS'] = np.round((df_table.loc[:,'predicted_sales']- df_table.loc[:, 'sales_dollars'])/ df_table.loc[:, 'sales_dollars'], 4)
# print("Data for time series", df_[['dmand_yr_mo', 'ord_base7', 'snapshot', 'model', 'location_type', 'sales_dollars']].sort_values('dmand_yr_mo'))
fig = px.bar(df_table, x="snapshot", y="BIAS",
color="model", barmode="group", title = "BIAS by Snapshot")
return fig
#CONTROL THE Time Series GRAPH
@callback(
dash.dependencies.Output('timeseries_modal', 'figure'),
dash.dependencies.Input('snapshot_dropdown_modal', 'value'),
dash.dependencies.Input('item_table', 'active_cell'),
State("item_table", "data")
)
def time_series_show_hd(snapshot, active_cell, state_):
state_ = pd.DataFrame(state_)
if ctx.triggered_id == 'item_table':
item = state_.iloc[active_cell['row'], active_cell['column']]
else:
item = "100188K"
df_ = df_final[(df_final['ord_base7']==item) & (df_final['snapshot'] == snapshot) & (df_final['location_type'] == "home_delivery")].sort_values('dmand_yr_mo').copy()
# print("Data for time series", df_[['dmand_yr_mo', 'ord_base7', 'snapshot', 'model', 'location_type', 'sales_dollars']].sort_values('dmand_yr_mo'))
fig = px.scatter(df_, x = 'dmand_yr_mo', y = 'predicted_sales', color = 'model')
fig1 = px.line(df_[(df_['model'] == 'stats_model') & (df_['location_type'] == 'home_delivery')], x = 'dmand_yr_mo', y = 'sales_dollars')
fig3 = go.Figure(data=fig.data + fig1.data)
fig3.update_layout(hovermode="x unified", title = "Actual (line) vs Predicted (points) Sales @ Home Delivery")
return fig3
@callback(
dash.dependencies.Output('timeseries2_modal', 'figure'),
dash.dependencies.Input('snapshot_dropdown_modal', 'value'),
dash.dependencies.Input('item_table', 'active_cell'),
State("item_table", "data"),
)
def time_series_show_ss(snapshot, active_cell, state_):
state_ = pd.DataFrame(state_)
if ctx.triggered_id == 'item_table':
item = state_.iloc[active_cell['row'], active_cell['column']]
else:
item = "100188K"
df_ = df_final[(df_final['ord_base7']==item) & (df_final['snapshot'] == snapshot) & (df_final['location_type'] != "home_delivery")].sort_values('dmand_yr_mo').copy()
# print("Data for time series", df_[['dmand_yr_mo', 'ord_base7', 'snapshot', 'model', 'location_type', 'sales_dollars']].sort_values('dmand_yr_mo'))
fig = px.scatter(df_, x = 'dmand_yr_mo', y = 'predicted_sales', color = 'model')
fig1 = px.line(df_[(df_['model'] == 'stats_model') & (df_['location_type'] != 'home_delivery')], x = 'dmand_yr_mo', y = 'sales_dollars')
fig3 = go.Figure(data=fig.data + fig1.data)
fig3.update_layout(hovermode="x unified", title = "Actual (line) vs Predicted (points) Sales @ Shop Sales")
return fig3
@callback(
dash.dependencies.Output('tna_figure_modal', 'figure'),
dash.dependencies.Input('snapshot_dropdown_modal', 'value'),
dash.dependencies.Input('item_table', 'active_cell'),
State("item_table", "data"),
)
def tna_show(snapshot, active_cell, state_):
state_ = pd.DataFrame(state_)
if ctx.triggered_id == 'item_table':
item = state_.iloc[active_cell['row'], active_cell['column']]
else:
item = "100188K"
df_ = df_final[(df_final['ord_base7']==item) & (df_final['snapshot'] == snapshot)].sort_values('dmand_yr_mo').copy()
# print("Data for time series", df_[['dmand_yr_mo', 'ord_base7', 'snapshot', 'model', 'location_type', 'sales_dollars']].sort_values('dmand_yr_mo'))
fig = px.scatter(df_, x='dmand_yr_mo', y='adj_tna_daily', color = 'location_type',
title="Time Series Look - TNA")
return fig
@callback(
dash.dependencies.Output('promo_figure_modal', 'figure'),
dash.dependencies.Input('snapshot_dropdown_modal', 'value'),
dash.dependencies.Input('item_table', 'active_cell'),
State("item_table", "data")
)
def tna_show(snapshot, active_cell, state_):
state_ = pd.DataFrame(state_)
if ctx.triggered_id == 'item_table':
item = state_.iloc[active_cell['row'], active_cell['column']]
else:
item = "100188K"
df_ = df_final[(df_final['ord_base7']==item) & (df_final['snapshot'] == snapshot)].sort_values('dmand_yr_mo').copy()
# print("Data for time series", df_[['dmand_yr_mo', 'ord_base7', 'snapshot', 'model', 'location_type', 'sales_dollars']].sort_values('dmand_yr_mo'))
df_.loc[:, 'cannibalized'] = df_.loc[:, 'cannibalized'].astype('str')
fig = px.scatter(df_, x='dmand_yr_mo', y='promo_status_metric_measure', color = 'cannibalized',
title="Time Series Look - Promotion Occurence")
return fig
#Control BIAS graph
@callback(
dash.dependencies.Output('BIAS_modal', 'figure'),
dash.dependencies.Input('item_table', 'active_cell'),
State("item_table", "data")
# dash.dependencies.Input('snapshot_dropdown_modal', 'value')
)
def cov_show(active_cell, state_):
state_ = pd.DataFrame(state_)
if ctx.triggered_id == 'item_table':
item = state_.iloc[active_cell['row'], active_cell['column']]
else:
item = "100188K"
df_ = df_final[(df_final['ord_base7']==item)]
df_['diff'] = np.round((np.round(df_.loc[:, 'predicted_sales'] - df_.loc[:, 'sales_dollars'],2)))
df_['BIAS'] = (df_.loc[:, 'diff']/df_.loc[:, 'sales_dollars'])
fig = px.histogram(df_, x = 'BIAS', color = 'location_type', title=item + " BIAS by Location Type", )
return fig
#Control CoV graph
@callback(
dash.dependencies.Output('CoV_modal', 'figure'),
dash.dependencies.Input('item_table', 'active_cell'),
State("item_table", "data")
# dash.dependencies.Input('snapshot_dropdown_modal', 'value')
)
def cov_show(active_cell, state_):
state_ = pd.DataFrame(state_)
if ctx.triggered_id == 'item_table':
item = state_.iloc[active_cell['row'], active_cell['column']]
else:
item = "100188K"
df1 = df_final.copy()
df1_group = df1[df1['month_offset']==6].groupby(['ord_base7', 'location_type']).agg(sum_sales = ('sales_dollars','sum'),
std_sales = ('sales_dollars', 'std'),
mean_sales = ('sales_dollars', 'mean'),
sum_predictioned_sales = ('predicted_sales', 'sum')).reset_index()
df1_group['CoV'] = df1_group.loc[:, 'std_sales']/df1_group.loc[:, 'mean_sales']
df1_group['diff'] = np.round(np.abs(np.round(df1_group.loc[:, 'sum_predictioned_sales'] - df1_group.loc[:, 'sum_sales'],2)))
df1_group['MAPE'] = (df1_group.loc[:, 'diff']/df1_group.loc[:, 'sum_sales'])
fig = px.scatter(df1_group, x='CoV', y='MAPE', color = 'location_type',
title="MAPE v. Sales Variation @ Six Month Offset - Based on Dollars")
fig.update_layout(yaxis_range=[0, 2])
fig.add_trace(go.Scatter(x=df1_group[df1_group['ord_base7'] == item]['CoV'],
y=df1_group[df1_group['ord_base7'] == item]['MAPE'], mode = 'markers',
marker_symbol = 'star', marker_size = 15, name = item,))
fig.add_hline(y=0.2)
fig.add_vline(x=df1_group['CoV'].mean())
return fig
@callback(
dash.dependencies.Output('notes_table_modal', 'data'),
dash.dependencies.Output('notes_table_modal', 'columns'),
dash.dependencies.Input('item_table', 'active_cell'),
State('item_table', 'data')
)
def get_notes(active_cell, state_):
state_ = pd.DataFrame(state_)
if ctx.triggered_id == 'item_table':
item = state_.iloc[active_cell['row'], active_cell['column']]
else:
item = "100188K"
df_ = df_notes[df_notes['ITEM_NO']==item]
return df_.to_dict('records'), [{"name": i, "id": i} for i in df_.columns]