Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

svg / d3.js rounded corner on one corner of a rectangle

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.

like image 289
user1167650 Avatar asked Aug 24 '12 19:08

user1167650


People also ask

How do you round SVG corners?

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.


1 Answers

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:

  • http://bl.ocks.org/3468167

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.

like image 150
mbostock Avatar answered Oct 01 '22 09:10

mbostock