Skip to content

Commit

Permalink
fix(tooltip): fix positioning when charts are rendered inside an scal…
Browse files Browse the repository at this point in the history
…ed div (#2034)

* Fix tooltip positioning when charts are rendered inside an scaled div
In a normal situation mouse enter / mouse leave events
capture the position ok. But when the chart is inside a scaled
element with a CSS transform like: `transform: scale(2);`
tooltip are not positioned ok.
Comparing original width `box.width` agains scaled width give us the
scaling factor to calculate ok mouse position.

* Fix tooltip positioning on line slice tooltips
When a Nivo chart is inside an scaled div with something like
`transform: scale(2)` for example tooltips inside slides are not
positoned correctly. Taking into accoun `offsetWidth` fix the issue
  • Loading branch information
andresgutgon committed Jun 17, 2022
1 parent 5985ab4 commit a1a529c
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 3 deletions.
10 changes: 9 additions & 1 deletion packages/core/src/lib/interactivity/index.js
Expand Up @@ -12,6 +12,14 @@ export * from './detect'
export const getRelativeCursor = (el, event) => {
const { clientX, clientY } = event
const bounds = el.getBoundingClientRect()
const box = el.getBBox()

return [clientX - bounds.left, clientY - bounds.top]
// In a normal situation mouse enter / mouse leave events
// capture the position ok. But when the chart is inside a scaled
// element with a CSS transform like: `transform: scale(2);`
// tooltip are not positioned ok.
// Comparing original width `box.width` agains scaled width give us the
// scaling factor to calculate ok mouse position
const scaling = box.width === bounds.width ? 1 : box.width / bounds.width
return [(clientX - bounds.left) * scaling, (clientY - bounds.top) * scaling]
}
13 changes: 11 additions & 2 deletions packages/tooltip/src/hooks.ts
Expand Up @@ -26,8 +26,17 @@ export const useTooltipHandlers = (container: MutableRefObject<HTMLDivElement>)
const showTooltipFromEvent: TooltipActionsContextData['showTooltipFromEvent'] = useCallback(
(content: JSX.Element, event: MouseEvent, anchor: TooltipAnchor = 'top') => {
const bounds = container.current.getBoundingClientRect()
const x = event.clientX - bounds.left
const y = event.clientY - bounds.top
const offsetWidth = container.current.offsetWidth
// In a normal situation mouse enter / mouse leave events
// capture the position ok. But when the chart is inside a scaled
// element with a CSS transform like: `transform: scale(2);`
// tooltip are not positioned ok.
// Comparing original width `offsetWidth` agains scaled
// width give us the scaling factor to calculate
// ok mouse position
const scaling = offsetWidth === bounds.width ? 1 : offsetWidth / bounds.width
const x = (event.clientX - bounds.left) * scaling
const y = (event.clientY - bounds.top) * scaling

if (anchor === 'left' || anchor === 'right') {
if (x < bounds.width / 2) anchor = 'right'
Expand Down

0 comments on commit a1a529c

Please sign in to comment.