Skip to content

Commit 0d26852

Browse files
committed
adding the library
1 parent 509f703 commit 0d26852

4 files changed

Lines changed: 160 additions & 0 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

package.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "radial-progress",
3+
"version": "1.0.0",
4+
"description": "a radial progress bar in react js and SVG",
5+
"main": "src/index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/samidarko/radial-progress.git"
12+
},
13+
"keywords": [
14+
"radial",
15+
"progress",
16+
"React",
17+
"Javascript",
18+
"SVG"
19+
],
20+
"author": "Sami Darko <samidarko@gmail.com> (https://github.com/samidarko)",
21+
"license": "MIT",
22+
"bugs": {
23+
"url": "https://github.com/samidarko/radial-progress/issues"
24+
},
25+
"homepage": "https://github.com/samidarko/radial-progress#readme"
26+
}

src/RadialProgress.js

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import React from 'react';
2+
import AuthenticatedComponent from '../containers/AuthenticatedComponent';
3+
4+
function clamp (n, min, max) {
5+
return Math.max(min, Math.min(max, n));
6+
}
7+
8+
export class RadialProgress extends React.Component {
9+
10+
constructor() {
11+
super();
12+
this.initialize = this.initialize.bind(this);
13+
this.generatePath = this.generatePath.bind(this);
14+
this.setInterval = this.setInterval.bind(this);
15+
this.state = {value: 0};
16+
}
17+
18+
setInterval() {
19+
clearInterval(this.interval);
20+
this.interval = setInterval(() => {
21+
if (this.state.value < this.props.value) {
22+
this.setState({value: this.state.value + this.props.progressRate});
23+
} else {
24+
clearInterval(this.interval);
25+
}
26+
}, 1000/this.props.fps);
27+
}
28+
29+
initialize() {
30+
if (this.props.animated) {
31+
this.setInterval();
32+
} else {
33+
this.setState({value: this.props.value});
34+
}
35+
}
36+
37+
componentDidMount() {
38+
this.initialize();
39+
}
40+
41+
componentWillUnmount() {
42+
if (this.props.animated) clearInterval(this.interval);
43+
}
44+
45+
componentWillReceiveProps() {
46+
this.setState({value: 0}, this.initialize);
47+
}
48+
49+
generatePath(degrees) {
50+
const radius = this.props.radius;
51+
const radians = (degrees * Math.PI / 180);
52+
var x = Math.sin(radians) * radius;
53+
var y = Math.cos(radians) * -radius;
54+
const halfEdgeSize = this.props.edgeSize/2;
55+
x += halfEdgeSize;
56+
y += halfEdgeSize;
57+
const largeArcSweepFlag = degrees > 180 ? 1 : 0;
58+
const startX = halfEdgeSize;
59+
const startY = halfEdgeSize - radius;
60+
return `M${startX},${startY} A${radius},${radius} 0 ${largeArcSweepFlag} 1 ${x},${y} `;
61+
}
62+
63+
render() {
64+
65+
const center = this.props.edgeSize / 2;
66+
const radius = this.props.radius;
67+
let degrees, text = '';
68+
if (this.props.unit === 'percent') {
69+
let percent = clamp(this.state.value, 0, 100);
70+
degrees = percent / 100 * 360;
71+
degrees = clamp(degrees, 0, 359.9);
72+
text = this.props.formatText(percent)
73+
} else {
74+
degrees = this.state.value;
75+
degrees = clamp(degrees, 0, 359.9);
76+
text = this.props.formatText(degrees)
77+
}
78+
79+
const pathDescription = this.generatePath(degrees);
80+
81+
return (
82+
<svg height={this.props.edgeSize} width={this.props.edgeSize}>
83+
<circle cx={center} cy={center} r={radius}
84+
stroke={this.props.circleStroke}
85+
strokeWidth={this.props.circleStrokeWidth}
86+
fill={this.props.circleFill}/>
87+
<path d={pathDescription}
88+
fill="transparent"
89+
stroke={this.props.progressStroke}
90+
strokeWidth={this.props.circleStrokeWidth}/>
91+
{
92+
this.props.displayText &&
93+
<text x={center} y={center} textAnchor="middle">{text}</text>
94+
}
95+
</svg>
96+
);
97+
}
98+
}
99+
100+
RadialProgress.defaultProps = {
101+
edgeSize: 100,
102+
radius: 45,
103+
circleStrokeWidth: 4,
104+
circleStroke: '#D8D8D8',
105+
circleFill: 'transparent',
106+
progressStroke: 'black',
107+
unit: 'degrees',
108+
displayText: true,
109+
formatText: (value) => value,
110+
animated: true,
111+
fps: 60,
112+
progressRate: 1
113+
};
114+
115+
RadialProgress.propTypes = {
116+
edgeSize: React.PropTypes.number.isRequired,
117+
radius: React.PropTypes.number.isRequired,
118+
circleStrokeWidth: React.PropTypes.number.isRequired,
119+
circleStroke: React.PropTypes.string.isRequired,
120+
circleFill: React.PropTypes.string.isRequired,
121+
progressStroke: React.PropTypes.string.isRequired,
122+
value: React.PropTypes.number.isRequired,
123+
unit: React.PropTypes.oneOf(['degrees', 'percent']).isRequired,
124+
displayText: React.PropTypes.bool.isRequired,
125+
formatText: React.PropTypes.func,
126+
animated: React.PropTypes.bool.isRequired,
127+
fps: React.PropTypes.number.isRequired,
128+
progressRate: React.PropTypes.number.isRequired
129+
};
130+
131+
export default RadialProgress;
132+

src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('./RadialProgress');

0 commit comments

Comments
 (0)