JSFiddle - React, Tailwind, and code Playground
by Pete Watson-Wailes
HTML
<div id="svg"></div>
JavaScript
var data = {
size: 230,
sectors: [{
percentage: 0.43,
label: 'Thing 1'
}, {
percentage: 0.22,
label: "Thing Two"
}, {
percentage: 0.18,
label: "Another Thing"
}, {
percentage: 0.17,
label: "Pineapple"
}
]
}
var newSVG = document.createElementNS("http://www.w3.org/2000/svg", "svg")
newSVG.setAttributeNS(null, 'style', "width: " + data.size + "px; height: " + data.size + "px")
var sectors = calculateSectors(data)
sectors.map(function(sector) {
var newSector = document.createElementNS("http://www.w3.org/2000/svg","path")
newSector.setAttributeNS(null, 'fill', sector.color)
newSector.setAttributeNS(null, 'd', 'M' + sector.L + ',' + sector.L + ' L' + sector.L + ',0 A' + sector.L + ',' + sector.L + ' 0 ' + sector.arcSweep + ',1 ' + sector.X + ', ' + sector.Y + ' z')
newSector.setAttributeNS(null, 'transform', 'rotate(' + sector.R + ', '+ sector.L+', '+ sector.L+')')
newSVG.appendChild(newSector)
})
document.getElementById("svg").appendChild(newSVG)
function calculateSectors (data) {
var sectors = [],
colors = ["#61C0BF", "#DA507A", "#BB3D49", "#DB4547"]
var l = data.size / 2,
a = 0, // Angle
aRad = 0, // Angle in Rad
z = 0, // Size z
x = 0, // Side x
y = 0, // Side y
X = 0, // SVG X coordinate
Y = 0, // SVG Y coordinate
R = 0 // Rotation
data.sectors.map(function(item, key) {
a = 360 * item.percentage
aCalc = ( a > 180 ) ? 360 - a : a
aRad = aCalc * Math.PI / 180
z = Math.sqrt( 2*l*l - ( 2*l*l*Math.cos(aRad) ) )
x = (aCalc <= 90)
? l * Math.sin(aRad)
: l * Math.sin((180 - aCalc) * Math.PI/180)
y = Math.sqrt(z*z - x*x)
Y = y
if (a <= 180) {
X = l + x
arcSweep = 0
}
else {
X = l - x
arcSweep = 1
}
sectors.push({
percentage: item.percentage,
label: item.label,
color: colors[key],
arcSweep: arcSweep,
L: l,
X:...