Created
September 29, 2017 09:49
-
-
Save JofArnold/35ecefe959bfa6bf8491a82052c2f941 to your computer and use it in GitHub Desktop.
Donut Chart using Styled Components
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from "react"; | |
import PropTypes from "prop-types"; | |
import styled from "styled-components"; | |
const dimsFromProps = ({ size, strokeWidth, value }) => { | |
const halfsize = size * 0.5; | |
const radius = halfsize - strokeWidth * 0.5; | |
const circumference = 2 * Math.PI * radius; | |
const strokeVal = value * circumference / 100; | |
const dashVal = strokeVal + " " + circumference; | |
const rotateVal = "rotate(-90 " + halfsize + "," + halfsize + ")"; | |
return { | |
halfsize, | |
radius, | |
circumference, | |
strokeVal, | |
dashVal, | |
rotateVal, | |
size, | |
value, | |
strokeWidth, | |
}; | |
}; | |
const Container = styled.span` | |
border-radius: 50%; | |
display: block; | |
position: relative; | |
`; | |
const Track = styled.circle` | |
fill: transparent; | |
stroke: #dae2e5; | |
`; | |
const Indicator = styled.circle` | |
fill: transparent; | |
stroke: #009688; | |
stroke-dasharray: ${props => dimsFromProps(props).dashVal || "0 10000"}; | |
transition: stroke-dasharray 0.3s ease; | |
`; | |
const Text = styled.span` | |
width: ${({ width }) => width + "px"}; | |
height: ${({ height }) => height + "px"}; | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
justify-content: center; | |
position: absolute; | |
top: 0; | |
left: 0; | |
`; | |
class DonutChart extends Component { | |
static defaultProps = { | |
value: 50, | |
size: 116, | |
strokeWidth: 26, | |
}; | |
render() { | |
const { | |
halfsize, | |
radius, | |
rotateVal, | |
size, | |
value, | |
strokeWidth, | |
} = dimsFromProps(this.props); | |
const { className, children } = this.props; | |
return ( | |
<Container className={className} width={size} height={size}> | |
<svg width={size} height={size}> | |
<Track | |
r={radius} | |
cx={halfsize} | |
cy={halfsize} | |
transform={rotateVal} | |
value={value} | |
size={size} | |
strokeWidth={strokeWidth} | |
/> | |
<Indicator | |
r={radius} | |
cx={halfsize} | |
cy={halfsize} | |
transform={rotateVal} | |
value={value} | |
size={size} | |
strokeWidth={strokeWidth} | |
/> | |
</svg> | |
<Text width={size} height={size}> | |
{children} | |
</Text> | |
</Container> | |
); | |
} | |
} | |
DonutChart.propTypes = { | |
className: PropTypes.string, | |
value: PropTypes.number, // value the chart should show | |
size: PropTypes.number, // diameter of chart | |
strokeWidth: PropTypes.number, // width of chart line | |
}; | |
export default DonutChart; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment