Javascript svg / d3.js 矩形一个角上的圆角
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12115691/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
svg / d3.js rounded corner on one corner of a rectangle
提问by user1167650
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.
我知道 svg 有一个内置函数来做圆角,但我只需要在四个角中的两个角上做圆角。
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?
我知道我可以在彼此之上绘制多个矩形来模仿它,但这似乎有点俗气。有什么办法可以使用剪辑或任何 d3.js 方法来做到这一点?
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.
我试图在矩形的右侧产生圆角,但不知道该怎么做。
回答by mbostock
Expanding on @robert-longson's answer, you can use SVG's elliptical arc commandsto make the corners, in conjunction with lineto commandsfor the straight edges. These are used with path elements. Here's one possible implementation:
扩展@robert-longson 的答案,您可以使用 SVG 的椭圆弧命令来制作角,并结合lineto 命令来制作直边。这些与路径元素一起使用。这是一种可能的实现:
// 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:
然后,您可以调用此函数来计算“d”属性。例如:
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:
可选:如果您愿意,可以重构 rightRoundedRect 函数以使其可配置,而不是采用大量参数。这种方法类似于 D3 的内置形状生成器。例如,您可以像这样使用 rect 生成器:
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.
有关该方法的更多详细信息,请参阅可配置函数教程。
回答by stackmate
Just to expand on the answers given, here is a more comprehensive function to return the path for your rect.
只是为了扩展给出的答案,这里有一个更全面的函数来返回你的 rect 的路径。
x: x-coordinate
y: y-coordinate
w: width
h: height
r: corner radius
tl: top_left rounded?
tr: top_right rounded?
bl: bottom_left rounded?
br: bottom_right rounded?
function rounded_rect(x, y, w, h, r, tl, tr, bl, br) {
var retval;
retval = "M" + (x + r) + "," + y;
retval += "h" + (w - 2*r);
if (tr) { retval += "a" + r + "," + r + " 0 0 1 " + r + "," + r; }
else { retval += "h" + r; retval += "v" + r; }
retval += "v" + (h - 2*r);
if (br) { retval += "a" + r + "," + r + " 0 0 1 " + -r + "," + r; }
else { retval += "v" + r; retval += "h" + -r; }
retval += "h" + (2*r - w);
if (bl) { retval += "a" + r + "," + r + " 0 0 1 " + -r + "," + -r; }
else { retval += "h" + -r; retval += "v" + -r; }
retval += "v" + (2*r - h);
if (tl) { retval += "a" + r + "," + r + " 0 0 1 " + r + "," + -r; }
else { retval += "v" + -r; retval += "h" + r; }
retval += "z";
return retval;
}
回答by duhaime
In case others end up here wanting to round allcorners of a rect
element, you can add an rx
attribute to the rect
element (as @mbostock mentions in his fiddle above):
如果其他人最终想要绕过元素的所有角落rect
,您可以rx
向rect
元素添加一个属性(正如@mbostock 在上面的小提琴中提到的那样):
var rectangle = group.append("rect")
.attr("width", 60)
.attr("height", 75)
.attr("rx", 4)
.style("fill", function(d) { return "#e6653e"; })
.style("stroke", function(d) { return d3.rgb("#e6653e").darker(); })
回答by Barna Burom
Anyone who looks for an Eslinted version of stackmate -s answer:
任何寻找 Eslinted 版本的 stackmate -s 的人都会回答:
function roundedRect(x, y, w, h, r, tl, tr, bl, br) {
let retval;
retval = `M${x + r},${y}`;
retval += `h${w - (2 * r)}`;
if (tr) {
retval += `a${r},${r} 0 0 1 ${r},${r}`;
} else {
retval += `h${r}`; retval += `v${r}`;
}
retval += `v${h - (2 * r)}`;
if (br) {
retval += `a${r},${r} 0 0 1 ${-r},${r}`;
} else {
retval += `v${r}`; retval += `h${-r}`;
}
retval += `h${(2 * r) - w}`;
if (bl) {
retval += `a${r},${r} 0 0 1 ${-r},${-r}`;
} else {
retval += `h${-r}`; retval += `v${-r}`;
}
retval += `v${((2 * r) - h)}`;
if (tl) {
retval += `a${r},${r} 0 0 1 ${r},${-r}`;
} else {
retval += `v${-r}`; retval += `h${r}`;
}
retval += 'z';
return retval;
}
回答by Jon Portella
I found myself with this problem recently in order to do a bar chart with top rounded corners in d3. I made a codesandbox demoof the solution I found.
我最近发现自己遇到了这个问题,以便在 d3 中制作带有顶部圆角的条形图。我做了一个我找到的解决方案的代码和盒子演示。