forked from atom/github
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdonut-chart.js
69 lines (60 loc) · 1.52 KB
/
donut-chart.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
import React from 'react';
import PropTypes from 'prop-types';
import {autobind} from '../helpers';
export default class DonutChart extends React.Component {
static propTypes = {
baseOffset: PropTypes.number,
slices: PropTypes.arrayOf(
PropTypes.shape({
type: PropTypes.string,
className: PropTypes.string,
count: PropTypes.number,
}),
),
}
static defaultProps = {
baseOffset: 25,
}
constructor(props) {
super(props);
autobind(this, 'renderArc');
}
render() {
const {slices, baseOffset, ...others} = this.props; // eslint-disable-line no-unused-vars
const arcs = this.calculateArcs(slices);
return (
<svg {...others}>
{arcs.map(this.renderArc)}
</svg>
);
}
calculateArcs(slices) {
const total = slices.reduce((acc, item) => acc + item.count, 0);
let lengthSoFar = 0;
return slices.map(({count, ...others}) => {
const piece = {
length: count / total * 100,
position: lengthSoFar,
...others,
};
lengthSoFar += piece.length;
return piece;
});
}
renderArc({length, position, type, className}) {
return (
<circle
key={type}
cx="21"
cy="21"
r="15.91549430918954"
fill="transparent"
className={`donut-ring-${type}`}
pathLength="100"
strokeWidth="3"
strokeDasharray={`${length} ${100 - length}`}
strokeDashoffset={`${100 - position + this.props.baseOffset}`}
/>
);
}
}