fix: smooth green→amber→red gradient for cost effectiveness chart (Task B.2)
This commit is contained in:
@@ -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
|
- **Checkpoint**: All chart titles use consistent font, size, and color
|
||||||
|
|
||||||
### B.2 Cost effectiveness smooth gradient
|
### B.2 Cost effectiveness smooth gradient
|
||||||
- [ ] In `create_cost_effectiveness_figure()` (~L428-435):
|
- [x] In `create_cost_effectiveness_figure()`:
|
||||||
- Replace 3-bin hard threshold (green/amber/red) with smooth RGB interpolation
|
- Replaced 3-bin hard threshold with smooth `_lerp_color()` RGB interpolation
|
||||||
- Green (#009639) → Amber (#ED8B00) for ratio 0–0.5
|
- Green (#009639) → Amber (#ED8B00) for ratio 0–0.5
|
||||||
- Amber (#ED8B00) → Red (#DA291C) for ratio 0.5–1.0
|
- Amber (#ED8B00) → Red (#DA291C) for ratio 0.5–1.0
|
||||||
- [ ] Apply `_base_layout()` to the function
|
- [x] `_base_layout()` already applied in B.1
|
||||||
- **Checkpoint**: Lollipop dots show smooth green→amber→red gradient
|
- **Checkpoint**: Lollipop dots show smooth green→amber→red gradient
|
||||||
|
|
||||||
### B.3 Sankey narrow-screen fix
|
### B.3 Sankey narrow-screen fix
|
||||||
|
|||||||
@@ -494,15 +494,24 @@ def create_cost_effectiveness_figure(
|
|||||||
min_cost = min(costs) if costs else 0
|
min_cost = min(costs) if costs else 0
|
||||||
cost_range = max_cost - min_cost if max_cost != min_cost else 1
|
cost_range = max_cost - min_cost if max_cost != min_cost else 1
|
||||||
|
|
||||||
colours = []
|
def _lerp_color(ratio: float) -> str:
|
||||||
for c in costs:
|
"""Smooth green→amber→red gradient via linear RGB interpolation."""
|
||||||
ratio = (c - min_cost) / cost_range
|
green = (0x00, 0x96, 0x39)
|
||||||
if ratio < 0.33:
|
amber = (0xED, 0x8B, 0x00)
|
||||||
colours.append("#009639") # NHS green
|
red = (0xDA, 0x29, 0x1C)
|
||||||
elif ratio < 0.66:
|
ratio = max(0.0, min(1.0, ratio))
|
||||||
colours.append("#ED8B00") # NHS warm yellow
|
if ratio <= 0.5:
|
||||||
|
t = ratio / 0.5
|
||||||
|
c1, c2 = green, amber
|
||||||
else:
|
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)
|
# Dot size scaled by patient count (min 8, max 30)
|
||||||
max_pts = max(patients) if patients else 1
|
max_pts = max(patients) if patients else 1
|
||||||
|
|||||||
Reference in New Issue
Block a user