v2/View/CircularProgressBar/index.tsx
import React from 'react';
import { arc } from 'd3-shape';
import { _cs } from '@togglecorp/fujs';
import styles from './styles.scss';
interface Props {
width: number;
arcWidth: number;
value: number;
src?: string;
imagePadding: number;
className?: string;
arcClassName?: string;
}
const arcGenerator = arc()
.cornerRadius(5);
function CircularProgressBar(props: Props) {
const {
width,
arcWidth,
value,
src,
imagePadding,
className,
arcClassName,
} = props;
const height = width;
const arcOuterRadius = width / 2;
const arcInnerRadius = (width / 2) - arcWidth;
const innerCircleRadius = arcInnerRadius - imagePadding;
const imageWidth = (innerCircleRadius - (0.1 * imagePadding)) * Math.sqrt(2);
const progressArc = (v: number) => arcGenerator({
endAngle: 2 * Math.PI * v,
startAngle: 0,
innerRadius: arcInnerRadius,
outerRadius: arcOuterRadius,
});
return (
<svg className={_cs(styles.progressBar, className)} height={height} width={width}>
<g transform={`translate(${width / 2}, ${height / 2})`}>
<path
className={styles.arcBackground}
d={progressArc(1) ?? undefined}
/>
</g>
<g transform={`translate(${width / 2}, ${height / 2})`}>
<path
className={_cs(styles.arc, arcClassName)}
d={progressArc(value / 100) ?? undefined}
/>
</g>
<g transform={`translate(${width / 2}, ${height / 2})`}>
<circle
className={styles.circle}
r={innerCircleRadius}
/>
{ src && (
<use
width={imageWidth}
height={imageWidth}
href={src}
x={-(imageWidth / 2)}
y={-(imageWidth / 2)}
/>
)}
</g>
</svg>
);
}
export default CircularProgressBar;