如何访问与D3 SVG对象相关的DOM元素?

我试着通过尝试一下他们的基本泡泡图来学习D3。 第一个任务:弄清楚如何拖拽一个气泡,并在被拖拽时变成最上面的对象。 (问题是D3的对象模型映射到DOM,但我会到达那里…)

要拖动它,我们可以使用它们提供的代码简单地调用d3的拖动行为:

var drag = d3.behavior.drag() .on("dragstart", dragstart) .on("drag", dragmove) .on("dragend", dragend); 

很好用。 拖得很好。 现在,我们如何才能成为最重要的项目呢? 在这里search“svg z-index”,很明显,改变索引的唯一方法是在DOM中进一步移动对象。 好。 它们并不容易,因为单个的泡泡没有ID,但是搞乱了控制台,我们可以find其中一个泡泡对象:

 $("text:contains('TimeScale')").parent() 

我们可以将它移动到包含svg元素的末尾:

 .appendTo('svg') 

这样做后拖动它,这是最高的项目。 到目前为止, 如果您完全在DOM中工作,那么这么好。

但是:我真正想要做的就是自动发生一个给定的对象/泡泡拖动。 D3为dragstart()dragend()函数提供了一个模型,这将允许我们在拖动过程中embedded一条语句来执行我们想要的操作。 D3提供了d3.select(this)语法,它允许我们访问d3的当前拖动的对象/气泡对象表示。 但是,我该如何干净地将这个庞大的数组返回到一个可以与之交互的DOM元素的引用中 – 例如,将其移动到svg容器的末尾,或者在DOM中执行其他引用,例如表单提交?

SVG文档中的任何DOM元素都将拥有一个引用ownerSVGElement在的SVG文档的ownerSVGElement属性。

D3的select只是嵌套数组,其上有额外的方法; 如果你有.select()一个DOM元素,你可以用[0][0]得到它,例如:

 var foo = d3.select(someDOM); // later, where you don't have someDOM but you do have foo var someDom = foo[0][0]; var svgRoot = someDom.ownerSVGElement; 

但是,请注意,如果您正在使用d3.select(this)那么this已经 DOM元素; 你不需要把它包装在一个D3select只是为了解开它。

您也可以通过selection.node()方法获取select代表的DOM元素

 var selection = d3.select(domElement); // later via the selection you can retrieve the element with .node() var elt = selection.node(); 

如果您需要追加,您可以将ID和类分配给各个元素:

 node.append("circle.bubble") .attr("r", function(d) { return dr; }) .style("fill", function(d) { return fill(d.packageName); }) .attr("id", function(d, i) { return ("idlabel_" + i)}) .attr("class", "bubble") ; 

然后你可以通过selectAll(“circle.bubble”)类来select,或者通过id来select并修改属性,如下所示:

 var testCircle = svg.select("#idlabel_3") .style("stroke-width", 8);