From 22b8c47403f9b0b81165a765f664872b306c35b1 Mon Sep 17 00:00:00 2001 From: myung03 Date: Fri, 17 May 2024 16:45:21 -0700 Subject: [PATCH] fixed hover effects (transition still broken) --- .../app/$libraryId/overview/PieChart.tsx | 124 ++++++++---------- 1 file changed, 56 insertions(+), 68 deletions(-) diff --git a/interface/app/$libraryId/overview/PieChart.tsx b/interface/app/$libraryId/overview/PieChart.tsx index 649ca9939..510de29fc 100644 --- a/interface/app/$libraryId/overview/PieChart.tsx +++ b/interface/app/$libraryId/overview/PieChart.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useRef, FunctionComponent } from 'react'; +import React, { useState, useRef, FunctionComponent } from 'react'; import clsx from 'clsx'; export type PieChartProps = { @@ -11,14 +11,6 @@ export type PieChartProps = { units?: string; }; -const polarToCartesian = (centerX: number, centerY: number, radius: number, angleInDegrees: number) => { - const angleInRadians = ((angleInDegrees - 90) * Math.PI) / 180.0; - return { - x: centerX + radius * Math.cos(angleInRadians), - y: centerY + radius * Math.sin(angleInRadians), - }; -}; - const PieChart: FunctionComponent = ({ data, radius, @@ -29,26 +21,22 @@ const PieChart: FunctionComponent = ({ units = '', }) => { const [hoveredIndex, setHoveredIndex] = useState(null); + const pieChartRef = useRef(null); - useEffect(() => { - const handleMouseOut = (event: MouseEvent) => { - if (pieChartRef.current && !pieChartRef.current.contains(event.target as Node)) { - setHoveredIndex(null); - } - }; - - document.addEventListener('mouseout', handleMouseOut); - return () => { - document.removeEventListener('mouseout', handleMouseOut); - }; - }, []); - const total = data.reduce((sum, item) => sum + item.value, 0); const margin = 10; const svgSize = 2 * (radius + strokeWidth) + margin * 2; const center = radius + strokeWidth + margin; + const polarToCartesian = (centerX: number, centerY: number, radius: number, angleInDegrees: number) => { + const angleInRadians = ((angleInDegrees - 90) * Math.PI) / 180.0; + return { + x: centerX + radius * Math.cos(angleInRadians), + y: centerY + radius * Math.sin(angleInRadians), + }; + }; + const renderSlices = () => { let cumulativeValue = 0; @@ -67,75 +55,75 @@ const PieChart: FunctionComponent = ({ const innerEnd = polarToCartesian(center, center, innerRadius!, startAngle); const largeArcFlag = sliceAngle > 180 ? 1 : 0; - const outerPathData = [ + const pathData = [ `M ${outerStart.x} ${outerStart.y}`, `A ${radius} ${radius} 0 ${largeArcFlag} 1 ${outerEnd.x} ${outerEnd.y}`, - `L ${center} ${center}`, - `Z`, - ].join(' '); - - const innerPathData = [ - `M ${innerStart.x} ${innerStart.y}`, + `L ${innerStart.x} ${innerStart.y}`, `A ${innerRadius} ${innerRadius} 0 ${largeArcFlag} 0 ${innerEnd.x} ${innerEnd.y}`, - `L ${center} ${center}`, `Z`, ].join(' '); - const fullPathData = [ - `M ${outerStart.x} ${outerStart.y}`, - `A ${radius} ${radius} 0 ${largeArcFlag} 1 ${outerEnd.x} ${outerEnd.y}`, - `L ${innerEnd.x} ${innerEnd.y}`, - `A ${innerRadius} ${innerRadius} 0 ${largeArcFlag} 0 ${innerStart.x} ${innerStart.y}`, + const hoverPathData = [ + `M ${polarToCartesian(center, center, radius + 10, startAngle).x} ${polarToCartesian(center, center, radius + 10, startAngle).y}`, + `A ${radius + 10} ${radius + 10} 0 ${largeArcFlag} 1 ${polarToCartesian(center, center, radius + 10, startAngle + sliceAngle).x} ${polarToCartesian(center, center, radius + 10, startAngle + sliceAngle).y}`, + `L ${polarToCartesian(center, center, innerRadius! - 10, startAngle + sliceAngle).x} ${polarToCartesian(center, center, innerRadius! - 10, startAngle + sliceAngle).y}`, + `A ${innerRadius! - 10} ${innerRadius! - 10} 0 ${largeArcFlag} 0 ${polarToCartesian(center, center, innerRadius! - 10, startAngle).x} ${polarToCartesian(center, center, innerRadius! - 10, startAngle).y}`, `Z`, ].join(' '); return ( - setHoveredIndex(index)} - onMouseOut={() => setHoveredIndex(null)} - className={clsx('transition-transform duration-300 ease-out', { - 'opacity-100': isHovered, - 'opacity-50': hoveredIndex !== null && !isHovered, - })} - style={{ - transform: isHovered ? `translate(${translation.x}px, ${translation.y}px) scale(1.05)` : 'scale(1)', - opacity: hoveredIndex !== null && !isHovered ? 0.5 : 1, - transition: 'transform 0.3s ease-out, opacity 0.3s ease-out', - zIndex: isHovered ? 10 : 1, - }} - > - {/* Full path for the whole slice, used for hover effect */} - - {/* Path for the outer portion of the slice, with color */} - + + setHoveredIndex(index)} + onMouseLeave={() => setHoveredIndex(null)} + style={{ cursor: 'pointer' }} + /> + ); }); }; return ( -
+
{renderSlices()} - {hoveredIndex !== null && ( - - {data[hoveredIndex]?.value} - {units} - - )} + {hoveredIndex !== null && ( +
+ {data[hoveredIndex].value} + + {units} + +
+ )}
);