Repository navigation
Commit bc5cd00
authored
feat: highlight the series nearest the cursor in time chart tooltips (#2456)
Multi-series Line and Area chart tooltips list every series at the hovered time. When a Group By produces many series, it is hard to tell which tooltip row maps to which line. This bolds the row for the series whose line is nearest the cursor and updates it as the pointer moves up and down, so a row is easy to trace back to its line.
HDX-4531
## Summary
In the shared tooltip for `HDXMultiSeriesTimeChart`, the row for the series nearest the cursor renders at `font-weight: 600` (the same weight the legend uses for a selected series). The highlighted row updates as the pointer moves vertically and clears when the pointer is farther than a small threshold from every line, so nothing is emphasized in empty space.
The nearest series is found in pure pixel space. Each Area's active dot records its active-point pixel Y, and the tooltip compares those positions against the cursor's pixel Y (`coordinate.y`). No axis-scale reconstruction is involved, which matters because the y domain is often `[0, 'auto']`.
## Changes
- `ChartUtils.tsx`: new pure helper `findNearestSeriesKey(seriesYByKey, candidateKeys, pointerY, maxDistancePx)` that returns the nearest series' key within the threshold, or `undefined`. Isolated so the geometry is unit-testable without rendering Recharts.
- `HDXMultiSeriesTimeChart.tsx`: a small capturing active dot on the `<Area>` branch records each series' active-point pixel Y into a per-chart ref, keyed by `dataKey`. It still draws the same dot Recharts renders by default. The tooltip reads the ref to bold the nearest row. Highlighting only applies when more than one series is shown.
- `ChartTooltip.tsx`: `ChartTooltipItem` takes an optional `highlighted` prop that sets the row weight to 600. Backward compatible; existing callers are unaffected.
## Why a ref read during render
Recharts renders the graphical items and their active dots before it renders the tooltip in the same commit, so the captured dot positions are current when the tooltip reads them. Both the capture write and the tooltip read touch a ref during render; this mirrors the existing pattern in `TimelineMouseCursor` and `TimelineXAxis`, and the `react-hooks/refs` disable is annotated with the reason.
## Out of scope
Stacked bar uses `activeBar` rather than `activeDot`, and vertical stacking makes "nearest line" meaningless, so it is intentionally untouched. Single-series charts have nothing to disambiguate, so highlighting is skipped there. Both cases were verified to render with no bold row.
## Test plan
- [x] `yarn lint:fix`, `make ci-lint`
- [x] `make ci-unit`, with new unit tests for `findNearestSeriesKey`: nearest within threshold, none within threshold, undefined pointer, undefined map, empty candidate list, candidate absent from the map skipped, tie resolves to the first candidate, inclusive boundary at `maxDistancePx`
- [x] Manual in Chart Explorer, a Logs Line chart grouped by `ServiceName` with several series:
- hovering bolds exactly one row, the series nearest the cursor
- moving the pointer down moves the bold through the lines in order
- nothing bolds when the pointer is far above every line or below the baseline
- confirmed in both light and dark themes
- stacked-bar tooltip shows no bold row; single-series tooltip shows no bold row
Before this change every tooltip row rendered at the same weight. Before/after captures in light and dark are ready to attach.
[ui-states: allow]
[viewport: allow]
[no-story: allow]1 parent 34aa906 commit bc5cd00
5 files changed
Lines changed: 276 additions & 5 deletions
File tree
- .changeset
- packages/app/src
- __tests__
- components/charts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
130 | 130 | | |
131 | 131 | | |
132 | 132 | | |
133 | | - | |
134 | | - | |
| 133 | + | |
| 134 | + | |
135 | 135 | | |
136 | 136 | | |
137 | 137 | | |
| |||
473 | 473 | | |
474 | 474 | | |
475 | 475 | | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
476 | 518 | | |
477 | 519 | | |
478 | 520 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| 33 | + | |
33 | 34 | | |
34 | 35 | | |
35 | 36 | | |
| |||
40 | 41 | | |
41 | 42 | | |
42 | 43 | | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
43 | 49 | | |
44 | 50 | | |
45 | 51 | | |
| |||
60 | 66 | | |
61 | 67 | | |
62 | 68 | | |
| 69 | + | |
| 70 | + | |
63 | 71 | | |
64 | 72 | | |
65 | 73 | | |
66 | 74 | | |
| 75 | + | |
| 76 | + | |
67 | 77 | | |
68 | 78 | | |
69 | 79 | | |
| |||
75 | 85 | | |
76 | 86 | | |
77 | 87 | | |
| 88 | + | |
| 89 | + | |
78 | 90 | | |
79 | 91 | | |
80 | 92 | | |
| |||
85 | 97 | | |
86 | 98 | | |
87 | 99 | | |
| 100 | + | |
| 101 | + | |
88 | 102 | | |
89 | 103 | | |
90 | 104 | | |
| |||
97 | 111 | | |
98 | 112 | | |
99 | 113 | | |
| 114 | + | |
100 | 115 | | |
101 | 116 | | |
102 | 117 | | |
| |||
120 | 135 | | |
121 | 136 | | |
122 | 137 | | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
123 | 158 | | |
124 | 159 | | |
125 | 160 | | |
| |||
142 | 177 | | |
143 | 178 | | |
144 | 179 | | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
145 | 184 | | |
146 | 185 | | |
147 | 186 | | |
| |||
337 | 376 | | |
338 | 377 | | |
339 | 378 | | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
340 | 431 | | |
341 | 432 | | |
342 | 433 | | |
| |||
345 | 436 | | |
346 | 437 | | |
347 | 438 | | |
348 | | - | |
| 439 | + | |
349 | 440 | | |
350 | 441 | | |
351 | 442 | | |
| |||
417 | 508 | | |
418 | 509 | | |
419 | 510 | | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
420 | 526 | | |
421 | 527 | | |
422 | 528 | | |
| |||
435 | 541 | | |
436 | 542 | | |
437 | 543 | | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
438 | 553 | | |
439 | 554 | | |
440 | 555 | | |
| |||
460 | 575 | | |
461 | 576 | | |
462 | 577 | | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
463 | 583 | | |
464 | 584 | | |
465 | 585 | | |
| |||
472 | 592 | | |
473 | 593 | | |
474 | 594 | | |
475 | | - | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
476 | 603 | | |
477 | 604 | | |
478 | 605 | | |
| |||
638 | 765 | | |
639 | 766 | | |
640 | 767 | | |
| 768 | + | |
641 | 769 | | |
642 | 770 | | |
643 | 771 | | |
| |||
652 | 780 | | |
653 | 781 | | |
654 | 782 | | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
655 | 804 | | |
656 | 805 | | |
657 | 806 | | |
| |||
722 | 871 | | |
723 | 872 | | |
724 | 873 | | |
| 874 | + | |
| 875 | + | |
| 876 | + | |
725 | 877 | | |
726 | 878 | | |
727 | 879 | | |
| |||
785 | 937 | | |
786 | 938 | | |
787 | 939 | | |
| 940 | + | |
788 | 941 | | |
789 | 942 | | |
790 | 943 | | |
| |||
0 commit comments