-
-
Notifications
You must be signed in to change notification settings - Fork 1k
/
ArcsLayer.tsx
95 lines (89 loc) · 2.86 KB
/
ArcsLayer.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
92
93
94
95
import React, { createElement } from 'react'
import { useTheme } from '@nivo/core'
import { InheritedColorConfig, useInheritedColor } from '@nivo/colors'
import { DatumWithArcAndColor, ArcGenerator } from './types'
import { useArcsTransition } from './useArcsTransition'
import { ArcTransitionMode } from './arcTransitionMode'
import { ArcMouseHandler, ArcShape, ArcShapeProps } from './ArcShape'
export type ArcComponent<Datum extends DatumWithArcAndColor> = (
props: ArcShapeProps<Datum>
) => JSX.Element
interface ArcsLayerProps<Datum extends DatumWithArcAndColor> {
center: [number, number]
data: Datum[]
arcGenerator: ArcGenerator
borderWidth: number
borderColor: InheritedColorConfig<Datum>
onClick?: ArcMouseHandler<Datum>
onMouseEnter?: ArcMouseHandler<Datum>
onMouseMove?: ArcMouseHandler<Datum>
onMouseLeave?: ArcMouseHandler<Datum>
transitionMode: ArcTransitionMode
component?: ArcComponent<Datum>
}
export const ArcsLayer = <Datum extends DatumWithArcAndColor>({
center,
data,
arcGenerator,
borderWidth,
borderColor,
onClick,
onMouseEnter,
onMouseMove,
onMouseLeave,
transitionMode,
component = ArcShape,
}: ArcsLayerProps<Datum>) => {
const theme = useTheme()
const getBorderColor = useInheritedColor<Datum>(borderColor, theme)
const { transition, interpolate } = useArcsTransition<
Datum,
{
opacity: number
color: string
borderColor: string
}
>(data, transitionMode, {
enter: datum => ({
opacity: 0,
color: datum.color,
borderColor: getBorderColor(datum),
}),
update: datum => ({
opacity: 1,
color: datum.color,
borderColor: getBorderColor(datum),
}),
leave: datum => ({
opacity: 0,
color: datum.color,
borderColor: getBorderColor(datum),
}),
})
const Arc: ArcComponent<Datum> = component
return (
<g transform={`translate(${center[0]},${center[1]})`}>
{transition((transitionProps, datum) => {
return createElement(Arc, {
key: datum.id,
datum,
style: {
...transitionProps,
borderWidth,
path: interpolate(
transitionProps.startAngle,
transitionProps.endAngle,
transitionProps.innerRadius,
transitionProps.outerRadius,
arcGenerator
),
},
onClick,
onMouseEnter,
onMouseMove,
onMouseLeave,
})
})}
</g>
)
}