generated from vannizhang/react-redux-boilerplate
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Bars.tsx
67 lines (56 loc) · 1.72 KB
/
Bars.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
import React, { useRef, useEffect } from 'react';
import { select, ScaleBand, ScaleLinear } from 'd3';
import { SvgContainerData } from '../SvgContainer/SvgContainer';
import { DivergingBarChartDataItem } from './types';
type Props = {
xScale: ScaleBand<string | number>;
yScale: ScaleLinear<number, number>;
svgContainerData?: SvgContainerData;
data: DivergingBarChartDataItem[];
/**
* fill color of bar rects
*/
fill?: string;
};
const Bars: React.FC<Props> = ({
xScale,
yScale,
data,
svgContainerData,
fill = 'steelblue',
}) => {
const barsGroup = useRef<SVGGElement>();
const draw = () => {
const { dimension } = svgContainerData;
// const { height } = dimension;
const existingBars = select(barsGroup.current).selectAll('rect');
if (existingBars.size()) {
existingBars.remove();
}
select(barsGroup.current)
.selectAll(`rect`)
.data(data)
.enter()
.append('rect')
.style('fill', (d) => d.fill || fill)
.attr('x', (d) => {
return typeof d.x === 'number'
? xScale(d.x.toString())
: xScale(d.x);
})
.attr('width', xScale.bandwidth())
.attr('y', (d) => {
return yScale(Math.max(0, d.y));
})
.attr('height', (d) => {
return Math.abs(yScale(d.y) - yScale(0));
});
};
useEffect(() => {
if (svgContainerData && xScale && yScale && data) {
draw();
}
}, [xScale, yScale, data]);
return <g ref={barsGroup} className="bar-group"></g>;
};
export default Bars;