Skip to content

Commit fe45df4

Browse files
dshkolclaude
andcommitted
Fix horizontal bar chart labels across all articles
- Standardize label positioning to fixed right-edge position - Remove dynamic textAnchor and dx offsets that caused overlap - Add fontSize: 11 for consistent label sizing - Update CHART-STYLE-GUIDE with recommended approach - Fix French CPI table (NL province: "—" → "0,0 pp") Articles fixed: - airline-passengers (EN/FR) - wholesale-trade (EN/FR) - retail-trade (EN/FR) - lfs/epa (EN/FR) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 96a4148 commit fe45df4

10 files changed

Lines changed: 57 additions & 43 deletions

File tree

docs/CHART-STYLE-GUIDE.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,21 +104,27 @@ display(Plot.plot({
104104
- Sort bars by value with `sort: {y: "-x"}`
105105
- Position labels with `dx: 20` (positive values) or handle negative separately
106106

107-
### Handling Negative Value Labels
107+
### Handling Mixed Positive/Negative Labels
108108

109-
When bars can be negative, position labels dynamically:
109+
**Recommended approach:** Place ALL labels at a fixed right-edge position to avoid overlap:
110110

111111
```js
112112
Plot.text(data, {
113113
y: "name",
114-
x: d => d.change >= 0 ? domainMax : domainMin,
114+
x: domainMax, // Fixed position at right edge (e.g., 12 if domain is [-5, 12])
115115
text: d => (d.change >= 0 ? "+" : "") + d.change.toFixed(1) + "%",
116-
textAnchor: d => d.change >= 0 ? "start" : "end",
117-
dx: d => d.change >= 0 ? 5 : -5,
118-
fill: "currentColor"
116+
textAnchor: "end",
117+
fill: "currentColor",
118+
fontSize: 11
119119
})
120120
```
121121

122+
**Why this approach:**
123+
- Labels aligned at the bar end can overlap when bars have similar lengths
124+
- A fixed right-edge position keeps all labels readable and consistently positioned
125+
- Set `marginRight: 60` to ensure labels have space
126+
- Expand the x-domain slightly beyond the max value to accommodate labels
127+
122128
## Reference Lines
123129

124130
Add context with horizontal reference lines:

docs/en/airline-passengers-october-2025/index.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,22 +99,24 @@ display(Plot.plot({
9999
width: 550,
100100
height: 200,
101101
marginLeft: 150,
102-
x: {grid: true, label: "Percent change"},
102+
marginRight: 60,
103+
x: {domain: [-15, 12], grid: true, label: "Percent change"},
103104
y: {label: null},
104105
marks: [
105106
Plot.ruleX([0]),
106107
Plot.barX(trafficData, {
107108
y: "segment",
108109
x: "yoyChange",
109-
fill: d => d.yoyChange >= 0 ? "#AF3C43" : "#1f77b4",
110+
fill: d => d.yoyChange >= 0 ? "#AF3C43" : "#2e7d32",
110111
sort: {y: "-x"}
111112
}),
112113
Plot.text(trafficData, {
113114
y: "segment",
114-
x: d => d.yoyChange >= 0 ? d.yoyChange + 0.8 : d.yoyChange - 0.8,
115+
x: 12,
115116
text: d => (d.yoyChange >= 0 ? "+" : "") + d.yoyChange.toFixed(1) + "%",
116-
textAnchor: d => d.yoyChange >= 0 ? "start" : "end",
117-
fill: "currentColor"
117+
textAnchor: "end",
118+
fill: "currentColor",
119+
fontSize: 11
118120
})
119121
]
120122
}));

docs/en/lfs-november-2025/index.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,11 @@ display(Plot.plot({
176176
}),
177177
Plot.text(typeData, {
178178
y: "type",
179-
x: d => d.change >= 0 ? 70 : -20,
179+
x: 70,
180180
text: d => (d.change >= 0 ? "+" : "") + d.change.toFixed(1),
181-
textAnchor: d => d.change >= 0 ? "start" : "end",
182-
dx: d => d.change >= 0 ? 5 : -5,
183-
fill: "currentColor"
181+
textAnchor: "end",
182+
fill: "currentColor",
183+
fontSize: 11
184184
})
185185
]
186186
}));

docs/en/retail-trade-october-2025/index.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,11 @@ display(Plot.plot({
117117
}),
118118
Plot.text(sectorData, {
119119
y: "sector",
120-
x: d => d.change >= 0 ? 12 : -5,
120+
x: 12,
121121
text: d => (d.change >= 0 ? "+" : "") + d.change.toFixed(1) + "%",
122-
textAnchor: d => d.change >= 0 ? "start" : "end",
123-
dx: d => d.change >= 0 ? 5 : -5,
124-
fill: "currentColor"
122+
textAnchor: "end",
123+
fill: "currentColor",
124+
fontSize: 11
125125
})
126126
]
127127
}));

docs/en/wholesale-trade-october-2025/index.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,22 +100,24 @@ display(Plot.plot({
100100
width: 600,
101101
height: 280,
102102
marginLeft: 180,
103-
x: {grid: true, label: "Percent change"},
103+
marginRight: 60,
104+
x: {domain: [-5, 20], grid: true, label: "Percent change"},
104105
y: {label: null},
105106
marks: [
106107
Plot.ruleX([0]),
107108
Plot.barX(subsectorData, {
108109
y: "sector",
109110
x: "change",
110-
fill: d => d.change >= 0 ? "#AF3C43" : "#1f77b4",
111+
fill: d => d.change >= 0 ? "#AF3C43" : "#2e7d32",
111112
sort: {y: "-x"}
112113
}),
113114
Plot.text(subsectorData, {
114115
y: "sector",
115-
x: d => d.change >= 0 ? d.change + 0.5 : d.change - 0.5,
116+
x: 20,
116117
text: d => (d.change >= 0 ? "+" : "") + d.change.toFixed(1) + "%",
117-
textAnchor: d => d.change >= 0 ? "start" : "end",
118-
fill: "currentColor"
118+
textAnchor: "end",
119+
fill: "currentColor",
120+
fontSize: 11
119121
})
120122
]
121123
}));

