From 73ae23914861730b79b293c0c8b1b5ffe226f70f Mon Sep 17 00:00:00 2001 From: "av.maiorov" Date: Thu, 22 Dec 2022 12:34:09 +0500 Subject: [PATCH] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=BE=20=D0=BF=D0=BE=D0=B2=D0=B5=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=B4=D1=81=D0=BA=D0=B0=D0=B7=D0=BA=D0=B8=20?= =?UTF-8?q?=D1=83=20=D0=B3=D1=80=D0=B0=D1=84=D0=B8=D0=BA=D0=B0=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=20=D0=B5=D0=B3=D0=BE=20=D0=B7=D1=83=D0=BC=D0=B5=20?= =?UTF-8?q?=D0=B8=D0=BB=D0=B8=20=D1=81=D0=BA=D1=80=D0=BE=D0=BB=D0=B5=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=B8=D1=86=D0=B5?= =?UTF-8?q?=20=D0=BE=D0=BF=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D0=B9.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/d3/D3Chart.tsx | 4 +-- src/components/d3/plugins/D3Tooltip.tsx | 39 ++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/components/d3/D3Chart.tsx b/src/components/d3/D3Chart.tsx index 9e8bee9..0581b9c 100644 --- a/src/components/d3/D3Chart.tsx +++ b/src/components/d3/D3Chart.tsx @@ -115,7 +115,7 @@ const _D3Chart = >({ height: givenHeight = '100%', loading, offset: _offset, - animDurationMs = 200, + animDurationMs = 20, backgroundColor = 'transparent', ticks, plugins, @@ -417,7 +417,7 @@ const _D3Chart = >({ charts={charts} {...plugins?.legend} /> - charts={charts} {...plugins?.tooltip} /> + charts={charts} {...plugins?.tooltip} zoomState={currentZoomState}/> diff --git a/src/components/d3/plugins/D3Tooltip.tsx b/src/components/d3/plugins/D3Tooltip.tsx index 1d16cb7..820e48a 100644 --- a/src/components/d3/plugins/D3Tooltip.tsx +++ b/src/components/d3/plugins/D3Tooltip.tsx @@ -76,6 +76,7 @@ export const makeDefaultRender = (): D3RenderFunc export type D3TooltipProps = Partial> & { charts: ChartRegistry[], + zoomState?: d3.ZoomTransform | null, } function _D3Tooltip({ @@ -86,7 +87,8 @@ function _D3Tooltip({ position: _position = 'bottom', className = '', style: _style = {}, - limit = 2 + limit = 2, + zoomState, }: D3TooltipProps) { const { mouseState, zoneRect, subscribe } = useD3MouseZone() const [tooltipBody, setTooltipBody] = useState() @@ -94,6 +96,7 @@ function _D3Tooltip({ const [position, setPosition] = useState(_position ?? 'bottom') const [visible, setVisible] = useState(false) const [fixed, setFixed] = useState(false) + const [currentZoom, setCurrentZoom] = useState(null); const tooltipRef = useRef(null) @@ -113,7 +116,7 @@ function _D3Tooltip({ }, [subscribe, visible]) useEffect(() => { - if (!tooltipRef.current || !zoneRect || fixed) return + if (!tooltipRef.current || !zoneRect || fixed || !visible) return const rect = tooltipRef.current.getBoundingClientRect() if (!mouseState.visible) return @@ -121,8 +124,9 @@ function _D3Tooltip({ const offsetX = -rect.width / 2 // По центру const offsetY = 15 // Чуть выше курсора - const left = Math.max(10, Math.min(zoneRect.width - rect.width - 10, mouseState.x + offsetX)) + const left = mouseState.x + offsetX let top = mouseState.y - offsetY - rect.height + setPosition(top <= 0 ? 'top' : 'bottom') if (top <= 0) top = mouseState.y + offsetY @@ -131,7 +135,34 @@ function _D3Tooltip({ left, top, })) - }, [tooltipRef.current, mouseState, zoneRect, fixed]) + }, [tooltipRef.current, mouseState, zoneRect, fixed, visible]) + + useEffect(() => { + if (!zoomState) return + + setCurrentZoom(zoomState) + + if (!fixed) { + setVisible(false) + return + } + + const offsetX = Number(style.left) + Number(width) + 7 + + if (zoneRect && ((offsetX <= zoneRect.left) || (offsetX > zoneRect.right)) || zoomState.k !== currentZoom?.k) { + setVisible(false) + setFixed(false) + return + } + + const distanceMoveX = currentZoom ? currentZoom.x - zoomState.x : 1 + + setStyle((prevStyle) => ({ + ...prevStyle, + left: prevStyle?.left ? +prevStyle.left - distanceMoveX : 0, + })) + }, [zoomState, fixed]) + useEffect(() => { if (fixed) return