/
ChordArc.tsx
91 lines (80 loc) · 3.05 KB
/
ChordArc.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import { createElement, memo, useMemo, MouseEvent } from 'react'
import { SpringValues, animated } from '@react-spring/web'
import { useTooltip } from '@nivo/tooltip'
import { ArcAnimatedProps, ArcDatum, ArcGenerator, ChordCommonProps } from './types'
import { computeArcPath } from './compute'
interface ChordArcProps {
arc: ArcDatum
animatedProps: SpringValues<ArcAnimatedProps>
arcGenerator: ArcGenerator
borderWidth: number
setCurrent: (arc: ArcDatum | null) => void
isInteractive: ChordCommonProps['isInteractive']
onMouseEnter?: ChordCommonProps['onArcMouseEnter']
onMouseMove?: ChordCommonProps['onArcMouseMove']
onMouseLeave?: ChordCommonProps['onArcMouseLeave']
onClick?: ChordCommonProps['onArcClick']
tooltip: ChordCommonProps['arcTooltip']
}
export const ChordArc = memo(
({
arc,
animatedProps,
borderWidth,
arcGenerator,
setCurrent,
isInteractive,
onMouseEnter,
onMouseMove,
onMouseLeave,
onClick,
tooltip,
}: ChordArcProps) => {
const { showTooltipFromEvent, hideTooltip } = useTooltip()
const handleMouseEnter = useMemo(() => {
if (!isInteractive) return undefined
return (event: MouseEvent) => {
setCurrent(arc)
showTooltipFromEvent(createElement(tooltip, { arc }), event)
onMouseEnter?.(arc, event)
}
}, [isInteractive, showTooltipFromEvent, tooltip, arc, onMouseEnter])
const handleMouseMove = useMemo(() => {
if (!isInteractive) return undefined
return (event: MouseEvent) => {
showTooltipFromEvent(createElement(tooltip, { arc }), event)
onMouseMove?.(arc, event)
}
}, [isInteractive, showTooltipFromEvent, tooltip, arc, onMouseMove])
const handleMouseLeave = useMemo(() => {
if (!isInteractive) return undefined
return (event: MouseEvent) => {
setCurrent(null)
hideTooltip()
onMouseLeave?.(arc, event)
}
}, [isInteractive, hideTooltip, arc, onMouseLeave])
const handleClick = useMemo(() => {
if (!isInteractive || !onClick) return undefined
return (event: MouseEvent) => onClick?.(arc, event)
}, [isInteractive, arc, onClick])
return (
<animated.path
data-testid={`arc.${arc.id}`}
d={computeArcPath({
startAngle: animatedProps.startAngle,
endAngle: animatedProps.endAngle,
arcGenerator,
})}
fill={animatedProps.color}
opacity={animatedProps.opacity}
strokeWidth={borderWidth}
stroke={animatedProps.borderColor}
onMouseEnter={handleMouseEnter}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
onClick={handleClick}
/>
)
}
)