generated from vannizhang/react-redux-boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Area.tsx
61 lines (52 loc) · 1.68 KB
/
Area.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
import React, { useEffect, useMemo } from 'react';
import { select, ScaleLinear, ScaleTime, curveMonotoneX, area } from 'd3';
// import { LineChartDataItem } from './LineChartBasic';
import { SvgContainerData } from '../SvgContainer/SvgContainer';
import { AreaChartDataItem } from './types';
type Props = {
xScale: ScaleTime<number, number> | ScaleLinear<number, number>;
yScale: ScaleLinear<number, number>;
svgContainerData?: SvgContainerData;
data: AreaChartDataItem[];
stroke?: string;
fill?: string;
};
export const Area: React.FC<Props> = ({
xScale,
yScale,
data,
svgContainerData,
fill = 'skyblue',
}) => {
const areaGroup = React.useRef<SVGGElement>();
const valueArea = useMemo(() => {
const [yMin] = yScale.domain();
return area<AreaChartDataItem>()
.x((d) => xScale(d.x))
.y0(yScale(yMin))
.y1((d) => yScale(d.y));
}, [xScale, yScale]);
const draw = () => {
remove();
select(areaGroup.current)
.append('path')
.data([data])
.style('fill', fill)
// .style('stroke', stroke)
// .style('stroke-width', 0)
.attr('d', valueArea);
};
const remove = () => {
const area = select(areaGroup.current).select('path');
// check the number of existing area path, if greater than 0; remove all existing ones
if (area.size()) {
area.remove().exit();
}
};
useEffect(() => {
if (svgContainerData && xScale && yScale && data) {
draw();
}
}, [xScale, yScale, data]);
return <g ref={areaGroup} className="area-group"></g>;
};