-
Notifications
You must be signed in to change notification settings - Fork 2
/
useAreaChart.js
56 lines (44 loc) · 1.35 KB
/
useAreaChart.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
import { useMemo } from 'react'
import T from 'prop-types'
import { area } from 'd3'
function scaleAreaChart(height, width, xScale, yScale, flip) {
xScale.range([0, width])
yScale.range(flip ? [0, height] : [height, 0])
const areaMaker = area()
.x(d => xScale(d.data.end))
.y0(d => yScale(d[0]))
.y1(d => yScale(d[1]))
.defined(d => !d.data.noData)
return areaMaker
}
function getPathDefs(stackedData, areaMaker) {
const pathDefs = stackedData.map(datum => ({
pathDef: areaMaker(datum),
key: datum.key,
}))
return pathDefs
}
function useAreaChart(props) {
T.checkPropTypes(useAreaChart.propTypes, props, 'prop', 'useAreaChart')
const { height, width, stackedData, xScale, yScale, flip = false } = props
// Both steps are potentially very expensive if applied to large,
// rapidly changing data sets, so don't rescale unless needed
const areaMaker = useMemo(
() => scaleAreaChart(height, width, xScale, yScale, flip),
[height, width, xScale, yScale, flip]
)
const pathDefs = useMemo(() => getPathDefs(stackedData, areaMaker), [
stackedData,
areaMaker,
])
return pathDefs
}
useAreaChart.propTypes = {
height: T.number.isRequired,
width: T.number.isRequired,
stackedData: T.array.isRequired,
xScale: T.func.isRequired,
yScale: T.func.isRequired,
flip: T.bool,
}
export default useAreaChart