@@ -467,8 +467,12 @@ def _extract_features() -> Dict[str, Any]:
467467
468468 charts : List [Dict [str , Any ]] = []
469469
470+ # Exclude bug_fix from charts — bugs are tracked in the summary tiles
471+ # but are not user-facing features for graph purposes.
472+ df_feat = df [df ["category" ] != "bug_fix" ]
473+
470474 # 1: Features per month — All teams
471- monthly = df .groupby ("month" ).size ()
475+ monthly = df_feat .groupby ("month" ).size ()
472476 if not monthly .empty :
473477 labels = [str (p ) for p in monthly .index ]
474478 charts .append ({
@@ -482,7 +486,7 @@ def _extract_features() -> Dict[str, Any]:
482486 })
483487
484488 # 2: User-facing features per month — All teams
485- uf = df [ df ["is_user_facing" ] == "true" ]
489+ uf = df_feat [ df_feat ["is_user_facing" ] == "true" ]
486490 uf_monthly = uf .groupby ("month" ).size ()
487491 if not uf_monthly .empty :
488492 labels = [str (p ) for p in uf_monthly .index ]
@@ -498,12 +502,12 @@ def _extract_features() -> Dict[str, Any]:
498502 })
499503
500504 # 3: Features per month by team (stacked bar)
501- teams = sorted (df ["team" ].unique ())
505+ teams = sorted (df_feat ["team" ].unique ())
502506 if teams :
503- all_months = sorted (df ["month" ].unique ())
507+ all_months = sorted (df_feat ["month" ].unique ())
504508 series = []
505509 for team in teams :
506- tdf = df [ df ["team" ] == team ]
510+ tdf = df_feat [ df_feat ["team" ] == team ]
507511 counts = tdf .groupby ("month" ).size ().reindex (all_months , fill_value = 0 )
508512 series .append ({"name" : team , "data" : counts .tolist ()})
509513 charts .append ({
@@ -516,27 +520,27 @@ def _extract_features() -> Dict[str, Any]:
516520 "drilldown" : True ,
517521 })
518522
519- # 4: Category breakdown per month (stacked bar)
520- categories = ["feature" , "bug_fix" , " improvement" , "tech_debt" ]
521- all_months = sorted (df ["month" ].unique ())
523+ # 4: Category breakdown per month (stacked bar — excludes bug_fix )
524+ categories = ["feature" , "improvement" , "tech_debt" ]
525+ all_months = sorted (df_feat ["month" ].unique ())
522526 cat_series = []
523527 for cat in categories :
524- cdf = df [ df ["category" ] == cat ]
528+ cdf = df_feat [ df_feat ["category" ] == cat ]
525529 counts = cdf .groupby ("month" ).size ().reindex (all_months , fill_value = 0 )
526530 cat_series .append ({"name" : cat , "data" : counts .tolist ()})
527531 charts .append ({
528532 "id" : "feat-category-monthly" ,
529533 "type" : "stackedBar" ,
530534 "title" : "Feature Categories per Month" ,
531- "subtitle" : "Feature vs bug_fix vs improvement vs tech_debt" ,
535+ "subtitle" : "Feature vs improvement vs tech_debt (bug fixes excluded) " ,
532536 "x" : [str (m ) for m in all_months ],
533537 "series" : cat_series ,
534538 "drilldown" : True ,
535539 })
536540
537541 # 5: Per-team monthly line charts
538542 for team in teams :
539- tdf = df [ df ["team" ] == team ]
543+ tdf = df_feat [ df_feat ["team" ] == team ]
540544 t_monthly = tdf .groupby ("month" ).size ()
541545 if not t_monthly .empty :
542546 charts .append ({
@@ -550,8 +554,8 @@ def _extract_features() -> Dict[str, Any]:
550554 "filter" : {"team" : team },
551555 })
552556
553- # 6: Average lead time per month
554- df_lt = df [ df ["lead_time_days" ] != "" ].copy ()
557+ # 6: Average lead time per month (features only, no bug fixes)
558+ df_lt = df_feat [ df_feat ["lead_time_days" ] != "" ].copy ()
555559 df_lt ["lead_time_days" ] = pd .to_numeric (df_lt ["lead_time_days" ], errors = "coerce" )
556560 df_lt = df_lt .dropna (subset = ["lead_time_days" ])
557561 if not df_lt .empty :
0 commit comments