diff --git a/src/components/bar_chart.py b/src/components/bar_chart.py index baad0ed..06c376c 100644 --- a/src/components/bar_chart.py +++ b/src/components/bar_chart.py @@ -2,10 +2,12 @@ import pandas as pd import plotly.express as px from dash import Dash, dcc, html from dash.dependencies import Input, Output +import dash_bootstrap_components as dbc from ..data.loader_gz import MTBFSchema from . import ids + def render(app: Dash, data: pd.DataFrame) -> html.Div: @app.callback( Output(ids.BAR_CHART, "children"), @@ -17,32 +19,33 @@ def render(app: Dash, data: pd.DataFrame) -> html.Div: ], ) def update_bar_chart( - years: list[str], weeks: list[str], hits_type: str, single_hitter_filter: list[str] + years: list[str], weeks: list[str], u_hits: bool, remove_single: bool ) -> html.Div: - filtered_data = data.query( - "year in @years and week in @weeks" - ) + filtered_data = data.query("year in @years and week in @weeks") if filtered_data.shape[0] == 0: return html.Div("No data selected.") - if hits_type == "p-hits": - hits_col = MTBFSchema.P_HITS - else: - hits_col = MTBFSchema.U_HITS + hits_col = MTBFSchema.U_HITS if u_hits else MTBFSchema.P_HITS + hits_type = "U-Hits" if u_hits else "P-Hits" # Count 'Y' values and create pareto - pareto_data = filtered_data[filtered_data[hits_col] == 'Y'].groupby(MTBFSchema.AIR).size().reset_index(name='count') - - if 'remove_single' in single_hitter_filter: - pareto_data = pareto_data[pareto_data['count'] > 1] + pareto_data = ( + filtered_data[filtered_data[hits_col] == "Y"] + .groupby(MTBFSchema.AIR) + .size() + .reset_index(name="count") + ) - pareto_data = pareto_data.sort_values('count', ascending=False) + if remove_single: + pareto_data = pareto_data[pareto_data["count"] > 1] + + pareto_data = pareto_data.sort_values("count", ascending=False) fig = px.bar( pareto_data, x=MTBFSchema.AIR, y="count", - title=f"{hits_type.capitalize()} per AIR (Pareto)", + title=f"{hits_type} per AIR (Pareto)", labels={ MTBFSchema.AIR: "AIR", "count": "Count", @@ -52,20 +55,15 @@ def render(app: Dash, data: pd.DataFrame) -> html.Div: return html.Div( children=[ - dcc.RadioItems( + dbc.Switch( id=ids.PU_HITS_SELECTOR, - options=[ - {'label': 'P-Hits', 'value': 'p-hits'}, - {'label': 'U-Hits', 'value': 'u-hits'}, - ], - value='p-hits', - labelStyle={'display': 'inline-block'} + label="P-Hits / U-Hits", + value=False, ), - dcc.Checklist( + dbc.Switch( id=ids.SINGLE_HITTER_FILTER, - options=[{'label': 'Remove single hitters', 'value': 'remove_single'}], - value=[], - labelStyle={'display': 'inline-block'} + label="Remove single hitters", + value=False, ), html.Div(id=ids.BAR_CHART), ] diff --git a/src/components/data_table.py b/src/components/data_table.py index 9b55acf..d2065b5 100644 --- a/src/components/data_table.py +++ b/src/components/data_table.py @@ -7,6 +7,15 @@ import dash_bootstrap_components as dbc from ..data.loader_gz import MTBFSchema from . import ids +import pandas as pd +from dash import Dash, dcc, html, dash_table, Input, Output, State, callback_context +from datetime import datetime +import os +import dash_bootstrap_components as dbc + +from ..data.loader_gz import MTBFSchema +from . import ids + def render(app: Dash, data: pd.DataFrame) -> html.Div: @app.callback( Output(ids.DATA_TABLE, "children"), @@ -18,7 +27,7 @@ def render(app: Dash, data: pd.DataFrame) -> html.Div: ], ) def update_data_table( - years: list[str], weeks: list[str], hits_type: str, single_hitter_filter: list[str] + years: list[str], weeks: list[str], u_hits: bool, remove_single: bool ) -> html.Div: filtered_data = data.query( "year in @years and week in @weeks" @@ -26,10 +35,7 @@ def render(app: Dash, data: pd.DataFrame) -> html.Div: if filtered_data.shape[0] == 0: return html.Div("No data selected.") - if hits_type == "p-hits": - hits_col = MTBFSchema.P_HITS - else: - hits_col = MTBFSchema.U_HITS + hits_col = MTBFSchema.U_HITS if u_hits else MTBFSchema.P_HITS # Count 'Y' values hits_data = filtered_data[filtered_data[hits_col] == 'Y'] @@ -40,10 +46,8 @@ def render(app: Dash, data: pd.DataFrame) -> html.Div: close_notes=(MTBFSchema.CLOSE_NOTES, lambda x: ', '.join(x.dropna().astype(str).unique())) ).reset_index() - if 'remove_single' in single_hitter_filter: + if remove_single: table_data = table_data[table_data['count'] > 1] - else: - table_data = table_data[table_data['count'] == 1] table_data = table_data.sort_values('count', ascending=False) @@ -51,7 +55,7 @@ def render(app: Dash, data: pd.DataFrame) -> html.Div: table_data = table_data[[MTBFSchema.AIR, 'air_issue_description', 'close_notes', 'count']] return dash_table.DataTable( - id=ids.CATEGORY_TABLE, # Using this ID for feedback callbacks + id=ids.MTBF_PAR_TABLE, # Using this ID for feedback callbacks data=table_data.to_dict("records"), columns=[{"name": i, "id": i} for i in table_data.columns], page_size=10, @@ -64,11 +68,11 @@ def render(app: Dash, data: pd.DataFrame) -> html.Div: @app.callback( Output(ids.FEEDBACK_MODAL, "is_open"), Output(ids.FEEDBACK_MESSAGE, "children"), - Input(ids.CATEGORY_TABLE, "selected_rows"), + Input(ids.MTBF_PAR_TABLE, "selected_rows"), Input(ids.SAVE_FEEDBACK_BUTTON_POPUP, "n_clicks"), Input(ids.CLOSE_FEEDBACK_BUTTON_POPUP, "n_clicks"), State(ids.FEEDBACK_MODAL, "is_open"), - State(ids.CATEGORY_TABLE, "data"), + State(ids.MTBF_PAR_TABLE, "data"), State(ids.FEEDBACK_INPUT, "value"), ) def handle_feedback_modal(selected_rows, save_clicks, close_clicks, is_open, table_data, comment): @@ -78,7 +82,7 @@ def render(app: Dash, data: pd.DataFrame) -> html.Div: triggered_id = ctx.triggered[0]['prop_id'].split('.')[0] - if triggered_id == ids.CATEGORY_TABLE and selected_rows: + if triggered_id == ids.MTBF_PAR_TABLE and selected_rows: return True, "" if triggered_id == ids.SAVE_FEEDBACK_BUTTON_POPUP and selected_rows: @@ -107,8 +111,8 @@ def render(app: Dash, data: pd.DataFrame) -> html.Div: @app.callback( Output("feedback-category-label", "children"), - Input(ids.CATEGORY_TABLE, "selected_rows"), - State(ids.CATEGORY_TABLE, "data"), + Input(ids.MTBF_PAR_TABLE, "selected_rows"), + State(ids.MTBF_PAR_TABLE, "data"), prevent_initial_call=True ) def update_feedback_air_label(selected_rows, data): diff --git a/src/components/ids.py b/src/components/ids.py index 2bdc314..c9e2e0a 100644 --- a/src/components/ids.py +++ b/src/components/ids.py @@ -11,7 +11,7 @@ SELECT_ALL_YEARS_BUTTON = "select-all-years-button" WEEK_DROPDOWN = "week-dropdown" SELECT_ALL_WEEKS_BUTTON = "select-all-weeks-button" -CATEGORY_TABLE = "category-table" +MTBF_PAR_TABLE = "mtbf-par-table" FEEDBACK_INPUT = "feedback-input" FEEDBACK_MESSAGE = "feedback-message"