Last active
December 23, 2016 09:53
-
-
Save jackysee/9ce9b0cb7be2fc828db60ccafd48cd4a to your computer and use it in GitHub Desktop.
Donut chart in Vanilla es6
This file contains hidden or 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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>JS Bin</title> | |
</head> | |
<body> | |
<div id="svg"></div> | |
<script> | |
var cx = 90; | |
var cy = 90; | |
var innerRadius = 50; | |
var outerRadius = 60; | |
function toRad(deg){ | |
return deg * Math.PI / 180.0; | |
} | |
function getPos(x, y, r, deg){ | |
var a = toRad(deg - 90); | |
return { | |
x: x + (r * Math.cos(a)), | |
y: y + (r * Math.sin(a)) | |
} | |
} | |
function getArc(startAngle, endAngle, radiusOffset){ | |
radiusOffset = radiusOffset || 0; | |
var c = getPos(cx, cy, radiusOffset, startAngle + (endAngle - startAngle)/2); | |
var start1 = getPos(c.x, c.y, innerRadius , endAngle); | |
var end1 = getPos(c.x, c.y, innerRadius, startAngle); | |
var arc = endAngle - startAngle <= 180? "0":"1"; | |
var start2 = getPos(c.x, c.y, outerRadius, startAngle); | |
var end2 = getPos(c.x, c.y, outerRadius, endAngle); | |
var cmd = [ | |
'M', start1.x, start1.y, | |
'A', innerRadius, innerRadius, 0, arc, 0, end1.x, end1.y,//Draw outer circle | |
'L', start2.x, start2.y, //Move pointer | |
'A', outerRadius, outerRadius, 0, arc, 1, end2.x, end2.y,//Draw inner circle | |
'Z' | |
]; | |
cmd = cmd.join(' '); | |
return cmd; | |
} | |
var data = [ | |
{value: 100, selected:false}, | |
{value: 20, selected:true}, | |
{value: 30, selected:false}, | |
{value: 250, selected:false} | |
]; | |
var colors = [ | |
'#99CCFF', | |
'yellow', | |
'gray', | |
'red', | |
'green' | |
]; | |
function toArcs(data){ | |
var total = data.reduce(function(sum, d){ | |
return sum + d.value; | |
}, 0); | |
var r = data.reduce(function(result, d, i){ | |
var startAngle = result.current; | |
var endAngle = result.current + 360*d.value/total; | |
result.arcs.push({ | |
d: getArc(startAngle, endAngle, d.selected? 8 : 0), | |
fill: colors[i%colors.length] | |
}); | |
result.current = endAngle; | |
return result; | |
}, { arcs:[], current:0 }); | |
return r.arcs; | |
} | |
var centerBoxLength = 2*innerRadius/Math.sqrt(2); | |
var svg = ` | |
<svg style="border:1px solid red" | |
viewBox="0 0 180 180"> | |
${toArcs(data).map(function(a){ | |
return ` | |
<path | |
d="${a.d}" | |
fill="${a.fill}" | |
/> | |
`; | |
}).join('')} | |
<g> | |
<rect x="90" y="90" | |
width="${centerBoxLength}" | |
height="${centerBoxLength}" | |
transform="translate(-${centerBoxLength/2}, -${centerBoxLength/2})" | |
fill="transparent" | |
stroke="red" | |
stroke-width="0.2"> | |
</rect> | |
<text x="90" y="95" width="20" height="20" | |
fill="black" text-anchor="middle" | |
style="font-family:sans-serif; font-size:1.5em; fill:#555"> | |
8465 | |
</text> | |
<text x="90" y="106" width="20" height="20" | |
fill="black" text-anchor="middle" | |
style="font-family:sans-serif; font-size:0.6em; fill:#888;"> | |
items | |
</text> | |
</g> | |
</svg> | |
`; | |
document.getElementById('svg').innerHTML = svg; | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment