82 lines
1.7 KiB
JavaScript
82 lines
1.7 KiB
JavaScript
import React from 'react';
|
|
import PropTypes from 'prop-types';
|
|
|
|
import style from './ProgressCircle.sass';
|
|
|
|
const ProgressCircle = ({
|
|
children,
|
|
min,
|
|
max,
|
|
progress,
|
|
size,
|
|
strokeWidth,
|
|
backStroke,
|
|
stroke,
|
|
}) => {
|
|
const width = size;
|
|
const height = size;
|
|
|
|
const viewBox = [0, 0, width, height].join(' ');
|
|
|
|
const cx = width / 2;
|
|
const cy = height / 2;
|
|
|
|
const r = (size / 2) - (strokeWidth / 2);
|
|
|
|
const strokeLength = 2 * Math.PI * r;
|
|
|
|
const finalProgress = (progress - min) / (max - min);
|
|
|
|
const strokeDasharray = strokeLength;
|
|
const strokeDashoffset = strokeLength * (1 - finalProgress);
|
|
|
|
return (
|
|
<div
|
|
className={style.progressCircleContainer}
|
|
style={{
|
|
width: `${width}px`,
|
|
height: `${height}px`,
|
|
}}
|
|
>
|
|
<svg className={style.progressCircle} {...{ width, height, viewBox }}>
|
|
<circle
|
|
fill="none"
|
|
stroke={backStroke}
|
|
{...{ cx, cy, r, strokeWidth }}
|
|
/>
|
|
<circle
|
|
className={style.progressValue}
|
|
fill="none"
|
|
{...{ cx, cy, r, stroke, strokeWidth, strokeDashoffset, strokeDasharray }}
|
|
/>
|
|
</svg>
|
|
<span className={style.progressCircleLabel}>
|
|
{children}
|
|
</span>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
ProgressCircle.propTypes = {
|
|
children: PropTypes.node,
|
|
size: PropTypes.number.isRequired,
|
|
progress: PropTypes.number,
|
|
strokeWidth: PropTypes.number,
|
|
min: PropTypes.number,
|
|
max: PropTypes.number,
|
|
backStroke: PropTypes.string,
|
|
stroke: PropTypes.string,
|
|
};
|
|
|
|
ProgressCircle.defaultProps = {
|
|
stroke: '#444',
|
|
backStroke: 'rgba(102, 166, 229, 0.12)',
|
|
strokeWidth: 10,
|
|
progress: 0.5,
|
|
min: 0,
|
|
max: 1,
|
|
children: null,
|
|
};
|
|
|
|
export default ProgressCircle;
|