Skip to content

Commit 5bb1202

Browse files
ryan-williamsclaude
andcommitted
fix double-reversal in unified hover: normalize entry order first
groupedHoverData arrives in inconsistent order depending on showlegend and hover collection path. Sorting entries by trace.index before passing to getLegendData ensures the reversal in getLegendData is the single source of truth for traceorder. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 482abde commit 5bb1202

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Inconsistent unified hover tooltip ordering
2+
3+
## Problem
4+
5+
Unified hover entries arrive in inconsistent order depending on whether the plot has `showlegend: true` or `false`:
6+
7+
- **Plot with `showlegend: false`** (custom legend): hover entries arrive in `groupedHoverData` already reversed (top-of-stack first). `getLegendData.reverse()` then double-reverses → wrong order.
8+
- **Plot with `showlegend: true`**: hover entries arrive in original trace array order (bottom-of-stack first). `getLegendData.reverse()` correctly reverses → right order.
9+
- But for CrashPlot (`showlegend: true`): the order is scrambled (Fatal, Prop. Damage, Injury instead of Prop. Damage, Injury, Fatal).
10+
11+
## Debug evidence (Plot1, showlegend: false)
12+
13+
```
14+
BEFORE_REVERSE: Total,Passengers,Pedestrians,Drivers,Cyclists ← already reversed
15+
AFTER_REVERSE: Cyclists,Drivers,Pedestrians,Passengers,Total ← double-reversed, WRONG
16+
```
17+
18+
## Root cause
19+
20+
The `groupedHoverData` order depends on the plot's full layout processing. When `showlegend: false`, the trace iteration order during hover data collection may differ from when `showlegend: true`. The hover code in `hover.ts` builds entries in whatever order `hoverData` arrives, which depends on `_hoverPoints` in `plot_api.ts`.
21+
22+
## Fix needed
23+
24+
Normalize the hover entry order BEFORE passing to `getLegendData`. The entries should always arrive in trace array order (bottom-of-stack first), and `getLegendData.reverse()` should be the sole reversal. Find where `groupedHoverData` gets pre-reversed and prevent that.

src/components/fx/hover.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1233,7 +1233,11 @@ function createHoverText(hoverData: any[], opts: any): any {
12331233

12341234
mockLegend.entries.push([pt]);
12351235
}
1236-
// Sort is handled by getLegendData inside legendDraw,
1236+
// Normalize to trace index order before getLegendData applies traceorder.
1237+
// groupedHoverData may arrive in inconsistent order depending on
1238+
// showlegend and hover collection order.
1239+
mockLegend.entries.sort((a: any, b: any) => a[0].trace.index - b[0].trace.index);
1240+
// Reversal (if traceorder includes 'reversed') is handled by getLegendData inside legendDraw.
12371241
// which respects traceorder (including 'reversed').
12381242
mockLegend.layer = container;
12391243

0 commit comments

Comments
 (0)