0

I've been working on filling in 72% a circle with a hole cut out of the middle for some time now and I've been referring to This way of calculating for most of it and This for anything else. With the calculation, I keep running into issues with my cosine calculation being negative and not giving me the arc that I'm looking for. I'm new to HTML, so my issues maybe my own fault. I would greatly appreciate any advice someone can give me!

Below is an example of the code working with 12%. I haven't been able to wrap my brain around a 72% version, so I've tried to get as close to it as possible.

<svg focusable="false" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" tabindex="-1" height="60%" width="60%" viewBox="-5  -5 410 410" style="display: block; fill: transparent; position: absolute; right: 15px; bottom: 15px;">
  <circle aria-hidden="true" tabindex="-1" cx="200" cy="200" r="200" style="stroke: rgb(139, 138, 175); stroke-width: 5px;"></circle>
  <path aria-hidden="true" tabindex="-1" d="M 200 0 A 200 200 0 1 1 199.8000000333334 0.00009999999167575879 L 199.87500002083337 75.0000624999948 A 125 125 0 1 0 200 75 Z" fill="#FFFFFF"></path>
  <path aria-hidden="true" tabindex="-1" d="M 200 0 A 200 200 0 0 1 199.80000003333333 0.00009999999167575879 L 199.87500002083334 75.0000624999948 A 125 125 0 0 0 200 75 Z" fill="#00ACC8"></path>
  <path aria-hidden="true" tabindex="-1" d="M 200 0 A 200 200 0 0 1 336.76355902984756 54.06943801420687 L 285.4772243936547 108.79339875887929 A 125 125 0 0 0 200 75 Z" fill="#00ACC8"></path>
  <circle aria-hidden="true" tabindex="-1" cx="200" cy="200" r="125" style="stroke: rgb(139, 138, 175); stroke-width: 2.5px; fill: transparent;"></circle><text aria-hidden="true" tabindex="-1" x="50%" y="50%" dy="7%" style="text-anchor: middle; font-weight: bold; font-size: 115px; fill: rgb(70, 112, 125);">12</text>
</svg>
  • Your question is a little confusing. Can you post a picture with the desired result? – Michael Rovinsky Jan 16 '22 at 06:41
  • Please show us how you are doing the calculation. – A Haworth Jan 16 '22 at 06:43
  • 1
    This sort of chart is easily done by using a dashed stroke circle where the length of the stroke and the length of the gaps is igual to the circumference of the circle. Please read about [How SVG Line Animation Works](https://css-tricks.com/svg-line-animation-works/) – enxaneta Jan 16 '22 at 07:57

1 Answers1

2

Here is an example of how to control the donut chart using CSS. Instead of using the technique used for the pie chart I use the stroke-dasharray on a circle.

text {
  text-anchor: middle;
  dominant-baseline: middle;
  font-weight: bold;
  font-size: 30px;
  fill: rgb(70, 112, 125);
}

circle.bar {
  stroke-dasharray: 0 100;
}

circle.p25 {
  stroke-dasharray: 25 100;
}

circle.p33 {
  stroke-dasharray: 33 100;
}

circle.p50 {
  stroke-dasharray: 50 100;
}
<svg focusable="false" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" tabindex="-1" width="200" viewBox="0 0 100 100">
  <circle class="bar" cx="50" cy="50" r="40" stroke="#00ACC8" stroke-width="16" fill="none" pathLength="100" transform="rotate(-90 50 50)"/>
  <circle cx="50" cy="50" r="48" stroke="rgb(139, 138, 175)" stroke-width="1" fill="none" />
  <circle cx="50" cy="50" r="32" stroke="rgb(139, 138, 175)" stroke-width="1" fill="none" />
  <text aria-hidden="true" tabindex="-1" x="50" y="50">0</text>
</svg>

<svg focusable="false" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" tabindex="-1" width="200" viewBox="0 0 100 100">
  <circle class="bar p25" cx="50" cy="50" r="40" stroke="#00ACC8" stroke-width="16" fill="none" pathLength="100" transform="rotate(-90 50 50)"/>
  <circle cx="50" cy="50" r="48" stroke="rgb(139, 138, 175)" stroke-width="1" fill="none" />
  <circle cx="50" cy="50" r="32" stroke="rgb(139, 138, 175)" stroke-width="1" fill="none" />
  <text aria-hidden="true" tabindex="-1" x="50" y="50">25</text>
</svg>

<svg focusable="false" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" tabindex="-1" width="200" viewBox="0 0 100 100">
  <circle class="bar p33" cx="50" cy="50" r="40" stroke="#00ACC8" stroke-width="16" fill="none" pathLength="100" transform="rotate(-90 50 50)"/>
  <circle cx="50" cy="50" r="48" stroke="rgb(139, 138, 175)" stroke-width="1" fill="none" />
  <circle cx="50" cy="50" r="32" stroke="rgb(139, 138, 175)" stroke-width="1" fill="none" />
  <text aria-hidden="true" tabindex="-1" x="50" y="50">33</text>
</svg>

Is there a reason why the chart should be controlled by CSS? Here I made a version that uses a bit of JavaScript:

document.forms.form01.range.addEventListener('change', e => {
  document.getElementById('bar').setAttribute('stroke-dasharray', `${e.target.value} 100`);
  document.getElementById('text').textContent = e.target.value;
});
text {
  text-anchor: middle;
  dominant-baseline: middle;
  font-weight: bold;
  font-size: 30px;
  fill: rgb(70, 112, 125);
}
<form name="form01">
  <input type="range" name="range" min="0" max="100" value="25"/>
</form>

<svg focusable="false" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" tabindex="-1" width="200" viewBox="0 0 100 100">
  <circle id="bar" cx="50" cy="50" r="40" stroke="#00ACC8" stroke-width="16" stroke-dasharray="25 100" fill="none" pathLength="100" transform="rotate(-90 50 50)"/>
  <circle cx="50" cy="50" r="48" stroke="rgb(139, 138, 175)" stroke-width="1" fill="none" />
  <circle cx="50" cy="50" r="32" stroke="rgb(139, 138, 175)" stroke-width="1" fill="none" />
  <text id="text" aria-hidden="true" tabindex="-1" x="50" y="50">25</text>
</svg>
chrwahl
  • 8,675
  • 2
  • 20
  • 30