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 cx="20" cy="20" r="15.915494309189533" fill="transparent" stroke="#1a0d1c" stroke-dashoffset="11" stroke-dasharray="74" stroke-width="5"></circle>
<circle cx="20" cy="20" r="15.915494309189533" fill="transparent" stroke="#e9ad61" stroke-dashoffset="14" stroke-dasharray="25 75" stroke-width="5"></circle>
</svg>
CodePudding user response:
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 >Progress (<span >50</span> %) <input id="progress" style="width:100px" type="range" min="0" max="100" step="10" value="50" />
</p>
<div >
<div >
<p>horse shoe gauge 270°</p>
<svg viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg" transform="scale(-1 1) rotate(-225) ">
<circle id="gaugeBG" cx="50%" cy="50%" r="45" pathLength="133.333" fill="none" stroke="#000" stroke-dasharray="100 100" />
<circle id="gauge" cx="50%" cy="50%" r="45" pathLength="133.333" fill="none" stroke-dasharray="50 133.333" stroke="#e9ad61" />
</svg>
</div>
<div >
<p>Semi-circle gauge 180°</p>
<svg viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg" transform="scale(-1 1) rotate(-180)">
<circle id="gaugeBG" cx="50%" cy="50%" r="45" pathLength="200" fill="none" stroke="#000" stroke-dasharray="100 200" />
<circle id="gauge" cx="50%" cy="50%" r="45" pathLength="200" fill="none" stroke-dasharray="50 200" stroke="#e9ad61" />
</svg>
</div>
<div >
<p>Full-circle gauge 360°</p>
<svg viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg" transform="rotate(-90)">
<circle id="gaugeBG" cx="50%" cy="50%" r="45" pathLength="100" fill="none" stroke="#000" stroke-dasharray="100 100" />
<circle 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 to
transform="scale(-1 1) rotate(-225)"
CodePudding user response:
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 cx="20" cy="20" r="15.915494309189533" fill="transparent" stroke="#1a0d1c" stroke-dashoffset="20" stroke-dasharray="100" stroke-width="5" pathLength="100"></circle>
<circle cx="20" cy="20" r="15.915494309189533" fill="transparent" stroke="#e9ad61" stroke-dashoffset="80" stroke-dasharray="100" stroke-width="5" pathLength="100"></circle>
</svg>