'css/html- to create a circle with a hole in the bottom
I wanna make circle chart like this. below is my code.
If I invert up and down in that code, i get the shape you want. But what I really want is a graph with the yellow graph pointing further to the right. How do I adjust the spacing? Please help me
<svg width="4.5rem" height="4.5rem" viewBox="0 0 40 40">
<circle class="pieSegment segment1" cx="20" cy="20" r="15.915494309189533" fill="transparent" stroke="#1a0d1c" stroke-dashoffset="11" stroke-dasharray="74" stroke-width="5"></circle>
<circle class="pieSegment segment3" cx="20" cy="20" r="15.915494309189533" fill="transparent" stroke="#e9ad61" stroke-dashoffset="14" stroke-dasharray="25 75" stroke-width="5"></circle>
</svg>
Solution 1:[1]
Edit (missed the previous answer by @jeremy-denis also using pathLength)
Here is another approach also using pathLength
value:
See also MDN Docs: pathLength
example horse shoe gauge
let progress = document.querySelector("#progress");
let svgGauges = document.querySelectorAll(".svgGauge");
let gauges = document.querySelectorAll(".gaugePercent");
let percentText = document.querySelector(".percentText");
progress.addEventListener("change", function(e) {
let percent = e.target.value;
if (svgGauges.length) {
svgGauges.forEach(function(item, i) {
let currentGauge = svgGauges[i];
let gauge = currentGauge.querySelector(".gaugePercent");
let dashGap = gauge.getAttribute("stroke-dasharray").split(" ")[1];
// console.log(gauge);
gauge.setAttribute("stroke-dasharray", percent + " " + dashGap);
gauge.setAttribute("style", "animation-fill-mode: none");
percentText.textContent = percent;
});
}
});
.gaugeWrap {
display: inline-block;
width: 10rem;
}
.layout {
width: 50%;
margin: 0 auto;
display: flex;
justify-content: center;
}
.txt-cnt {
text-align: center;
}
.circle {
transition: 0.3s;
stroke-width: 15;
}
.linecap-round .circle {
stroke-linecap: round;
shape-rendering: geometricPrecision;
}
.linecap-round .circle[stroke-dasharray^="0 "] {
stroke-linecap: unset;
}
<p class="txt-cnt">Progress (<span class="percentText">50</span> %) <input id="progress" style="width:100px" type="range" min="0" max="100" step="10" value="50" />
</p>
<div class="layout">
<div class="gaugeWrap">
<p>horse shoe gauge 270°</p>
<svg class="svgGauge linecap-round" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg" transform="scale(-1 1) rotate(-225) ">
<circle class="circle gaugeBG" id="gaugeBG" cx="50%" cy="50%" r="45" pathLength="133.333" fill="none" stroke="#000" stroke-dasharray="100 100" />
<circle class="circle gaugePercent " id="gauge" cx="50%" cy="50%" r="45" pathLength="133.333" fill="none" stroke-dasharray="50 133.333" stroke="#e9ad61" />
</svg>
</div>
<div class="gaugeWrap">
<p>Semi-circle gauge 180°</p>
<svg class="svgGauge linecap-round" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg" transform="scale(-1 1) rotate(-180)">
<circle class="circle gaugeBG " id="gaugeBG" cx="50%" cy="50%" r="45" pathLength="200" fill="none" stroke="#000" stroke-dasharray="100 200" />
<circle class="circle gaugePercent" id="gauge" cx="50%" cy="50%" r="45" pathLength="200" fill="none" stroke-dasharray="50 200" stroke="#e9ad61" />
</svg>
</div>
<div class="gaugeWrap">
<p>Full-circle gauge 360°</p>
<svg class="svgGauge" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg" transform="rotate(-90)">
<circle class="circle gaugeBG" id="gaugeBG" cx="50%" cy="50%" r="45" pathLength="100" fill="none" stroke="#000" stroke-dasharray="100 100" />
<circle class="circle gaugePercent" id="gauge" cx="50%" cy="50%" r="45" pathLength="100" fill="none" stroke-linecap="butt" stroke-dasharray="50 100" stroke="#e9ad61" />
</svg>
</div>
</div>
Your example has approximately a 270° range (3/4 of 360°).
By setting pathLength
to 133 (360/270*100) we change the computation of the dash lengths.
Since we don't use the complete circumference of the circle (see the full circle example with pathLength=100) we increase the pathlength to make this 3/4 segment to have a length of 100 units.
We can set the first stroke-dasharray
value e.g. to 50 (display 50% progress).
The 2nd value 133 ensures the dash gap is large enough to fill the rest of the circle gauge.
To make the horse shoe gauge stand upright we need to calculate a rotation like this:
(360 + 270)/2 - 90 = -225
So we can rotate the parent svg by setting the transform attribute totransform="scale(-1 1) rotate(-225)"
Solution 2:[2]
an idea can be to use pathLength="100"
to your circle
that allow you to give a percent in the attribute stroke-dashoffset with 100% - {percent of circle to fill}
then we can imagine rotate the circle to the correct shape
#mySvg {
transform: rotate(-125deg) scaleX(-1);
}
to round the border of your line you can use
stroke-linecap: round;
#mySvg {
transform: rotate(-125deg) scaleX(-1);
}
#mySvg circle {
stroke-linecap: round;
shape-rendering: geometricPrecision;
}
<svg id="mySvg" width="4.5rem" height="4.5rem" viewBox="0 0 40 40">
<circle class="pieSegment segment1" cx="20" cy="20" r="15.915494309189533" fill="transparent" stroke="#1a0d1c" stroke-dashoffset="20" stroke-dasharray="100" stroke-width="5" pathLength="100"></circle>
<circle class="pieSegment segment3" cx="20" cy="20" r="15.915494309189533" fill="transparent" stroke="#e9ad61" stroke-dashoffset="80" stroke-dasharray="100" stroke-width="5" pathLength="100"></circle>
</svg>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |