Skip to content

Instantly share code, notes, and snippets.

@deamme
Last active August 23, 2018 15:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save deamme/67929fb11c9a7582a2d258cfe23a4f96 to your computer and use it in GitHub Desktop.
Save deamme/67929fb11c9a7582a2d258cfe23a4f96 to your computer and use it in GitHub Desktop.
import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import { Spring, animated } from 'react-spring'
import { springs } from '../../utils/styles'
const BORDER_WIDTH = 4
const VALUE_DEFAULT = 1
const SIZE_DEFAULT = 80
const LABEL_DEFAULT = value => `${Math.round(value * 100)}%`
const CircleGraph = ({ value, label, size }) => {
const length = Math.PI * 2 * (size - BORDER_WIDTH)
const radius = (size - BORDER_WIDTH) / 2
return (
<Spring
config={springs.lazy}
to={{ progressValue: value }}
native
>
{({ progressValue }) => (
<div>
<svg
width={size}
height={size}
viewBox={`0 0 ${size} ${size}`}
xmlns="http://www.w3.org/2000/svg"
>
<CircleBase cx={size / 2} cy={size / 2} r={radius} />
<CircleValue
cx={size / 2}
cy={size / 2}
r={radius}
style={{
strokeDasharray: length,
strokeDashoffset: progressValue.interpolate(
t => length - (length * t) / 2
),
strokeWidth: BORDER_WIDTH,
}}
/>
</svg>
<Label x="50%" y="50%">
{progressValue.interpolate(t =>
label(Math.min(value, Math.max(0, t)))
)}
</Label>
</div>
)}
</Spring>
)
}
CircleGraph.propTypes = {
value: PropTypes.number,
size: PropTypes.number,
label: PropTypes.func,
}
CircleGraph.defaultProps = {
value: VALUE_DEFAULT,
size: SIZE_DEFAULT,
label: LABEL_DEFAULT,
}
const CircleBase = styled.circle`
fill: none;
stroke: #6d777b;
opacity: 0.3;
`
const CircleValue = styled(animated.circle)`
fill: none;
transform: rotate(270deg);
transform-origin: 50% 50%;
stroke: #21c1e7;
`
const Label = styled(animated.text)`
fill: #000;
font-size: 16px;
font-weight: 600;
dominant-baseline: middle;
alignment-baseline: middle;
text-anchor: middle;
transform: translate(45px, -77px);
display: block;
`
export default CircleGraph
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment