Home > front end >  css/html- to create a circle with a hole in the bottom
css/html- to create a circle with a hole in the bottom

Time:02-11

enter image description here

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>&thinsp;%) <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 pathLengthto 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)"

Gauge generator pen

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>

  • Related