简体   繁体   中英

Round edges at the ends of radial progress bar

I'm using d3.js to create a radial progress bar i have achieved that but the problem which I'm facing is that I'm unable to create the round edges of each side Im attaching the image of the output and the expected change in output as well.

Below is thee code that I'm using to create the radial progress bar

<script src="https://d3js.org/d3.v6.min.js"></script>
<style>
  .progress {
      display: inline-block;
      padding: 20px;
  }

  .radial-progress { 
    &__text {
      font-family: Arial, sans-serif;
      font-size: 2rem;
      font-weight: bold;
    }  
  }
</style>

<div style="background:#2E98C5" class="background">
<div
  data-text-colour="#2E98C5" //Text color
  class="progress"> 
</div>

</div>
<script>
var renderProgress = function(el,background) {

    //Note: i have kept the track color to be same as the background color so that
    //      it seems that there is no track

  var start = 0;
  //var background='#2E98C5';
  var actual_count=12;
  var total_count=20;
  var end = (actual_count/total_count)*100;
  //var end = el.dataset.progress;
  
  var colours = {
    fill: "white",                          //common for both 
    //track: '#' + el.dataset.trackColour,
    text:  el.dataset.textColour,
    //stroke: '#' + el.dataset.strokeColour,
  }
  
  var radius = 68;
  var border = 8;
  var strokeSpacing = el.dataset.strokeSpacing;
  var endAngle = Math.PI * 2;
  var formatText = d3.format('.0%');
  var boxSize = radius * 2;
  var count = end;
  var progress = start;
  var step = end < start ? -0.01 : 0.01;
  
  //Define the circle
  var circle = d3.arc()
    .startAngle(0)
    .innerRadius(radius)
    .outerRadius(radius - border);
  
  //setup SVG wrapper
  var svg = d3.select(el)
    .append('svg')
    .attr('width', boxSize)
    .attr('height', boxSize);
  
  // ADD Group container
  var g = svg.append('g')
    .attr('transform', 'translate(' + boxSize / 2 + ',' + boxSize / 2 + ')');
  
  //Setup track
  var track = g.append('g').attr('class', 'radial-progress');
  track.append('path')
    .attr('class', 'radial-progress__background')
    .attr('fill', background)
    .attr('stroke', colours.stroke)
    .attr('stroke-width',  '0px')
    .attr('d', (end/100)*360);
    //.attr('d', circle.endAngle(endAngle));
  
  //Add colour fill
  var value = track.append('path')
    .attr('class', 'radial-progress__value')
    .attr('fill', colours.fill)
    .attr('stroke', colours.stroke)
    .attr('stroke-width', strokeSpacing + 'px');
  
  
  //This circle is just created to give the effect of border over circle  
  var numberText = track.append('circle')
    .attr('fill', "#DBDBDB")        // This colr is constant in bot the control design
    .attr('dy', '.5rem')
    .attr('r', 51);

    //Add circle
  var numberText = track.append('circle')
    .attr('fill', "white")                    //This
    .attr('dy', '.5rem')
    .attr('r', 48);
    
  
  //Add text value
  var numberText = track.append('text')
    .attr('class', 'radial-progress__text')
    .attr('fill', colours.text)
    .text( function (d) {
                
                return actual_count.toString() +"/" +total_count.toString();
            })//Pass the value that should be at the centre
    .attr('font-size', '30px')
    .attr('text-anchor', 'middle')
    .attr('dy', '.5rem');
  
  function update(progress) {
    //update position of endAngle
    value.attr('d', circle.endAngle(-(endAngle * progress)));// -ve so that it goes left to right
    //update text value
    //numberText.text(formatText(progress));
    //numberText.text(actual_count.toString() +"/" +total_count.toString()); //Puts the text in the center
  };
  
  function iterate() {
    //call update to begin animation
    update(progress);
    
    if (count > 0) {
      //reduce count till it reaches 0
      count--;
      //increase progress
      progress += step;
      //Control the speed of the fill
      setTimeout(iterate, 10);
    }
  };
  
  iterate();
}

Array.prototype.slice.call(document.querySelectorAll('.progress')).forEach(el => {
  renderProgress(el,'#2E98C5');
});
</script>

在此处输入图片说明

