fix: consistent titles via _base_layout() for Sankey, Cost Effectiveness, Duration (Task B.1)
This commit is contained in:
@@ -91,12 +91,13 @@ Comprehensive review and improvement of all Plotly charts in the Dash dashboard.
|
|||||||
## Phase B: Visual Polish
|
## Phase B: Visual Polish
|
||||||
|
|
||||||
### B.1 Fix title inconsistencies across all charts
|
### B.1 Fix title inconsistencies across all charts
|
||||||
- [ ] Sankey (~L817): title color `"#003087"` → `CHART_TITLE_COLOR`
|
- [x] Sankey: replaced local nhs_colours with DRUG_PALETTE, title color `"#003087"` → `CHART_TITLE_COLOR` via `_base_layout()`
|
||||||
- [ ] Dosing (~L885): title color `"#003087"` → `CHART_TITLE_COLOR`
|
- [x] Dosing: already converted in A.3 — uses `_base_layout()` with CHART_TITLE_COLOR
|
||||||
- [ ] Patient Pathways heatmap (~L1300): title color `"#003087"` → `CHART_TITLE_COLOR`
|
- [x] Patient Pathways heatmap: already converted in A.2 — uses `_base_layout()` with CHART_TITLE_COLOR
|
||||||
- [ ] Duration (~L1449): title color `"#003087"` → `CHART_TITLE_COLOR`
|
- [x] Duration: title color `"#003087"` → `CHART_TITLE_COLOR`, fixed l=200→l=8+automargin, used constants for annotations
|
||||||
- [ ] All Trust Comparison functions: title `size=16` → `CHART_TITLE_SIZE` (18)
|
- [x] All Trust Comparison functions: already use `_base_layout()` (A.2-A.4), title size=18 via CHART_TITLE_SIZE
|
||||||
- [ ] Apply `_base_layout()` to all remaining chart functions not yet converted
|
- [x] Applied `_base_layout()` to all remaining chart functions: Sankey, Cost Effectiveness, Duration
|
||||||
|
- [x] Cost Effectiveness: replaced 38-line manual layout with `_base_layout()`, hardcoded colors/fonts → constants
|
||||||
- **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
|
||||||
|
|||||||
@@ -579,26 +579,17 @@ def create_cost_effectiveness_figure(
|
|||||||
showarrow=False,
|
showarrow=False,
|
||||||
xanchor="left",
|
xanchor="left",
|
||||||
xshift=10,
|
xshift=10,
|
||||||
font=dict(size=10, color="#768692", family="Source Sans 3"),
|
font=dict(size=10, color=ANNOTATION_COLOR, family=CHART_FONT_FAMILY),
|
||||||
)
|
)
|
||||||
annotation_count += 1
|
annotation_count += 1
|
||||||
|
|
||||||
fig.update_layout(
|
layout = _base_layout(display_title)
|
||||||
title=dict(
|
layout.update(
|
||||||
text=display_title,
|
|
||||||
font=dict(
|
|
||||||
family="Source Sans 3, system-ui, sans-serif",
|
|
||||||
size=18,
|
|
||||||
color="#1E293B",
|
|
||||||
),
|
|
||||||
x=0.5,
|
|
||||||
xanchor="center",
|
|
||||||
),
|
|
||||||
xaxis=dict(
|
xaxis=dict(
|
||||||
title="£ per patient per annum",
|
title="£ per patient per annum",
|
||||||
tickprefix="£",
|
tickprefix="£",
|
||||||
tickformat=",",
|
tickformat=",",
|
||||||
gridcolor="#E2E8F0",
|
gridcolor=GRID_COLOR,
|
||||||
zeroline=True,
|
zeroline=True,
|
||||||
zerolinecolor="#CBD5E1",
|
zerolinecolor="#CBD5E1",
|
||||||
),
|
),
|
||||||
@@ -608,23 +599,9 @@ def create_cost_effectiveness_figure(
|
|||||||
tickfont=dict(size=11),
|
tickfont=dict(size=11),
|
||||||
),
|
),
|
||||||
margin=dict(t=50, l=8, r=24, b=40),
|
margin=dict(t=50, l=8, r=24, b=40),
|
||||||
paper_bgcolor="rgba(0,0,0,0)",
|
|
||||||
plot_bgcolor="rgba(0,0,0,0)",
|
|
||||||
autosize=True,
|
|
||||||
hoverlabel=dict(
|
|
||||||
bgcolor="#FFFFFF",
|
|
||||||
bordercolor="#CBD5E1",
|
|
||||||
font=dict(
|
|
||||||
family="Source Sans 3, system-ui, sans-serif",
|
|
||||||
size=13,
|
|
||||||
color="#1E293B",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
font=dict(
|
|
||||||
family="Source Sans 3, system-ui, sans-serif",
|
|
||||||
),
|
|
||||||
height=max(450, len(filtered) * 28 + 150),
|
height=max(450, len(filtered) * 28 + 150),
|
||||||
)
|
)
|
||||||
|
fig.update_layout(**layout)
|
||||||
|
|
||||||
return fig
|
return fig
|
||||||
|
|
||||||
@@ -767,13 +744,6 @@ def create_sankey_figure(
|
|||||||
if not nodes or not links:
|
if not nodes or not links:
|
||||||
return go.Figure()
|
return go.Figure()
|
||||||
|
|
||||||
# NHS colour palette — one colour per unique base drug name
|
|
||||||
nhs_colours = [
|
|
||||||
"#005EB8", "#003087", "#41B6E6", "#0066CC", "#1E88E5",
|
|
||||||
"#4FC3F7", "#009639", "#ED8B00", "#768692", "#AE2573",
|
|
||||||
"#8A1538", "#330072", "#DA291C", "#00A499", "#425563",
|
|
||||||
]
|
|
||||||
|
|
||||||
# Extract base drug name (strip ordinal suffix) for colour consistency
|
# Extract base drug name (strip ordinal suffix) for colour consistency
|
||||||
def base_drug(name: str) -> str:
|
def base_drug(name: str) -> str:
|
||||||
return re.sub(r"\s*\(\d+(?:st|nd|rd|th)\)\s*$", "", name)
|
return re.sub(r"\s*\(\d+(?:st|nd|rd|th)\)\s*$", "", name)
|
||||||
@@ -783,7 +753,7 @@ def create_sankey_figure(
|
|||||||
b = base_drug(n["name"])
|
b = base_drug(n["name"])
|
||||||
if b not in unique_bases:
|
if b not in unique_bases:
|
||||||
unique_bases.append(b)
|
unique_bases.append(b)
|
||||||
base_colour_map = {b: nhs_colours[i % len(nhs_colours)] for i, b in enumerate(unique_bases)}
|
base_colour_map = {b: DRUG_PALETTE[i % len(DRUG_PALETTE)] for i, b in enumerate(unique_bases)}
|
||||||
|
|
||||||
# Node colours — same drug gets same colour regardless of treatment line
|
# Node colours — same drug gets same colour regardless of treatment line
|
||||||
node_colours = [base_colour_map[base_drug(n["name"])] for n in nodes]
|
node_colours = [base_colour_map[base_drug(n["name"])] for n in nodes]
|
||||||
@@ -851,26 +821,13 @@ def create_sankey_figure(
|
|||||||
if title:
|
if title:
|
||||||
chart_title = f"{chart_title} — {title}"
|
chart_title = f"{chart_title} — {title}"
|
||||||
|
|
||||||
fig.update_layout(
|
layout = _base_layout(chart_title)
|
||||||
title=dict(
|
layout.update(
|
||||||
text=chart_title,
|
font=dict(family=CHART_FONT_FAMILY, size=12),
|
||||||
font=dict(
|
|
||||||
family="Source Sans 3, system-ui, sans-serif",
|
|
||||||
size=18,
|
|
||||||
color="#003087",
|
|
||||||
),
|
|
||||||
x=0.5,
|
|
||||||
xanchor="center",
|
|
||||||
),
|
|
||||||
font=dict(
|
|
||||||
family="Source Sans 3, system-ui, sans-serif",
|
|
||||||
size=12,
|
|
||||||
),
|
|
||||||
paper_bgcolor="rgba(0,0,0,0)",
|
|
||||||
plot_bgcolor="rgba(0,0,0,0)",
|
|
||||||
margin=dict(t=60, l=30, r=30, b=30),
|
margin=dict(t=60, l=30, r=30, b=30),
|
||||||
height=max(500, len(unique_bases) * 35 + 200),
|
height=max(500, len(unique_bases) * 35 + 200),
|
||||||
)
|
)
|
||||||
|
fig.update_layout(**layout)
|
||||||
|
|
||||||
return fig
|
return fig
|
||||||
|
|
||||||
@@ -1453,27 +1410,18 @@ def create_duration_figure(
|
|||||||
text=f"n={pts:,}",
|
text=f"n={pts:,}",
|
||||||
showarrow=False,
|
showarrow=False,
|
||||||
xshift=45,
|
xshift=45,
|
||||||
font=dict(size=9, color="#768692", family="Source Sans 3"),
|
font=dict(size=9, color=ANNOTATION_COLOR, family=CHART_FONT_FAMILY),
|
||||||
)
|
)
|
||||||
|
|
||||||
chart_title = "Treatment Duration by Drug"
|
chart_title = "Treatment Duration by Drug"
|
||||||
if title:
|
if title:
|
||||||
chart_title += f"<br><span style='font-size:13px;color:#768692'>{title}</span>"
|
chart_title += f"<br><span style='font-size:13px;color:{ANNOTATION_COLOR}'>{title}</span>"
|
||||||
|
|
||||||
n_bars = len(data)
|
n_bars = len(data)
|
||||||
fig_height = max(400, 40 + n_bars * 28)
|
fig_height = max(400, 40 + n_bars * 28)
|
||||||
|
|
||||||
fig.update_layout(
|
layout = _base_layout(chart_title)
|
||||||
title=dict(
|
layout.update(
|
||||||
text=chart_title,
|
|
||||||
font=dict(
|
|
||||||
family="Source Sans 3, system-ui, sans-serif",
|
|
||||||
size=18,
|
|
||||||
color="#003087",
|
|
||||||
),
|
|
||||||
x=0.5,
|
|
||||||
xanchor="center",
|
|
||||||
),
|
|
||||||
xaxis=dict(
|
xaxis=dict(
|
||||||
title="Average Duration (days)",
|
title="Average Duration (days)",
|
||||||
titlefont=dict(size=13, color="#425563"),
|
titlefont=dict(size=13, color="#425563"),
|
||||||
@@ -1485,15 +1433,14 @@ def create_duration_figure(
|
|||||||
yaxis=dict(
|
yaxis=dict(
|
||||||
title="",
|
title="",
|
||||||
tickfont=dict(size=11, color="#425563"),
|
tickfont=dict(size=11, color="#425563"),
|
||||||
|
automargin=True,
|
||||||
autorange="reversed",
|
autorange="reversed",
|
||||||
),
|
),
|
||||||
plot_bgcolor="rgba(0,0,0,0)",
|
margin=dict(t=60, l=8, r=80, b=50),
|
||||||
paper_bgcolor="rgba(0,0,0,0)",
|
|
||||||
font=dict(family="Source Sans 3, system-ui, sans-serif"),
|
|
||||||
margin=dict(t=60, l=200, r=80, b=50),
|
|
||||||
height=fig_height,
|
height=fig_height,
|
||||||
showlegend=False,
|
showlegend=False,
|
||||||
)
|
)
|
||||||
|
fig.update_layout(**layout)
|
||||||
|
|
||||||
return fig
|
return fig
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user