/
Area.js
83 lines (77 loc) · 2.52 KB
/
Area.js
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
import { memo } from 'react'
import PropTypes from 'prop-types'
import { useSpring, animated } from '@react-spring/web'
import { useAnimatedPath, useMotionConfig, blendModePropType } from '@nivo/core'
import { useSerieHandlers } from './hooks'
const Area = ({
serie,
areaGenerator,
blendMode,
isInteractive,
onMouseEnter,
onMouseMove,
onMouseLeave,
onClick,
setCurrentSerie,
tooltip,
}) => {
const handlers = useSerieHandlers({
serie,
isInteractive,
onMouseEnter,
onMouseMove,
onMouseLeave,
onClick,
setCurrent: setCurrentSerie,
tooltip,
})
const { animate, config: springConfig } = useMotionConfig()
const animatedPath = useAnimatedPath(areaGenerator(serie.areaPoints))
const animatedProps = useSpring({
color: serie.color,
fillOpacity: serie.style.fillOpacity,
stroke: serie.style.borderColor,
strokeOpacity: serie.style.borderOpacity,
config: springConfig,
immediate: !animate,
})
return (
<animated.path
d={animatedPath}
fill={serie.fill ? serie.fill : animatedProps.color}
fillOpacity={animatedProps.fillOpacity}
stroke={animatedProps.stroke}
strokeWidth={serie.style.borderWidth}
strokeOpacity={animatedProps.strokeOpacity}
style={{ mixBlendMode: blendMode }}
onMouseEnter={handlers.onMouseEnter}
onMouseMove={handlers.onMouseMove}
onMouseLeave={handlers.onMouseLeave}
onClick={handlers.onClick}
/>
)
}
Area.propTypes = {
serie: PropTypes.shape({
id: PropTypes.string.isRequired,
color: PropTypes.string.isRequired,
fill: PropTypes.string,
areaPoints: PropTypes.array.isRequired,
style: PropTypes.shape({
fillOpacity: PropTypes.number.isRequired,
borderWidth: PropTypes.number.isRequired,
borderColor: PropTypes.string.isRequired,
borderOpacity: PropTypes.number.isRequired,
}).isRequired,
}).isRequired,
areaGenerator: PropTypes.func.isRequired,
blendMode: blendModePropType.isRequired,
isInteractive: PropTypes.bool.isRequired,
onMouseEnter: PropTypes.func,
onMouseMove: PropTypes.func,
onMouseLeave: PropTypes.func,
onClick: PropTypes.func,
setCurrentSerie: PropTypes.func.isRequired,
tooltip: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).isRequired,
}
export default memo(Area)