I have taken the image from some other source as it has highlighted the thing that I want to do . Thanks in advance any help or guidance will be great.

Edit 1 : As per adrew Reid suggestion I was able to make to work and below is the code which worked

<script src="https://d3js.org/d3.v6.min.js"></script>
<style>
  .progress {
      display: inline-block;
      padding: 20px;
  }

  .radial-progress { 
    &__text {
      font-family: Arial, sans-serif;
      font-size: 2rem;
      font-weight: bold;
    }  
  }
</style>

<div style="background:#2E98C5" class="background">
<div
  data-text-colour="#2E98C5" //Text color
  class="progress"> 
</div>

</div>
<script>
var renderProgress = function(el,background) {

    //Note: i have kept the track color to be same as the background color so that
    //      it seems that there is no track

  var start = 0;
  //var background='#2E98C5';
  var actual_count=12;
  var total_count=20;
  var end = (actual_count/total_count)*100;
  //var end = el.dataset.progress;
  
  var colours = {
    fill: "white",                          //common for both 
    //track: '#' + el.dataset.trackColour,
    text:  el.dataset.textColour,
    //stroke: '#' + el.dataset.strokeColour,
  }
  
  var radius = 68;
  var border = 8;
  var strokeSpacing = el.dataset.strokeSpacing;
  var endAngle = Math.PI * 2;
  var formatText = d3.format('.0%');
  var boxSize = radius * 2;
  var count = end;
  var progress = start;
  var step = end < start ? -0.01 : 0.01;
  
  //Define the circle
  var circle = d3.arc()
    .startAngle(0)
    .innerRadius(radius)
    .outerRadius(radius - border)
    .cornerRadius(12);
  
  //setup SVG wrapper
  var svg = d3.select(el)
    .append('svg')
    .attr('width', boxSize)
    .attr('height', boxSize);
  
  // ADD Group container
  var g = svg.append('g')
    .attr('transform', 'translate(' + boxSize / 2 + ',' + boxSize / 2 + ')');
  
  //Setup track
  var track = g.append('g').attr('class', 'radial-progress');
  track.append('path')
    .attr('class', 'radial-progress__background')
    .attr('fill', background)
    .attr('stroke', colours.stroke)
    .attr('stroke-width',  '0px')
    .attr('d', (end/100)*360);
    //.attr('d', circle.endAngle(endAngle));
  
  //Add colour fill
  var value = track.append('path')
    .attr('class', 'radial-progress__value')
    .attr('fill', colours.fill)
    .attr('stroke', colours.stroke)
    .attr('stroke-width', strokeSpacing + 'px');
  
  
  //This circle is just created to give the effect of border over circle  
  var numberText = track.append('circle')
    .attr('fill', "#DBDBDB")        // This colr is constant in bot the control design
    .attr('dy', '.5rem')
    .attr('r', 51);

    //Add circle
  var numberText = track.append('circle')
    .attr('fill', "white")                    //This
    .attr('dy', '.5rem')
    .attr('r', 48);
    
  
  //Add text value
  var numberText = track.append('text')
    .attr('class', 'radial-progress__text')
    .attr('fill', colours.text)
    .text( function (d) {
                
                return actual_count.toString() +"/" +total_count.toString();
            })//Pass the value that should be at the centre
    .attr('font-size', '30px')
    .attr('text-anchor', 'middle')
    .attr('dy', '.5rem');
  
  function update(progress) {
    //update position of endAngle
    value.attr('d', circle.endAngle(-(endAngle * progress)));// -ve so that it goes left to right
    //update text value
    //numberText.text(formatText(progress));
    //numberText.text(actual_count.toString() +"/" +total_count.toString()); //Puts the text in the center
  };
  
  function iterate() {
    //call update to begin animation
    update(progress);
    
    if (count > 0) {
      //reduce count till it reaches 0
      count--;
      //increase progress
      progress += step;
      //Control the speed of the fill
      setTimeout(iterate, 10);
    }
  };
  
  iterate();
}

Array.prototype.slice.call(document.querySelectorAll('.progress')).forEach(el => {
  renderProgress(el,'#2E98C5');
});
</script>

You can use css option for this class="radial-progress__value" in your style:

.radial-progress__value {
  stroke-linecap: round;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM