68

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

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

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

效果很好。拖得好。现在,我们如何让它成为最顶层的项目?在此处搜索“svg z-index”,很快就会发现更改索引的唯一方法是将对象在 DOM 中进一步向下移动。好的。它们并不容易,因为单个气泡没有 ID,但是在控制台中乱来,我们可以找到其中一个气泡对象:

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

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

.appendTo('svg')

完成后拖动它,它是最顶部的项目。到目前为止,一切都很好,如果您完全在 DOM 中工作。

但是:我真正想做的是在拖动给定对象/气泡时自动发生这种情况。D3 提供了一个模型dragstart()dragend()函数,允许我们在拖动过程中嵌入一个语句来做我们想做的事情。D3 提供了d3.select(this)允许我们访问d3 的对象表示的语法,该对象表示您当前正在拖动的对象/气泡。但是我如何干净地将它们返回的大量数组转换为对我可以交互的 DOM 元素的引用,并且 - 例如 - 将其移动到 svg 容器的末尾,或在 DOM 中执行其他引用,例如表单提交?

4

3 回答 3

198

您还可以通过selection.node() 方法获取选择所代表的 DOM 元素

var selection = d3.select(domElement);

// later via the selection you can retrieve the element with .node()
var elt = selection.node();
于 2014-02-25T19:56:14.517 回答
31

SVG 文档中的任何 DOM 元素都将具有ownerSVGElement引用它所在的 SVG 文档的属性。

D3 的选择只是嵌套数组,上面有额外的方法;如果你.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)thenthis已经DOM 元素;您无需将其包装在 D3 选择中即可展开它。

于 2012-04-26T20:56:10.033 回答
11

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

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

然后您可以使用 selectAll("circle.bubble") 按类选择或按 id 选择并修改属性,如下所示:

var testCircle = svg.select("#idlabel_3")
.style("stroke-width", 8);
于 2012-04-26T18:12:33.790 回答