Javascript 将SVG容器中最顶端的对象推到底部

Javascript 将SVG容器中最顶端的对象推到底部,javascript,html,d3.js,svg,Javascript,Html,D3.js,Svg,我知道我想完成什么,但我不知道如何去做 背景:我有一个交互式报告,使用D3,它使用圆圈在按邮政编码绘制的美国地图上,按用户位置提供应用程序使用情况的可视化参考。在某些地方,这些圆圈重叠,模糊了下面的圆圈,并阻止下面的圆圈接收事件,例如鼠标悬停。这将创建一组圆 目标:我希望能够单击一个圆,将其推到堆栈的底部,尽管不在构成地图的任何背景对象下方。或者,在本示例中,不在.bg圆圈后面 下面是我在JSFIDLE中编写的一些示例代码,以说明这个问题 CSS: HTML 样本项目 您可以在d3v4中使用se

我知道我想完成什么,但我不知道如何去做

背景:我有一个交互式报告,使用D3,它使用圆圈在按邮政编码绘制的美国地图上,按用户位置提供应用程序使用情况的可视化参考。在某些地方,这些圆圈重叠,模糊了下面的圆圈,并阻止下面的圆圈接收事件,例如鼠标悬停。这将创建一组圆

目标:我希望能够单击一个圆,将其推到堆栈的底部,尽管不在构成地图的任何背景对象下方。或者,在本示例中,不在.bg圆圈后面

下面是我在JSFIDLE中编写的一些示例代码,以说明这个问题

CSS:

HTML

样本项目

您可以在d3v4中使用selection.lower或selection.raise在父元素中向上或向下移动DOM中的内容。selection.lower将在其父元素的底部放置一个元素,而selection.raise将在其父元素的顶部放置一个元素。因此,随着DOM的顺序设置svg元素的顺序,这些方法将改变svg元素的分层

因此,为了容易做到这一点,背景元素应该在一个单独的窗口中,以便它们不受影响。然后,只需根据需要在单击时提升或降低元素,代码段中的每个单击事件只会触发最顶端的元素:

d3.selectAllcircle .onclick,函数{ d3.选择this.lower; } A{填充:橙色;} B{填充:钢蓝;} C{填充:粉红色;} D{fill:lawngreen;}
应将背景圆隔离在单独的组中。这使事情变得更容易

Svg元素是按顺序绘制的,因此第一个元素将落后于其他元素。 从你的问题来看,不清楚你是想把圆圈画在后面还是放在childeNode数组的最后一个位置。我添加了两种解决方案

d3.选择All'.popCircle' .单击,功能正常{ var parent=this.parentNode; parent.removeChildthis; //插入后面 parent.insertBeforethis,parent.firstChild; //插在前面 //parent.appendChildthis; }; B.圆圈{ 填充:蓝色; 不透明度:.25 } popCircle先生{ 填充:绿色; 不透明度:0.5; 笔画:黑色; 笔画宽度:1px; } svg{ 边框:1px纯黑; }
这是一个针对D3 v3.x的解决方案,使用的是香草JavaScript:

d3.selectAll("circle")
    .on("click", function() {
        var firstChild = this.parentNode.firstChild;
        this.parentNode.insertBefore(this, firstChild);
    })
实际上,在D3V3中这样做的提示就在它本身!它说:

selection.lower:按顺序重新插入每个选定元素作为其父元素的第一个子元素。相当于:

selection.each(function() {
    this.parentNode.insertBefore(this, this.parentNode.firstChild);
});
下面是我在这里使用的演示:

d3.selectAllcircle .onclick,函数{ var firstChild=this.parentNode.firstChild; this.parentNode.insertBeforethis,firstChild; } A{ 填充物:橙色; } B{ 填充:钢蓝; } C{ 填充:粉红色; } D{ 填充:朗格林; }
令人惊叹的我需要使用D3V4,因为v3不支持lower。这意味着在更新我的报告之前有一段有趣的时光。否则,这就太完美了。@amber将代码更新到v4是个好主意。然而,如果你做这件事没有乐趣,请检查我的v3答案,这是对安德鲁答案的补充。@GerardoFurtado和乐趣时光不是。我知道v4库发生了什么,但生成的贴图带有负x值,这导致它在SVG之外渲染。
d3.selectAll('.popCircle')
  .on('click', function(d) {
    var text = 'force circle ' + d3.select(this).attr('id') + ' to bottom of the popCircle stack but above the bgCircle';
    alert(text);
  });
d3.selectAll("circle")
    .on("click", function() {
        var firstChild = this.parentNode.firstChild;
        this.parentNode.insertBefore(this, firstChild);
    })
selection.each(function() {
    this.parentNode.insertBefore(this, this.parentNode.firstChild);
});