Compare commits
	
		
			2 Commits
		
	
	
		
			7cbf75d6a8
			...
			db30fa9b4e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| db30fa9b4e | |||
| 814f88932d | 
| @ -2,3 +2,4 @@ timestamp,category,comment | |||||||
| 2025-09-11 05:15:04,dashboard_table,"AIR: P853275 - most smaller issues related to this air should be eliminated" | 2025-09-11 05:15:04,dashboard_table,"AIR: P853275 - most smaller issues related to this air should be eliminated" | ||||||
| 2025-09-11 05:15:52,source_table,"SO: 53013308 - this should be erraddicated" | 2025-09-11 05:15:52,source_table,"SO: 53013308 - this should be erraddicated" | ||||||
| 2025-09-11 05:37:58,dashboard_table,"AIR: P892467 - ABZT: need some more explanation" | 2025-09-11 05:37:58,dashboard_table,"AIR: P892467 - ABZT: need some more explanation" | ||||||
|  | 2025-09-13 09:38:40,source_table,"SO: None - tralalal" | ||||||
|  | |||||||
| 
 | 
| @ -2,10 +2,12 @@ import pandas as pd | |||||||
| import plotly.express as px | import plotly.express as px | ||||||
| from dash import Dash, dcc, html | from dash import Dash, dcc, html | ||||||
| from dash.dependencies import Input, Output | from dash.dependencies import Input, Output | ||||||
|  | import dash_bootstrap_components as dbc | ||||||
|  |  | ||||||
| from ..data.loader_gz import MTBFSchema | from ..data.loader_gz import MTBFSchema | ||||||
| from . import ids | from . import ids | ||||||
|  |  | ||||||
|  |  | ||||||
| def render(app: Dash, data: pd.DataFrame) -> html.Div: | def render(app: Dash, data: pd.DataFrame) -> html.Div: | ||||||
|     @app.callback( |     @app.callback( | ||||||
|         Output(ids.BAR_CHART, "children"), |         Output(ids.BAR_CHART, "children"), | ||||||
| @ -17,32 +19,33 @@ def render(app: Dash, data: pd.DataFrame) -> html.Div: | |||||||
|         ], |         ], | ||||||
|     ) |     ) | ||||||
|     def update_bar_chart( |     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: |     ) -> html.Div: | ||||||
|         filtered_data = data.query( |         filtered_data = data.query("year in @years and week in @weeks") | ||||||
|             "year in @years and week in @weeks" |  | ||||||
|         ) |  | ||||||
|         if filtered_data.shape[0] == 0: |         if filtered_data.shape[0] == 0: | ||||||
|             return html.Div("No data selected.") |             return html.Div("No data selected.") | ||||||
|  |  | ||||||
|         if hits_type == "p-hits": |         hits_col = MTBFSchema.U_HITS if u_hits else MTBFSchema.P_HITS | ||||||
|             hits_col = MTBFSchema.P_HITS |         hits_type = "U-Hits" if u_hits else "P-Hits" | ||||||
|         else: |  | ||||||
|             hits_col = MTBFSchema.U_HITS |  | ||||||
|  |  | ||||||
|         # Count 'Y' values and create pareto |         # Count 'Y' values and create pareto | ||||||
|         pareto_data = filtered_data[filtered_data[hits_col] == 'Y'].groupby(MTBFSchema.AIR).size().reset_index(name='count') |         pareto_data = ( | ||||||
|  |             filtered_data[filtered_data[hits_col] == "Y"] | ||||||
|  |             .groupby(MTBFSchema.AIR) | ||||||
|  |             .size() | ||||||
|  |             .reset_index(name="count") | ||||||
|  |         ) | ||||||
|  |  | ||||||
|         if 'remove_single' in single_hitter_filter: |         if remove_single: | ||||||
|             pareto_data = pareto_data[pareto_data['count'] > 1] |             pareto_data = pareto_data[pareto_data["count"] > 1] | ||||||
|  |  | ||||||
|         pareto_data = pareto_data.sort_values('count', ascending=False) |         pareto_data = pareto_data.sort_values("count", ascending=False) | ||||||
|  |  | ||||||
|         fig = px.bar( |         fig = px.bar( | ||||||
|             pareto_data, |             pareto_data, | ||||||
|             x=MTBFSchema.AIR, |             x=MTBFSchema.AIR, | ||||||
|             y="count", |             y="count", | ||||||
|             title=f"{hits_type.capitalize()} per AIR (Pareto)", |             title=f"{hits_type} per AIR (Pareto)", | ||||||
|             labels={ |             labels={ | ||||||
|                 MTBFSchema.AIR: "AIR", |                 MTBFSchema.AIR: "AIR", | ||||||
|                 "count": "Count", |                 "count": "Count", | ||||||
| @ -52,20 +55,15 @@ def render(app: Dash, data: pd.DataFrame) -> html.Div: | |||||||
|  |  | ||||||
|     return html.Div( |     return html.Div( | ||||||
|         children=[ |         children=[ | ||||||
|             dcc.RadioItems( |             dbc.Switch( | ||||||
|                 id=ids.PU_HITS_SELECTOR, |                 id=ids.PU_HITS_SELECTOR, | ||||||
|                 options=[ |                 label="P-Hits / U-Hits", | ||||||
|                     {'label': 'P-Hits', 'value': 'p-hits'}, |                 value=False, | ||||||
|                     {'label': 'U-Hits', 'value': 'u-hits'}, |  | ||||||
|                 ], |  | ||||||
|                 value='p-hits', |  | ||||||
|                 labelStyle={'display': 'inline-block'} |  | ||||||
|             ), |             ), | ||||||
|             dcc.Checklist( |             dbc.Switch( | ||||||
|                 id=ids.SINGLE_HITTER_FILTER, |                 id=ids.SINGLE_HITTER_FILTER, | ||||||
|                 options=[{'label': 'Remove single hitters', 'value': 'remove_single'}], |                 label="Remove single hitters", | ||||||
|                 value=[], |                 value=False, | ||||||
|                 labelStyle={'display': 'inline-block'} |  | ||||||
|             ), |             ), | ||||||
|             html.Div(id=ids.BAR_CHART), |             html.Div(id=ids.BAR_CHART), | ||||||
|         ] |         ] | ||||||
|  | |||||||
| @ -7,6 +7,15 @@ import dash_bootstrap_components as dbc | |||||||
| from ..data.loader_gz import MTBFSchema | from ..data.loader_gz import MTBFSchema | ||||||
| from . import ids | 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: | def render(app: Dash, data: pd.DataFrame) -> html.Div: | ||||||
|     @app.callback( |     @app.callback( | ||||||
|         Output(ids.DATA_TABLE, "children"), |         Output(ids.DATA_TABLE, "children"), | ||||||
| @ -18,7 +27,7 @@ def render(app: Dash, data: pd.DataFrame) -> html.Div: | |||||||
|         ], |         ], | ||||||
|     ) |     ) | ||||||
|     def update_data_table( |     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: |     ) -> html.Div: | ||||||
|         filtered_data = data.query( |         filtered_data = data.query( | ||||||
|             "year in @years and week in @weeks" |             "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: |         if filtered_data.shape[0] == 0: | ||||||
|             return html.Div("No data selected.") |             return html.Div("No data selected.") | ||||||
|  |  | ||||||
|         if hits_type == "p-hits": |         hits_col = MTBFSchema.U_HITS if u_hits else MTBFSchema.P_HITS | ||||||
|             hits_col = MTBFSchema.P_HITS |  | ||||||
|         else: |  | ||||||
|             hits_col = MTBFSchema.U_HITS |  | ||||||
|  |  | ||||||
|         # Count 'Y' values |         # Count 'Y' values | ||||||
|         hits_data = filtered_data[filtered_data[hits_col] == 'Y'] |         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())) |             close_notes=(MTBFSchema.CLOSE_NOTES, lambda x: ', '.join(x.dropna().astype(str).unique())) | ||||||
|         ).reset_index() |         ).reset_index() | ||||||
|  |  | ||||||
|         if 'remove_single' in single_hitter_filter: |         if remove_single: | ||||||
|             table_data = table_data[table_data['count'] > 1] |             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) |         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']] |         table_data = table_data[[MTBFSchema.AIR, 'air_issue_description', 'close_notes', 'count']] | ||||||
|  |  | ||||||
|         return dash_table.DataTable( |         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"), |             data=table_data.to_dict("records"), | ||||||
|             columns=[{"name": i, "id": i} for i in table_data.columns], |             columns=[{"name": i, "id": i} for i in table_data.columns], | ||||||
|             page_size=10, |             page_size=10, | ||||||
| @ -64,11 +68,11 @@ def render(app: Dash, data: pd.DataFrame) -> html.Div: | |||||||
|     @app.callback( |     @app.callback( | ||||||
|         Output(ids.FEEDBACK_MODAL, "is_open"), |         Output(ids.FEEDBACK_MODAL, "is_open"), | ||||||
|         Output(ids.FEEDBACK_MESSAGE, "children"), |         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.SAVE_FEEDBACK_BUTTON_POPUP, "n_clicks"), | ||||||
|         Input(ids.CLOSE_FEEDBACK_BUTTON_POPUP, "n_clicks"), |         Input(ids.CLOSE_FEEDBACK_BUTTON_POPUP, "n_clicks"), | ||||||
|         State(ids.FEEDBACK_MODAL, "is_open"), |         State(ids.FEEDBACK_MODAL, "is_open"), | ||||||
|         State(ids.CATEGORY_TABLE, "data"), |         State(ids.MTBF_PAR_TABLE, "data"), | ||||||
|         State(ids.FEEDBACK_INPUT, "value"), |         State(ids.FEEDBACK_INPUT, "value"), | ||||||
|     ) |     ) | ||||||
|     def handle_feedback_modal(selected_rows, save_clicks, close_clicks, is_open, table_data, comment): |     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] |         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, "" |             return True, "" | ||||||
|  |  | ||||||
|         if triggered_id == ids.SAVE_FEEDBACK_BUTTON_POPUP and selected_rows: |         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( |     @app.callback( | ||||||
|         Output("feedback-category-label", "children"), |         Output("feedback-category-label", "children"), | ||||||
|         Input(ids.CATEGORY_TABLE, "selected_rows"), |         Input(ids.MTBF_PAR_TABLE, "selected_rows"), | ||||||
|         State(ids.CATEGORY_TABLE, "data"), |         State(ids.MTBF_PAR_TABLE, "data"), | ||||||
|         prevent_initial_call=True |         prevent_initial_call=True | ||||||
|     ) |     ) | ||||||
|     def update_feedback_air_label(selected_rows, data): |     def update_feedback_air_label(selected_rows, data): | ||||||
|  | |||||||
| @ -11,7 +11,7 @@ SELECT_ALL_YEARS_BUTTON = "select-all-years-button" | |||||||
| WEEK_DROPDOWN = "week-dropdown" | WEEK_DROPDOWN = "week-dropdown" | ||||||
| SELECT_ALL_WEEKS_BUTTON = "select-all-weeks-button" | SELECT_ALL_WEEKS_BUTTON = "select-all-weeks-button" | ||||||
|  |  | ||||||
| CATEGORY_TABLE = "category-table" | MTBF_PAR_TABLE = "mtbf-par-table" | ||||||
|  |  | ||||||
| FEEDBACK_INPUT = "feedback-input" | FEEDBACK_INPUT = "feedback-input" | ||||||
| FEEDBACK_MESSAGE = "feedback-message" | FEEDBACK_MESSAGE = "feedback-message" | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user