From d814d9f5c7af829f3b029103c219f20bff2d06ba Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Mon, 25 Aug 2025 14:24:58 +0200 Subject: [PATCH 1/2] Start work on making tooltip smooth transition instead of immediate position change --- .../LineChart/ChartTooltip/ChartTooltip.tsx | 48 ++++++++++++------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/frontend/src/component/insights/components/LineChart/ChartTooltip/ChartTooltip.tsx b/frontend/src/component/insights/components/LineChart/ChartTooltip/ChartTooltip.tsx index ff0b8891b2..af40a125a6 100644 --- a/frontend/src/component/insights/components/LineChart/ChartTooltip/ChartTooltip.tsx +++ b/frontend/src/component/insights/components/LineChart/ChartTooltip/ChartTooltip.tsx @@ -2,7 +2,7 @@ import { Box, Paper, styled, Typography } from '@mui/material'; import type { TooltipItem } from 'chart.js'; import { Truncator } from 'component/common/Truncator/Truncator'; import type React from 'react'; -import type { FC, VFC } from 'react'; +import { useEffect, useState, type FC, type VFC } from 'react'; import { objectId } from 'utils/objectId'; export type TooltipState = { @@ -73,23 +73,35 @@ const getLeftOffset = (caretX = 0, align?: 'left' | 'right' | 'center') => { export const ChartTooltipContainer: FC = ({ tooltip, children, -}) => ( - ({ - top: (tooltip?.caretY || 0) + offset, - left: getLeftOffset(tooltip?.caretX, tooltip?.align), - width: '1px', - position: 'absolute', - display: tooltip ? 'flex' : 'none', - pointerEvents: 'none', - zIndex: theme.zIndex.tooltip, - flexDirection: 'column', - alignItems: getAlign(tooltip?.align), - })} - > - {children} - -); +}) => { + const [top, setTop] = useState(0); + const [left, setLeft] = useState(0); + useEffect(() => { + if (tooltip) { + setTop(tooltip.caretY + offset); + setLeft(getLeftOffset(tooltip.caretX, tooltip.align)); + } + }, [tooltip]); + return ( + ({ + top: 0, + left: 0, + transform: `translate(${left}px, ${top}px)`, + transition: 'transform 0.3s ease-in-out', + width: '1px', + position: 'absolute', + display: tooltip ? 'flex' : 'none', + pointerEvents: 'none', + zIndex: theme.zIndex.tooltip, + flexDirection: 'column', + alignItems: getAlign(tooltip?.align), + })} + > + {children} + + ); +}; export const ChartTooltip: VFC = ({ tooltip }) => ( From 89bb5c23f2a73b958a0752c2e5a835afd752f11d Mon Sep 17 00:00:00 2001 From: Thomas Heartman Date: Thu, 28 Aug 2025 13:52:45 +0200 Subject: [PATCH 2/2] Use opacity instead of rendering and unrendering the tooltip. --- .../LineChart/ChartTooltip/ChartTooltip.tsx | 28 ++++--------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/frontend/src/component/insights/components/LineChart/ChartTooltip/ChartTooltip.tsx b/frontend/src/component/insights/components/LineChart/ChartTooltip/ChartTooltip.tsx index af40a125a6..c50ea76e71 100644 --- a/frontend/src/component/insights/components/LineChart/ChartTooltip/ChartTooltip.tsx +++ b/frontend/src/component/insights/components/LineChart/ChartTooltip/ChartTooltip.tsx @@ -2,7 +2,7 @@ import { Box, Paper, styled, Typography } from '@mui/material'; import type { TooltipItem } from 'chart.js'; import { Truncator } from 'component/common/Truncator/Truncator'; import type React from 'react'; -import { useEffect, useState, type FC, type VFC } from 'react'; +import type { FC, VFC } from 'react'; import { objectId } from 'utils/objectId'; export type TooltipState = { @@ -46,18 +46,6 @@ const StyledLabelIcon = styled('span')(({ theme }) => ({ const offset = 16; -const getAlign = (align?: 'left' | 'right' | 'center') => { - if (align === 'left') { - return 'flex-start'; - } - - if (align === 'right') { - return 'flex-end'; - } - - return 'center'; -}; - const getLeftOffset = (caretX = 0, align?: 'left' | 'right' | 'center') => { if (align === 'left') { return caretX + offset; @@ -74,28 +62,22 @@ export const ChartTooltipContainer: FC = ({ tooltip, children, }) => { - const [top, setTop] = useState(0); - const [left, setLeft] = useState(0); - useEffect(() => { - if (tooltip) { - setTop(tooltip.caretY + offset); - setLeft(getLeftOffset(tooltip.caretX, tooltip.align)); - } - }, [tooltip]); + const top = tooltip?.caretY ?? 0 + offset; + const left = getLeftOffset(tooltip?.caretX, tooltip?.align); return ( ({ top: 0, left: 0, transform: `translate(${left}px, ${top}px)`, - transition: 'transform 0.3s ease-in-out', + transition: 'transform 0.2s ease-in-out', width: '1px', position: 'absolute', display: tooltip ? 'flex' : 'none', pointerEvents: 'none', zIndex: theme.zIndex.tooltip, flexDirection: 'column', - alignItems: getAlign(tooltip?.align), + alignItems: 'center', })} > {children}