如何从DOM元素本身创建选择

时间:2015-02-28 19:29:50

标签: d3.js

在d3.js中,如果我给出了一个唯一标识DOM元素的CSS选择器,我可以创建一个只包含该元素的选择,例如,使用

svg.selectAll("g.node#"+d.id)

假设我已经给出了DOM元素本身,例如,已经存在的特定<g>。将DOM元素直接传递给selectAllselect会生成错误,报告为&#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)时,我会收到上面报告的错误消息。结果如下所示。谢谢你的帮助。

4 circles with links, each containing two circles

2 个答案:

答案 0 :(得分:3)

您可以使用d3.select()将DOM节点转换为D3选择。您无法使用selection.selectAll()将DOM节点转换为D3选择。你想要的代码是

d3.select(personG) 
    .selectAll("circle.person")  // create new circles within g node
    // ...

请注意两点:

  1. 声明的根是全局d3.而不是选择svg.
  2. 使用select()而不是selectAll()
  3. 进行选择

    Meetamit完全正确。

答案 1 :(得分:1)

您可以使用d3.select()将单个DOM节点转换为D3选择:

  

如果选择器不是字符串,则选择指定的节点;如果您已经有一个节点的引用,这很有用,例如在事件监听器或全局例如document.body

中。

此外,您可以使用d3.selectAll()

将DOM节点数组转换为d3选择
  

如果选择器不是字符串,而是选择指定的节点数组;如果您已经有节点的引用,例如this.childNodes ...

,这将非常有用