I'm using D3.js's built-in arc function to generate SVG <path>s for my data.
.attr("d", function(element, index) {
var arc = d3.arc()
.innerRadius(iR)
.outerRadius(iR + 10)
.startAngle(element[1])
.endAngle(element[2])
.cornerRadius(isRounded ? cR : 0);
return arc();
});
This works perfectly, but I'd like to round one side (both corners) of certain arcs. When a corner radius is supplied with .cornerRadius(), however, it rounds all four corners.
I know there are various ways to selectively round the corners of rectangles, but I'm hoping there's some generic way to do this for arcs.
I also saw this question about rounding only some corners of an arc, but it has no answer (and D3 v4 has come out since it was posted).
Even with the v4 API, still no straight-forward way to do this. Looking at the source code, the cornerRadius becomes a fixed value for the calculation of the whole arc (all 4 corners). Easiest fix is to just append two arcs for every data point with the 2nd arc just filling in the corners.
Example, say we have this nicely rounded arcs:
var myArcs = [
[0, 45],
[180, 300]
];
var vis = d3.select('body')
.append('svg')
.attr('width', 400)
.attr('height', 400);
var arc = d3.arc()
.innerRadius(80)
.outerRadius(150)
var someArcs = vis.selectAll('path')
.data(myArcs)
.enter();
someArcs
.append("path")
.attr("transform", "translate(200,200)")
.attr("d", function(d) {
arc.startAngle(d[0] * (Math.PI / 180))
.endAngle(d[1] * (Math.PI / 180))
.cornerRadius(20);
return arc();
})
.attr("fill", function(d, i) {
return d3.schemeCategory10[i];
});
<script data-require="[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
My fix would look like:
var myArcs = [
[0, 45],
[180, 300]
];
var vis = d3.select('body')
.append('svg')
.attr('width', 400)
.attr('height', 400);
var arc = d3.arc()
.innerRadius(80)
.outerRadius(150)
var someArcs = vis.selectAll('path')
.data(myArcs)
.enter();
someArcs
.append("path")
.attr("transform", "translate(200,200)")
.attr("d", function(d) {
arc.startAngle(d[0] * (Math.PI / 180))
.endAngle(d[1] * (Math.PI / 180))
.cornerRadius(20);
return arc();
})
.attr("fill", function(d, i) {
return d3.schemeCategory10[i];
});
someArcs
.append("path")
.attr("transform", "translate(200,200)")
.attr("d", function(d) {
arc.startAngle(d[0] * (Math.PI / 180))
.endAngle((d[0] + 10) * (Math.PI / 180))
.cornerRadius(0);
return arc();
})
.attr("fill", function(d, i) {
return d3.schemeCategory10[i];
});
<script data-require="[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With