Skip to content

Instantly share code, notes, and snippets.

@JofArnold
Created September 29, 2017 09:49
Show Gist options
  • Save JofArnold/35ecefe959bfa6bf8491a82052c2f941 to your computer and use it in GitHub Desktop.
Save JofArnold/35ecefe959bfa6bf8491a82052c2f941 to your computer and use it in GitHub Desktop.
Donut Chart using Styled Components
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