docs/fr/commerce-detail-octobre-2025/index.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,11 @@ display(Plot.plot({
117117
}),
118118
Plot.text(sectorData, {
119119
y: "sector",
120-
x: d => d.change >= 0 ? 12 : -5,
120+
x: 12,
121121
text: d => (d.change >= 0 ? "+" : "") + d.change.toFixed(1).replace(".", ",") + " %",
122-
textAnchor: d => d.change >= 0 ? "start" : "end",
123-
dx: d => d.change >= 0 ? 5 : -5,
124-
fill: "currentColor"
122+
textAnchor: "end",
123+
fill: "currentColor",
124+
fontSize: 11
125125
})
126126
]
127127
}));

docs/fr/commerce-gros-octobre-2025/index.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,22 +100,24 @@ display(Plot.plot({
100100
width: 600,
101101
height: 280,
102102
marginLeft: 200,
103-
x: {grid: true, label: "Variation en pourcentage"},
103+
marginRight: 60,
104+
x: {domain: [-5, 20], grid: true, label: "Variation en pourcentage"},
104105
y: {label: null},
105106
marks: [
106107
Plot.ruleX([0]),
107108
Plot.barX(subsectorData, {
108109
y: "sector",
109110
x: "change",
110-
fill: d => d.change >= 0 ? "#AF3C43" : "#1f77b4",
111+
fill: d => d.change >= 0 ? "#AF3C43" : "#2e7d32",
111112
sort: {y: "-x"}
112113
}),
113114
Plot.text(subsectorData, {
114115
y: "sector",
115-
x: d => d.change >= 0 ? d.change + 0.5 : d.change - 0.5,
116+
x: 20,
116117
text: d => (d.change >= 0 ? "+" : "") + d.change.toFixed(1).replace(".", ",") + " %",
117-
textAnchor: d => d.change >= 0 ? "start" : "end",
118-
fill: "currentColor"
118+
textAnchor: "end",
119+
fill: "currentColor",
120+
fontSize: 11
119121
})
120122
]
121123
}));

docs/fr/epa-novembre-2025/index.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,11 @@ display(Plot.plot({
176176
}),
177177
Plot.text(typeData, {
178178
y: "type",
179-
x: d => d.change >= 0 ? 70 : -20,
179+
x: 70,
180180
text: d => (d.change >= 0 ? "+" : "") + d.change.toFixed(1).replace(".", ","),
181-
textAnchor: d => d.change >= 0 ? "start" : "end",
182-
dx: d => d.change >= 0 ? 5 : -5,
183-
fill: "currentColor"
181+
textAnchor: "end",
182+
fill: "currentColor",
183+
fontSize: 11
184184
})
185185
]
186186
}));

docs/fr/ipc-novembre-2025/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ Le Québec (+3,0 %) et le Nouveau-Brunswick (+2,7 %) ont également dépassé le
114114
| Québec | +3,0 % | +0,8 pp |
115115
| Nouveau-Brunswick | +2,7 % | +0,5 pp |
116116
| Nouvelle-Écosse | +2,4 % | +0,2 pp |
117-
| Terre-Neuve-et-Labrador | +2,2 % | |
117+
| Terre-Neuve-et-Labrador | +2,2 % | 0,0 pp |
118118
| Saskatchewan | +2,1 % | -0,1 pp |
119119
| Colombie-Britannique | +2,0 % | -0,2 pp |
120120
| Ontario | +1,9 % | -0,3 pp |

docs/fr/passagers-aeriens-octobre-2025/index.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,22 +99,24 @@ display(Plot.plot({
9999
width: 550,
100100
height: 200,
101101
marginLeft: 200,
102-
x: {grid: true, label: "Variation en pourcentage"},
102+
marginRight: 60,
103+
x: {domain: [-15, 12], grid: true, label: "Variation en pourcentage"},
103104
y: {label: null},
104105
marks: [
105106
Plot.ruleX([0]),
106107
Plot.barX(trafficData, {
107108
y: "segment",
108109
x: "yoyChange",
109-
fill: d => d.yoyChange >= 0 ? "#AF3C43" : "#1f77b4",
110+
fill: d => d.yoyChange >= 0 ? "#AF3C43" : "#2e7d32",
110111
sort: {y: "-x"}
111112
}),
112113
Plot.text(trafficData, {
113114
y: "segment",
114-
x: d => d.yoyChange >= 0 ? d.yoyChange + 0.8 : d.yoyChange - 0.8,
115+
x: 12,
115116
text: d => (d.yoyChange >= 0 ? "+" : "") + d.yoyChange.toFixed(1).replace(".", ",") + " %",
116-
textAnchor: d => d.yoyChange >= 0 ? "start" : "end",
117-
fill: "currentColor"
117+
textAnchor: "end",
118+
fill: "currentColor",
119+
fontSize: 11
118120
})
119121
]
120122
}));

0 commit comments

Comments
 (0)