I know svg has an in built function to do rounded corners, but I need to do rounded corners on only 2 of the four corners.
I know I can draw multiple rectangles on top of each other to imitate that, but that seems kind of cheesy. Any way to do it using clipping or any d3.js method?
Right now I have a horizontal bar graph that has rects like:
rects.enter().append("rect") .attr("x",function(d,i) { return x(0); }) .attr("width",function(d) { return x(d.value) - x(0); }) .attr("height",y.rangeBand()) .attr("y",function(d) { return y(d.name); })
I'm trying to produce rounded corners on the right hand side of the rect, but not sure how to do it.
To draw a rectangle in HTML SVG, use the SVG <rect> element. For rounded corners, set the rx and ry attribute, which rounds the corners of the rectangle.
Expanding on @robert-longson's answer, you can use SVG's elliptical arc commands to make the corners, in conjunction with lineto commands for the straight edges. These are used with path elements. Here's one possible implementation:
// Returns path data for a rectangle with rounded right corners. // The top-left corner is ⟨x,y⟩. function rightRoundedRect(x, y, width, height, radius) { return "M" + x + "," + y + "h" + (width - radius) + "a" + radius + "," + radius + " 0 0 1 " + radius + "," + radius + "v" + (height - 2 * radius) + "a" + radius + "," + radius + " 0 0 1 " + -radius + "," + radius + "h" + (radius - width) + "z"; }
You can then call this function to compute the "d" attribute. For example:
rects.enter().append("path") .attr("d", function(d) { return rightRoundedRect(x(0), y(d.name), x(d.value) - x(0), y.rangeBand(), 10); });
Live example:
Optional: If you like, you could refactor the rightRoundedRect function to make it configurable, rather than taking lots of arguments. This approach would be similar to D3's built-in shape generators. For example, you might use a rect generator like so:
rects.enter().append("path") .attr("d", rightRoundedRect() .x(x(0)) .y(function(d) { return y(d.name); }) .width(function(d) { return x(d.value) - x(0); }) .height(y.rangeBand()) .radius(10));
For more details on that approach, see the configurable function tutorial.
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