(diameter, data, strokeWidth = 50, gap = 0, wedgeWidth = 4)
| 492 | } |
| 493 | |
| 494 | function Donut(diameter, data, strokeWidth = 50, gap = 0, wedgeWidth = 4) { |
| 495 | const decimals = 4; |
| 496 | const total = data.reduce((acc, curr) => acc + curr.value, 0); |
| 497 | const arcs = []; |
| 498 | let radius = diameter / 2; |
| 499 | let svgSize = radius * 2 + (wedgeWidth + 15) * 2; |
| 500 | let startAngle = 0; |
| 501 | let gapInAngle = 2 * Math.atan(gap / (2 * radius)) * (180 / Math.PI); |
| 502 | let cx = svgSize / 2; |
| 503 | let cy = svgSize / 2; |
| 504 | let r = radius - strokeWidth / 2; |
| 505 | |
| 506 | for (let i = 0; i < data.length; i++) { |
| 507 | const item = data[i]; |
| 508 | const percentage = ((item.value / total) * 100).toFixed(2); |
| 509 | const endAngle = startAngle + (360 / 100) * percentage - gapInAngle / 2; |
| 510 | const largeArcFlag = endAngle - startAngle <= 180 ? 0 : 1; |
| 511 | |
| 512 | let startPoint = calculatePoint(cx, cy, r, endAngle); |
| 513 | let endPoint = calculatePoint(cx, cy, r, startAngle); |
| 514 | let sx = startPoint.x.toFixed(decimals); |
| 515 | let sy = startPoint.y.toFixed(decimals); |
| 516 | let ex = endPoint.x.toFixed(decimals); |
| 517 | let ey = endPoint.y.toFixed(decimals); |
| 518 | const arcPath = `M${sx},${sy} A${r},${r} 0 ${largeArcFlag},0 ${ex},${ey}`; |
| 519 | |
| 520 | // another line beyond the edge of arc |
| 521 | let outterRadius = r + 25 + wedgeWidth; |
| 522 | startPoint = calculatePoint(cx, cy, outterRadius, endAngle); |
| 523 | endPoint = calculatePoint(cx, cy, outterRadius, startAngle); |
| 524 | sx = startPoint.x.toFixed(decimals); |
| 525 | sy = startPoint.y.toFixed(decimals); |
| 526 | ex = endPoint.x.toFixed(decimals); |
| 527 | ey = endPoint.y.toFixed(decimals); |
| 528 | const outerArcPath = `M${sx},${sy} A${outterRadius},${outterRadius} 0 ${largeArcFlag},0 ${ex},${ey}`; |
| 529 | |
| 530 | const arc = { |
| 531 | index: i, |
| 532 | value: item.value, |
| 533 | website: item.website, |
| 534 | color: item.color, |
| 535 | percentage: item.percentage, |
| 536 | d: arcPath, |
| 537 | d2: outerArcPath, |
| 538 | }; |
| 539 | |
| 540 | arcs.push(arc); |
| 541 | startAngle = endAngle + gapInAngle / 2; |
| 542 | } |
| 543 | |
| 544 | let svg = `<svg viewBox="0 0 ${svgSize} ${svgSize}" width="${svgSize}" height="${svgSize}" xmlns="http://www.w3.org/2000/svg"> |
| 545 | <foreignObject x="0" y="0" width="${svgSize}" height="${svgSize}"> |
| 546 | <body> |
| 547 | <div class="center"> |
| 548 | <div class="percentage"></div> |
| 549 | <div class="timer"></div> |
| 550 | <div class="name"></div> |
| 551 | </div> |
no test coverage detected