我可以在SVG组之间移动SVG元素 - 不需要在幕后进行太多计算,也不在我自己的代码中制作太多代码吗? d3 api documentation提到您无法重新附加已删除的元素(?)。
在将元素从原始组中删除后重新创建元素 - 在我的代码中似乎很麻烦,对于d3和浏览器而言,如果可能的话,它可能会更加昂贵。
这也与在将元素与组关联之前定义元素有关,而不仅仅是为了在组之间真正移动元素(即,将元素从非组移动到组)。
答案 0 :(得分:14)
docs you posted还提到您可以通过将函数传递给.append
或.insert
来重新添加元素。这就是它所说的:
请注意,目前没有专门的API可以将删除的元素添加回文档;但是,您可以将函数传递给selection.append或selection.insert以重新添加元素。
由于在选择上使用.remove
会返回该选择,您可以将删除的元素存储在变量中,然后使用.append
selection.node()
将其存储到新组中以获取DOM元素来自删除的选择:
var removed = yourSelection.remove();
yourTargetGroup.append(function() {
return removed.node();
});
这是一个简单的Fiddle,它使用此技术在点击处理程序中将圆元素从一个组移动到另一个组。
答案 1 :(得分:2)
仅在DOM树中的现有节点上移动,不必先删除它们,然后将这些相同的节点重新附加到不同位置即可。 d3.append()
internally使用Node.appendChild()
,其工作原理如下:
如果给定的子项是对文档中现有节点的引用,则
appendChild()
将其从其当前位置移动到新位置(在将其附加到父节点之前,无需从其父节点中删除该节点。其他节点)。这意味着节点不能同时在文档的两个点中。因此,如果该节点已经具有父节点,则首先将其删除,然后将其附加在新位置。
正如其他答复者已经提到的,selection.append()
和selection.insert()
在传递时将分别附加或插入该函数返回的节点。知道这一点,将DOM节点从当前位置移动到新目标所需的全部时间
target.append(() => existingNode); // target is a D3 selection, existingNode is a native DOM node
将其保存在工具箱中,一次在多个节点之间移动也相当容易:
selectionToBeMoved.each(function() { target.append(() => this); });
看看下面的演示,看看它的实际效果。用Aquamarine
上色的两个圆圈从#g1
组移到#g2
组。
const current = d3.select("#g1");
const target = d3.select("#g2");
current.selectAll("circle[fill=Aquamarine]")
.each(function() { target.append(() => this); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.15.0/d3.min.js"></script>
<svg>
<g id="g1">
<circle cx="100" cy="100" r="20" fill="Aquamarine" />
<circle cx="150" cy="100" r="20" fill="HotPink" />
<circle cx="200" cy="100" r="20" fill="Aquamarine" />
</g>
<g id="g2">
</g>
</svg>
答案 2 :(得分:1)
你不能在D3中这样做,但是JQuery有.appendTo()
function,例如。
$("#element").appendTo("#otherGroup");
答案 3 :(得分:0)
也许您可以使用多个元素来做到这一点:
d3.select('#btn').on('click', function() {
circle.remove()
.each(function(){
group2.node().appendChild(d3.select(this).node());
});
});