diff --git a/IMPLEMENTATION_PLAN.md b/IMPLEMENTATION_PLAN.md index 2eb4771..b66a5fc 100644 --- a/IMPLEMENTATION_PLAN.md +++ b/IMPLEMENTATION_PLAN.md @@ -1,673 +1,260 @@ -# Implementation Plan — Reflex → Dash Migration +# Implementation Plan — Dashboard Visualization Improvements ## Project Overview -Migrate the Reflex web application to Dash (Plotly) + Dash Mantine Components. The backend (`src/`) is untouched — only the frontend changes. +Comprehensive review and improvement of all Plotly charts in the Dash dashboard. Four tiers: bug fixes, visual polish, new analytics from existing data, and new analytics requiring backend work. + +**Primary file**: `src/visualization/plotly_generator.py` +**Palette policy**: Broader than NHS brand (maximally-distinct colors for trust comparisons) +**Constraint**: `python run_dash.py` must work after every task ### What Changes -- `pathways_app/` (Reflex) → `dash_app/` (Dash + DMC) -- `run_dash.py` entry point replaces `reflex run` -- CSS extracted from `01_nhs_classic.html` → `dash_app/assets/nhs.css` -- Drug/Directory/Indication filters consolidated into a right-side `dmc.Drawer` +- `src/visualization/plotly_generator.py` — shared styling constants, bug fixes, new chart functions +- `src/data_processing/pathway_queries.py` — new query functions for Tier 3 analytics +- `dash_app/data/queries.py` — thin wrappers for new queries +- `dash_app/callbacks/chart.py` — heatmap metric toggle, new tab support +- `dash_app/callbacks/trust_comparison.py` — trust color palette, heatmap metric toggle +- `dash_app/components/chart_card.py` — new tab definitions, metric toggle component +- `dash_app/components/trust_comparison.py` — metric toggle component -### What Stays (DO NOT MODIFY pipeline/analysis logic) -- `data_processing/pathway_pipeline.py`, `transforms.py`, `diagnosis_lookup.py` (matching logic) -- `analysis/pathway_analyzer.py`, `statistics.py` -- `cli/refresh_pathways.py` -- `data_processing/schema.py`, `reference_data.py`, `cache.py`, `data_source.py` -- SQLite schema and `pathway_nodes` table -- `data/` reference files (CSVs, pathways.db) - -### What CAN be edited in `src/` (shared utilities) -- `visualization/plotly_generator.py` — add/refactor a function to accept list-of-dicts (what Dash produces) instead of only DataFrames -- `data_processing/database.py` — add shared query functions for pathway node loading so both Reflex and Dash use the same queries -- `core/config.py` — if path resolution needs adjusting - -### Dash App Structure -``` -dash_app/ -├── __init__.py -├── app.py # Entry point, layout root, dcc.Store components -├── assets/ -│ └── nhs.css # Extracted from 01_nhs_classic.html -├── data/ -│ ├── queries.py # SQLite queries (extracted from Reflex AppState) -│ └── card_browser.py # DimSearchTerm.csv → directorate tree -├── components/ -│ ├── header.py # Top header bar -│ ├── sidebar.py # Left navigation -│ ├── kpi_row.py # 4 KPI cards -│ ├── filter_bar.py # Chart type toggle + date dropdowns -│ ├── chart_card.py # Chart area with tabs + dcc.Graph -│ ├── drawer.py # dmc.Drawer with card browser -│ └── footer.py # Page footer -├── callbacks/ -│ ├── __init__.py # register_callbacks(app) -│ ├── filters.py # Date/chart-type → app-state store -│ ├── chart.py # chart-data → go.Icicle figure -│ ├── drawer.py # Drawer open/close + drug selection -│ └── kpi.py # chart-data → KPI card values -└── utils/ - └── formatting.py # Cost/patient display formatters -``` - -### State Management (3 dcc.Store components) -- **app-state** (session): `chart_type`, `initiated`, `last_seen`, `selected_drugs`, `selected_directorates`, `date_filter_id` -- **chart-data** (memory): `nodes[]`, `unique_patients`, `total_drugs`, `total_cost` -- **reference-data** (session): `available_drugs`, `directorate_tree` (loaded once) - -### Callback Chain -``` -Page Load → load_reference_data → reference-data store - → load_pathway_data → chart-data store - ├→ update_kpis → KPI cards - └→ update_chart → dcc.Graph - -Filter change → update_app_state → app-state store → load_pathway_data → (chain above) - -Drawer selection → update_drug_selection → app-state store → load_pathway_data → (chain above) -``` - -### Directorate Card Browser (dmc.Drawer) -- Position: right, ~480px wide -- **Top card**: "All Drugs" — flat list from `pathway_nodes` level 3. Pick one drug → see it across all directorates/indications. -- **Below**: Cards per PrimaryDirectorate (from DimSearchTerm.csv). Each has `dmc.Accordion` with indication items → drug chips inside. -- **Clear Filters** button resets all selections. -- Data model: `DimSearchTerm.csv` grouped by PrimaryDirectorate → Search_Term → CleanedDrugName +### What Stays (DO NOT MODIFY) +- Pipeline/analysis logic: `pathway_pipeline.py`, `transforms.py`, `diagnosis_lookup.py`, `pathway_analyzer.py` +- Database schema and `pathway_nodes` table +- CLI refresh command +- Existing callback chain architecture (app-state → chart-data → UI) +- Two-view architecture (Patient Pathways + Trust Comparison) --- -## Phase 0: Project Scaffolding +## Phase A: Core Fixes + Shared Constants -### 0.1 Create dash_app/ skeleton + update pyproject.toml -- [x] Create `dash_app/` directory with `__init__.py`, `app.py`, subdirectories (`assets/`, `data/`, `components/`, `callbacks/`, `utils/`) -- [x] Create `run_dash.py` at project root (simple `from dash_app.app import app; app.run(debug=True, port=8050)`) -- [x] Update `pyproject.toml`: add `dash>=2.14.0`, `dash-mantine-components>=0.14.0` to dependencies (keep `reflex` temporarily) -- [x] Create minimal `app.py` with `dash.Dash(__name__)`, DMC provider wrapper, and "Hello Dash" placeholder layout -- **Checkpoint**: `python run_dash.py` starts, shows "Hello Dash" at localhost:8050 ✓ +### A.1 Extract shared styling constants + `_base_layout()` helper +- [ ] Add module-level constants to top of `src/visualization/plotly_generator.py`: + ```python + CHART_FONT_FAMILY = "Source Sans 3, system-ui, sans-serif" + CHART_TITLE_SIZE = 18 + CHART_TITLE_COLOR = "#1E293B" + GRID_COLOR = "#E2E8F0" + ANNOTATION_COLOR = "#768692" -### 0.2 Extract CSS from 01_nhs_classic.html into dash_app/assets/nhs.css -- [x] Copy the `