agi*_*ur5 4 javascript svg d3.js
我有一个SVG组,其内部有一个rect,并希望rect作为该组的边界...
<g>
<rect></rect>
</g>
Run Code Online (Sandbox Code Playgroud)
但该群体是动态的,其内容也在变化.我试图在我的更新功能中调整rect的大小
.attr("x", function(d) { return this.parentNode.getBBox().x })
.attr("y", function(d) { return this.parentNode.getBBox().y })
.attr("width", function(d) { return this.parentNode.getBBox().width })
.attr("height", function(d) { return this.parentNode.getBBox().height })
Run Code Online (Sandbox Code Playgroud)
但似乎发生的事情是它扩展得相对较好,但是由于组的边界框宽度现在与扩展的rect的宽度相同(矩形的宽度是组的宽度,但是组的宽度现在是矩形的宽度),因此无法正确收缩).
有没有办法让SVG组内的矩形正确调整大小并充当边框?
解决这个问题的方法不止一种.
使用该outline属性(2014-08-05状态:适用于Chrome和Opera)
<svg xmlns="http://www.w3.org/2000/svg" width="500px" height="500px">
<g style="outline: thick solid black; outline-offset: 10px;">
<circle cx="50" cy="60" r="20" fill="yellow"/>
<rect x="80" y="80" width="200" height="100" fill="blue"/>
</g>
</svg>
Run Code Online (Sandbox Code Playgroud)
查看实例.
使用a filter来生成边框(2014-08-05状态:在Firefox中有效,但Chrome/Opera有关于feMorphology 的错误,但应该可以通过使用其他过滤器基元来解决这个问题).
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<defs>
<filter id="border" x="-5%" y="-5%" width="110%" height="110%">
<feFlood flood-color="black" result="outer"/>
<feMorphology operator="erode" radius="2" in="outer" result="inner"/>
<feComposite in="inner" in2="outer" operator="xor"/>
<feComposite in2="SourceGraphic"/>
</filter>
</defs>
<g filter="url(#border)">
<circle cx="50" cy="60" r="20" fill="yellow"/>
<rect x="80" y="80" width="200" height="100" fill="blue"/>
</g>
</svg>
Run Code Online (Sandbox Code Playgroud)
查看实例.
以上两者都将自动更新为该组具有的任何大小,而无需进行DOM修改.
是的,您可以通过选择组中所有不是边界矩形本身的子元素,然后根据子项的各个边界框计算整体边界框来找到新的边界框。
假设您的边界矩形有一类bounding-rect,您可以执行以下操作:
function updateRect() {
// SELECT ALL CHILD NODES EXCEPT THE BOUNDING RECT
var allChildNodes = theGroup.selectAll(':not(.bounding-rect)')[0]
// `x` AND `y` ARE SIMPLY THE MIN VALUES OF ALL CHILD BBOXES
var x = d3.min(allChildNodes, function(d) {return d.getBBox().x;}),
y = d3.min(allChildNodes, function(d) {return d.getBBox().y;}),
// WIDTH AND HEIGHT REQUIRE A BIT OF CALCULATION
width = d3.max(allChildNodes, function(d) {
var bb = d.getBBox();
return (bb.x + bb.width) - x;
}),
height = d3.max(allChildNodes, function(d) {
var bb = d.getBBox();
return (bb.y + bb.height) - y;
});
// UPDATE THE ATTRS FOR THE RECT
svg.select('.bounding-rect')
.attr('x', x)
.attr('y', y)
.attr('width', width)
.attr('height', height);
}
Run Code Online (Sandbox Code Playgroud)
这会将整个边界框的 x 和 y 值设置为儿童边界框中的最小 x 和 y 值。然后通过找到最大右边界bb.x + bb.width并减去整个框的x来计算整体宽度。然后以与宽度相同的方式计算总高度。
这里是一个例子。
最简单的跨浏览器兼容方法是实现边框,rect就像我一样使用 a ,但将其放置在组之外,正如 @Duopixel 在他的评论中提到的。由于它仍然由边界框定位,因此它将具有正确的宽度、高度、x 和 y。
<rect></rect>
<g></g>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3379 次 |
| 最近记录: |