feat: header fraction KPIs replacing KPI row (Task 10.3)
Remove KPI card row, add 3 inline fraction KPIs to header bar: filtered/total patients, drugs, cost. Breadcrumb removed. KPI callback refactored for 6 output IDs (3 filtered + 3 total). total_cost added to load_initial_data() reference data.
This commit is contained in:
+41
-22
@@ -1,4 +1,4 @@
|
||||
"""Callback for updating KPI card values from chart-data store."""
|
||||
"""Callback for updating fraction KPI values in the header bar."""
|
||||
from dash import Input, Output, no_update
|
||||
|
||||
|
||||
@@ -12,30 +12,49 @@ def _format_cost(cost):
|
||||
|
||||
|
||||
def register_kpi_callbacks(app):
|
||||
"""Register KPI update callback."""
|
||||
"""Register header KPI update callbacks."""
|
||||
|
||||
@app.callback(
|
||||
Output("kpi-patients", "children"),
|
||||
Output("kpi-drugs", "children"),
|
||||
Output("kpi-cost", "children"),
|
||||
Output("kpi-match", "children"),
|
||||
# Filtered values (numerators)
|
||||
Output("kpi-filtered-patients", "children"),
|
||||
Output("kpi-filtered-drugs", "children"),
|
||||
Output("kpi-filtered-cost", "children"),
|
||||
# Total values (denominators)
|
||||
Output("kpi-total-patients", "children"),
|
||||
Output("kpi-total-drugs", "children"),
|
||||
Output("kpi-total-cost", "children"),
|
||||
Input("chart-data", "data"),
|
||||
Input("app-state", "data"),
|
||||
Input("reference-data", "data"),
|
||||
)
|
||||
def update_kpis(chart_data, app_state):
|
||||
"""Update KPI card values when chart-data changes."""
|
||||
if not chart_data:
|
||||
return no_update, no_update, no_update, no_update
|
||||
def update_header_kpis(chart_data, ref_data):
|
||||
"""Update header fraction KPIs from chart-data (filtered) and reference-data (totals)."""
|
||||
# Filtered values from chart-data
|
||||
if chart_data:
|
||||
patients = chart_data.get("unique_patients", 0)
|
||||
drugs = chart_data.get("total_drugs", 0)
|
||||
cost = chart_data.get("total_cost", 0.0)
|
||||
filtered_patients = f"{patients:,}" if patients else "\u2014"
|
||||
filtered_drugs = str(drugs) if drugs else "\u2014"
|
||||
filtered_cost = _format_cost(cost) if cost else "\u2014"
|
||||
else:
|
||||
filtered_patients = "\u2014"
|
||||
filtered_drugs = "\u2014"
|
||||
filtered_cost = "\u2014"
|
||||
|
||||
patients = chart_data.get("unique_patients", 0)
|
||||
drugs = chart_data.get("total_drugs", 0)
|
||||
cost = chart_data.get("total_cost", 0.0)
|
||||
# Total values from reference-data
|
||||
if ref_data:
|
||||
total_patients_val = ref_data.get("total_patients", 0)
|
||||
total_drugs_val = len(ref_data.get("available_drugs", []))
|
||||
total_cost_val = ref_data.get("total_cost", 0.0)
|
||||
total_patients = f"{total_patients_val:,}" if total_patients_val else "\u2014"
|
||||
total_drugs = str(total_drugs_val) if total_drugs_val else "\u2014"
|
||||
total_cost = _format_cost(total_cost_val) if total_cost_val else "\u2014"
|
||||
else:
|
||||
total_patients = "\u2014"
|
||||
total_drugs = "\u2014"
|
||||
total_cost = "\u2014"
|
||||
|
||||
patients_str = f"{patients:,}" if patients else "\u2014"
|
||||
drugs_str = str(drugs) if drugs else "\u2014"
|
||||
cost_str = _format_cost(cost) if cost else "\u2014"
|
||||
|
||||
chart_type = (app_state or {}).get("chart_type", "directory")
|
||||
match_str = "~93%" if chart_type == "indication" else "\u2014"
|
||||
|
||||
return patients_str, drugs_str, cost_str, match_str
|
||||
return (
|
||||
filtered_patients, filtered_drugs, filtered_cost,
|
||||
total_patients, total_drugs, total_cost,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user