在d3.js中,如果我给出了一个唯一标识DOM元素的CSS选择器,我可以创建一个只包含该元素的选择,例如,使用
svg.selectAll("g.node#"+d.id)
假设我已经给出了DOM元素本身,例如,已经存在的特定<g>
。将DOM元素直接传递给selectAll
或select
会生成错误,报告为&#34;语法错误:指定了无效或非法字符串&#34;在Firefox中,或者&#34; Uncaught SyntaxError:无法执行&#39; querySelectorAll&#39; on&#39;元素&#39;:&#39; [对象SVGGElement]&#39;不是一个有效的选择器&#34;在Chrome中。
如何从DOM元素本身的引用中创建选择?应该没有必要使用CSS选择器来搜索元素。
目前,我已经通过构建一个独特的CSS选择器获得了适当选择的工作代码,但这似乎是不必要的工作,因为我已经有一个我要追加的DOM元素的引用的东西。
编辑:
感谢@meetamit和@LarsKotthoff:好的,如果它只适用于DOM元素上的selectAll
,那么我对我的代码一无所知(这并不奇怪)。我试图避免在我的SO问题中丢弃大量代码,但我不知道还能做什么。这是一个fiddle。它并没有在jsfiddle中运行,我不知道为什么,但它在Firefox,Chrome和Safari中没有jsfiddle运行得很好。 (这里是一个fiddle,它只包含HTML窗口中的整个文件。)
我的代码应该在强制布局中为每个节点添加一个小包布局。可能有一种纯粹惯用的方法可以做到这一点,但我只是通过在强制布局中的节点上调用each
来成功实现它,从一个单独的函数中添加包布局: / p>
var svgnodes = svg.selectAll("g.node")
.data(data.nodes, function (d) {return d.id;})
.enter()
.append("g")
.attr("class", "node")
.attr("id", function (d) {return d.id;})
.call(layout.drag())
.on("click", click);
svgnodes.each(function (d, i) {addPersonCircles(d, svg, this);});
以下是addPersonCircles
的定义的一部分:
function addPersonCircles (d, svg, personG) {
// makes a data new structure for use by pack layout:
function makeroot (id) {return {"name":name, "children":[{"name":"a"}, {"name":"p"}]};}
// data structure containing three elements, one for each element generated by makeroot()
var pack = d3.layout.pack()
.size([personRadius, personRadius])
.value(function (d) {return 1;})
.nodes(makeroot(d.id));
// KLUDGE. Isn't there a way to select using the dom element personG that was passed in?
svg.selectAll("g.node#"+d.id) // find particular existing g node in person net
.selectAll("circle.person") // create new circles within g node
.data(pack)
.enter()
.append("circle")
...
}
当我添加console.log(personG)
,即显示this
内的each()
内容时,显示的内容是这样的:
<g class="node" id="sandra" transform="translate(263.59494561798255,242.1803122208288)">...</g>
我有时会被this
引用的东西困惑,但这里似乎是指一个DOM节点,而不是别的。但是,当我将svg.selectAll("g.node#"+d.id)
替换为svg.selectAll(personG)
时,我会收到上面报告的错误消息。结果如下所示。谢谢你的帮助。
答案 0 :(得分:3)
您可以使用d3.select()
将DOM节点转换为D3选择。您无法使用selection.selectAll()
将DOM节点转换为D3选择。你想要的代码是
d3.select(personG)
.selectAll("circle.person") // create new circles within g node
// ...
请注意两点:
d3.
而不是选择svg.
select()
而不是selectAll()
Meetamit完全正确。
答案 1 :(得分:1)
您可以使用d3.select()将单个DOM节点转换为D3选择:
如果选择器不是字符串,则选择指定的节点;如果您已经有一个节点的引用,这很有用,例如在事件监听器或全局例如document.body
中。
此外,您可以使用d3.selectAll():
将DOM节点数组转换为d3选择如果选择器不是字符串,而是选择指定的节点数组;如果您已经有节点的引用,例如this.childNodes ...
,这将非常有用