JavaScript Add border-radius property to D3js Donut Chart border radius property in css,border radius property in bootstrap

I have this donut chart currently working in an AngularJS app:

enter image description here

But the design mockup says we would like this, note the border-radius property on the green portion of the arc:

enter image description here

How do I add a border-radius to the SVG that d3js outputs, the code I'm currently using looks like this:

let data = [
    {
        label: 'Data',
        count: scope.data
    },
    {
        label: 'Fill',
        count: 100 - scope.data
    }
];

let width = 60;
let height = 60;
let radius = Math.min(width, height) / 2;
let color = d3.scale
    .ordinal()
    .range(['#3CC692', '#F3F3F4']);
let selector = '#donut-asset-' + scope.chartId;

d3
    .select(selector)
    .selectAll('*')
    .remove();

let svg = d3
    .selectAll(selector)
    .append('svg')
    .attr('width', width)
    .attr('height', height)
    .append('g')
    .attr(
        'transform',
        'translate(' + width / 2 + ',' + height / 2 + ')'
    );
let arc = d3.svg
    .arc()
    .innerRadius(23)
    .outerRadius(radius);
let pie = d3.layout
    .pie()
    .value(function(d) {
        return d.count;
    })
    .sort(null);
let path = svg
    .selectAll('path')
    .data(pie(data))
    .enter()
    .append('path')
    .attr('d', arc)
    .attr('fill', function(d, i) {
        return color(d.data.label);
    });
let legend = svg
    .selectAll('.legend')
    .data(data)
    .enter()
    .append('g')
    .attr('class', 'legend')
    .attr('transform', function(d, i) {
        return 'translate(' + 0 + ',' + 0 + ')';
    });
legend
    .append('text')
    .attr('x', 1)
    .attr('y', 1)
    .attr('text-anchor', 'middle')
    .attr('dominant-baseline', 'central')
    .text(function(d) {
        return d.count + '%';
    });

};

I know to use cornerRadius but when I do it sets a radius for both arcs, it just needs to exist on the colored one. Any ideas? Thanks in advance for any help!

Answer:1

You can apply a corner radius to a d3 arc which allows rounding on the corners:

let arc = d3.svg
    .arc()
    .innerRadius(23)
    .outerRadius(radius)
    .cornderRadius(10);

But, the downside is that all arcs' borders are rounded:

enter image description here

If you apply the cornerRadius to only the darkened arc - the other arc won't fill in the background behind the rounded corners. Instead, we could append a circular arc (full donut) and place the darkened arc on top with rounding (my example doesn't adapt your code, just shows how that it can be done, also with d3v4 which uses d3.arc() rather than d3.svg.arc() ):

var backgroundArc = d3.arc()
  .innerRadius(30)
  .outerRadius(50)
  .startAngle(0)
  .endAngle(Math.PI*2);
  
var mainArc = d3.arc()
  .innerRadius(30)
  .outerRadius(50)
  .cornerRadius(10)
  .startAngle(0)
  .endAngle(function(d) { return d/100*Math.PI* 2 });
  
var data = [10,20,30,40,50] // percents.
  
var svg = d3.select("body").append("svg")
  .attr("width", 600)
  .attr("height", 200);
  
var charts = svg.selectAll("g")
  .data(data)
  .enter()
  .append("g")
  .attr("transform",function(d,i) { 
     return "translate("+(i*100+50)+",100)";
  });
  
charts.append("path")
  .attr("d", backgroundArc)
  .attr("fill","#ccc")

charts.append("path")
  .attr("d", mainArc) 
  .attr("fill","orange")
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
Answer:2

I am using bootstrap datetimepicker have to get the datetime and add days to it var get_date_time = Friday, October 23rd 2015, 12:00:00 am format get_date_time to oct 25 2015 12:00:00 am how to ...

I am using bootstrap datetimepicker have to get the datetime and add days to it var get_date_time = Friday, October 23rd 2015, 12:00:00 am format get_date_time to oct 25 2015 12:00:00 am how to ...

I have a simple list that binds two-way to a parameter hero in hero.component.ts. Though when I start typing in the input field it loses focus and I have to click it again. What am I supposed to do ...

I have a simple list that binds two-way to a parameter hero in hero.component.ts. Though when I start typing in the input field it loses focus and I have to click it again. What am I supposed to do ...

  1. input loses focus react
  2. input loses focus when typing react
  3. input loses focus when typing
  4. input loses focus when typing angular
  5. input loses focus
  6. input loses focus angular
  7. input loses focus on click
  8. input loses focus react native
  9. input loses focus javascript
  10. input loses focus angularjs
  11. input loses focus html
  12. react input loses focus on change
  13. react input loses focus on rerender
  14. input field loses focus
  15. react input loses focus on render
  16. react input loses focus on setstate
  17. vue input loses focus
  18. formik input loses focus
  19. jquery input loses focus
  20. ngfor input loses focus

I found that ng-init is not updated after rowIndex is updated. <div ng-init="item = getItem(rowIndex)"> {{ item.Name }} </div> item is not updated after rowIndex is changed (even if ...

I found that ng-init is not updated after rowIndex is updated. <div ng-init="item = getItem(rowIndex)"> {{ item.Name }} </div> item is not updated after rowIndex is changed (even if ...

  1. update-initramfs force

I am in process of researching how to measure the performance metrics of an Angular JS applications. I have following questions. Please share your thoughts. Angular JS suits well for one page ...

I am in process of researching how to measure the performance metrics of an Angular JS applications. I have following questions. Please share your thoughts. Angular JS suits well for one page ...

  1. measure performance angular
  2. measure performance angular 2
  3. measure performance angular 4