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.