Search code examples
csssvgfill

SVG <circle> fill covering previous circle


I'm building an svg circular progress graph.

I'm trying to style my svg's stroke to match the visible part of circle.center but when I change the stroke of circle.progress it does not shrink the circle's fill enough to show the black part of circle.progress and match the width of the actual progress bar.

<svg width="300" height="300">
    <circle class="progress" id="progress-radial-1" r="125"/>
    <circle class="center" r="140" cx="140" cy="140" />
    <text text-anchor="middle" x="150" y="185" />
</svg>

Here is a fiddle: https://jsfiddle.net/BenRacicot/2kc7c56j/

Here is the svg's outcome (left): enter image description here I'm trying to get the results on the right. As you can see the circle.center which controls the blue progress bar (at 50%) also has a fill which is white in the image (gray in fiddle) and covers the black svg stroke too much. I need that stroke to be the same width of the blue.


Solution

  • center and progress circle has different origin and should have the same (now set to 150).

    The center has now 25px smaller radius than progress, to fit inside its stroke.

    So if you update the markup like this, change the fill for center to #ddd and change the svg background to #000 you will get the layout you want

    <div class="pie-wrapper">
      <svg width="300" height="300">
        <circle class="progress" id="pr1" r="125" cx="150" cy="150"/>
        <circle class="center" r="100" cx="150" cy="150" />
        <text text-anchor="middle" x="150" y="175" />
      </svg>
    </div>
    

    Updated fiddle

    Stack snippet

    window.addEventListener('load', function() {
      function radialProgress(update, id){
        let rd = document.getElementById(id).getAttribute("r"); 
        let i = 0;
        let a = 0;
        let x = rd * 2 * Math.PI;
        i = update;
        a = i / 100;
        let p = x * a;
    
        jQuery(".progress").attr("stroke-dasharray", p + ", " + x);
        jQuery(".progress").attr("stroke", "#0065a4");
        jQuery("text").text(update + "%");
      }
    
      radialProgress(50, 'pr1');
    })
    .pie-wrapper{
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%,-50%);
    }
        .pie-wrapper svg {
            background: #000;
            border-radius: 50%;
        }
    
    .progress {
        stroke-width: 50;
        transform: rotate(-90deg);
        transform-origin: 50% 50%;
    }
    
    .center {
        fill: #ddd;
    }
    
    text {
        fill: #fff;
        font-family: 'Share Tech Mono';
        font-size: 80px;
    }
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    
    <div class="pie-wrapper">
      <svg width="300" height="300">
        <circle class="progress" id="pr1" r="125" cx="150" cy="150"/>
        <circle class="center" r="100" cx="150" cy="150" />
        <text text-anchor="middle" x="150" y="175" />
      </svg>
    </div>


    Note, it is the progress circle which controls the blue progress bar (at 50%), not the center, and the black svg doesn't have a stroke, it has (had) only a dark gray background.