({
segments = [],
diameter = 200,
label = '',
isMonochrome = false,
printPercentage = false,
})
| 14 | const MONOCHROME_COLORS = ['#3b2c48', '#e0e0ea']; |
| 15 | |
| 16 | const DonutChart = ({ |
| 17 | segments = [], |
| 18 | diameter = 200, |
| 19 | label = '', |
| 20 | isMonochrome = false, |
| 21 | printPercentage = false, |
| 22 | }) => { |
| 23 | const centerX = diameter / 2; |
| 24 | const centerY = centerX; |
| 25 | const radius = centerX * 0.9; |
| 26 | |
| 27 | let lastX = centerX; |
| 28 | let lastY = centerY - radius; |
| 29 | let alpha = Math.PI / 2; |
| 30 | |
| 31 | let sum = 0.0; |
| 32 | for (let i = 0; i < segments.length; ++i) { |
| 33 | sum += segments[i]; |
| 34 | } |
| 35 | |
| 36 | const paths = []; |
| 37 | for (let i = 0; i < segments.length; ++i) { |
| 38 | const arc = (segments[i] / sum) * 2 * Math.PI; |
| 39 | let angle = alpha - Math.min(arc, Math.PI); |
| 40 | let endX = radius * Math.cos(angle) + centerX; |
| 41 | let endY = -radius * Math.sin(angle) + centerY; |
| 42 | |
| 43 | let path = ['M', centerY, centerY, 'L', lastX, lastY, 'A', radius, radius, 0, 0, 1, endX, endY]; |
| 44 | if (arc > Math.PI) { |
| 45 | angle = alpha - arc; |
| 46 | endX = radius * Math.cos(angle) + centerX; |
| 47 | endY = -radius * Math.sin(angle) + centerY; |
| 48 | path = path.concat(['A', radius, radius, 0, 0, 1, endX, endY]); |
| 49 | } |
| 50 | path.push('Z'); |
| 51 | |
| 52 | paths.push( |
| 53 | <path |
| 54 | className={styles.path} |
| 55 | d={path.join(' ')} |
| 56 | style={{ |
| 57 | fill: isMonochrome ? MONOCHROME_COLORS[i % 2] : CHART_COLORS[i], |
| 58 | transformOrigin: `${centerY}px ${centerX}px 0px`, |
| 59 | }} |
| 60 | key={`segment${i}`} |
| 61 | /> |
| 62 | ); |
| 63 | |
| 64 | lastX = endX; |
| 65 | lastY = endY; |
| 66 | alpha = angle; |
| 67 | } |
| 68 | |
| 69 | return ( |
| 70 | <svg style={{ width: diameter, height: diameter }}> |
nothing calls this directly
no outgoing calls
no test coverage detected