fix: smooth green→amber→red gradient for cost effectiveness chart (Task B.2)

This commit is contained in:
Andrew Charlwood
2026-02-07 02:57:16 +00:00
parent 8035762005
commit cbac37ea6b
2 changed files with 20 additions and 11 deletions
+3 -3
View File
@@ -101,11 +101,11 @@ Comprehensive review and improvement of all Plotly charts in the Dash dashboard.
- **Checkpoint**: All chart titles use consistent font, size, and color
### B.2 Cost effectiveness smooth gradient
- [ ] In `create_cost_effectiveness_figure()` (~L428-435):
- Replace 3-bin hard threshold (green/amber/red) with smooth RGB interpolation
- [x] In `create_cost_effectiveness_figure()`:
- Replaced 3-bin hard threshold with smooth `_lerp_color()` RGB interpolation
- Green (#009639) → Amber (#ED8B00) for ratio 00.5
- Amber (#ED8B00) → Red (#DA291C) for ratio 0.51.0
- [ ] Apply `_base_layout()` to the function
- [x] `_base_layout()` already applied in B.1
- **Checkpoint**: Lollipop dots show smooth green→amber→red gradient
### B.3 Sankey narrow-screen fix
+17 -8
View File
@@ -494,15 +494,24 @@ def create_cost_effectiveness_figure(
min_cost = min(costs) if costs else 0
cost_range = max_cost - min_cost if max_cost != min_cost else 1
colours = []
for c in costs:
ratio = (c - min_cost) / cost_range
if ratio < 0.33:
colours.append("#009639") # NHS green
elif ratio < 0.66:
colours.append("#ED8B00") # NHS warm yellow
def _lerp_color(ratio: float) -> str:
"""Smooth green→amber→red gradient via linear RGB interpolation."""
green = (0x00, 0x96, 0x39)
amber = (0xED, 0x8B, 0x00)
red = (0xDA, 0x29, 0x1C)
ratio = max(0.0, min(1.0, ratio))
if ratio <= 0.5:
t = ratio / 0.5
c1, c2 = green, amber
else:
colours.append("#DA291C") # NHS red
t = (ratio - 0.5) / 0.5
c1, c2 = amber, red
r = int(c1[0] + (c2[0] - c1[0]) * t)
g = int(c1[1] + (c2[1] - c1[1]) * t)
b = int(c1[2] + (c2[2] - c1[2]) * t)
return f"rgb({r},{g},{b})"
colours = [_lerp_color((c - min_cost) / cost_range) for c in costs]
# Dot size scaled by patient count (min 8, max 30)
max_pts = max(patients) if patients else 1