fix: bound tooltip coordinates to chart container in index sync method#6263
Conversation
Ensure synchronized tooltips stay within chart boundaries by clamping coordinates to the receiving chart's viewBox dimensions. Fixes tooltip positioning issues when synchronizing charts with different
|
@ckifer Hey, Feel free to take a look when available. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6263 +/- ##
==========================================
- Coverage 96.63% 96.62% -0.02%
==========================================
Files 221 221
Lines 20147 20178 +31
Branches 4129 4136 +7
==========================================
+ Hits 19470 19496 +26
- Misses 670 675 +5
Partials 7 7 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Hi @shreedharbhat98 , thanks for the PR. Please add tests - the more the better. There's tons of edge cases here to cover. |
@PavelVanecek Have added some tests to cover all kinds of charts. Feel free to mention if I left any. Thanks |
| if (lastCallA && typeof lastCallA === 'object' && 'x' in lastCallA) { | ||
| expect(lastCallA.x).toBeLessThanOrEqual(200); | ||
| expect(lastCallA.x).toBeGreaterThanOrEqual(0); | ||
| } |
There was a problem hiding this comment.
let's avoid conditionals in tests: if for whatever reason the call is falsy or any of the conditions fail, the test will continue to pass.
not sure what's the preferred method in the codebase, but I'd do something like this:
const lastCallA = spyA.mock.calls[spyA.mock.calls.length - 1][0];
// assuming lastCallA is of type `any`
expect(lastCallA?.x).toBeLessThanOrEqual(200);
expect(lastCallA?.x).toBeGreaterThanOrEqual(0);...as well as in all the rest of the test cases
the exception would be of course if we're testing the opposite behaviour, i.e. if we want it to be called without arguments or with undefined, I'd then separate that into a different set of test cases that assert expect(lastCallA.x).toBeUndefined(), etc
There was a problem hiding this comment.
+1. If the conditions are necessary for typescript then please use type assertions and throw. See assertNotNull for an example.
There was a problem hiding this comment.
@PavelVanecek I have refactored the tests and also the logic. Back to you for now. 🏓
…ove coordinate bounding - Replace conditional assertions with explicit expect statements - Remove all if/else blocks that could cause silent test failures - Use expect().toBeDefined(), expect().not.toBeNull(), and expect().toHaveProperty() for robust assertions
There was a problem hiding this comment.
Pull Request Overview
This PR fixes tooltip positioning issues during chart synchronization by ensuring tooltip coordinates are bounded within the receiving chart's container dimensions. The fix specifically addresses the syncMethod='index' case where tooltips could appear outside chart boundaries when synchronizing between charts of different sizes.
Key changes:
- Added coordinate bounding logic for x and y coordinates in the index sync method
- Preserved all other coordinate properties for compatibility with radial charts
- Added comprehensive test coverage for various chart type combinations and edge cases
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/synchronisation/useChartSynchronisation.tsx | Implements coordinate bounding logic to clamp x/y coordinates within viewBox dimensions while preserving other properties |
| test/component/Tooltip/Tooltip.sync.spec.tsx | Adds extensive test suite covering coordinate bounding for all chart types and cross-chart synchronization scenarios |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| const boundedCoordinate = { | ||
| ...otherCoordinateProps, | ||
| ...(typeof x === 'number' && { | ||
| x: Math.max(viewBox.x, Math.min(x, viewBox.x + viewBox.width)), |
There was a problem hiding this comment.
The x coordinate bounding logic is incorrect. It should clamp between viewBox.x and viewBox.x + viewBox.width - 1, or use <= comparison, since viewBox.x + viewBox.width represents the first pixel outside the bounds.
| x: Math.max(viewBox.x, Math.min(x, viewBox.x + viewBox.width)), | |
| x: Math.max(viewBox.x, Math.min(x, viewBox.x + viewBox.width - 1)), |
| x: Math.max(viewBox.x, Math.min(x, viewBox.x + viewBox.width)), | ||
| }), | ||
| ...(typeof y === 'number' && { | ||
| y: Math.max(viewBox.y, Math.min(y, viewBox.y + viewBox.height)), |
There was a problem hiding this comment.
The y coordinate bounding logic is incorrect. It should clamp between viewBox.y and viewBox.y + viewBox.height - 1, or use <= comparison, since viewBox.y + viewBox.height represents the first pixel outside the bounds.
| y: Math.max(viewBox.y, Math.min(y, viewBox.y + viewBox.height)), | |
| y: Math.max(viewBox.y, Math.min(y, viewBox.y + viewBox.height - 1)), |
|
Is the |
|
Should be an improvement either way for now |
@PavelVanecek Not sure, While testing it, I did not feel it. Tooltip perfectly appeared with in the viewbox itself. |
|
If you couldn't see it while testing then it's all good 👍 the AI is often hallucinating. |
Fix: Bound tooltip coordinates to chart container in index sync method
Ensure synchronized tooltips stay within chart boundaries by clamping coordinates to the receiving chart's viewBox dimensions. Fixes tooltip positioning issues when synchronizing charts with different widths.
Description
When using
syncMethod='index'for chart synchronization, tooltip coordinates were passed through directly without considering the receiving chart's container boundaries. This caused tooltips to appear outside chart bounds when synchronizing between charts with different dimensions.This PR adds coordinate bounding to the index sync method:
viewBox.xandviewBox.x + viewBox.widthviewBox.yandviewBox.y + viewBox.heightThe fix ensures tooltips always appear within their respective chart containers when synchronizing between charts of different sizes, while maintaining compatibility with all chart types including RadialBarChart.
Related Issue
Fixes #6253 - Tooltip sync for different chart widths
Motivation and Context
When multiple synchronized charts have different dimensions, the tooltip coordinates from one chart may fall outside the boundaries of another chart. This results in tooltips appearing in incorrect positions or outside the visible chart area.
The issue was particularly problematic when:
syncMethod='index'which previously did no coordinate validationHow Has This Been Tested?
Unit Tests Added
Comprehensive test suite covering:
Screenshots (if appropriate):
Types of changes
Checklist: