Javascript d3.js中数组元素的绑定

Javascript d3.js中数组元素的绑定,javascript,d3.js,Javascript,D3.js,基本上我有一些字符串的数组,我想把这些字符串绑定到一个圆上。然后,当我将鼠标悬停在圆上时,我希望在工具提示中显示这些字符串 这是我的数组: var node = [ "Hallo Hallo Hallo Hallo Hallo Hallo Hallo", "foobarbaz", "This is a short text", "Changed some things on the folder structure and adde

基本上我有一些字符串的数组,我想把这些字符串绑定到一个圆上。然后,当我将鼠标悬停在圆上时,我希望在工具提示中显示这些字符串

这是我的数组:

var node = [
        "Hallo Hallo Hallo Hallo Hallo Hallo Hallo",
        "foobarbaz",
        "This is a short text",
        "Changed some things on the folder structure and added some functions to the convert.c file",
    ]; 
然后是我的工具提示,显示html文本

var tooltip = svg.append('foreignObject')
        .attr('x', 50)
        .attr('y', 50)
        .attr('width', 200)
        .attr('height', 300)
        .style("visibility", "hidden")
        .append("xhtml:body")
        .html('<div style="width: 150px;">Example</div>');
var tooltip=svg.append('foreignObject')
.attr('x',50)
.attr('y',50)
.attr('width',200)
.attr('height',300)
.style(“可见性”、“隐藏”)
.append(“xhtml:body”)
.html(“示例”);
现在我想在for循环上创建我的圆,将数据附加到它们,并让工具提示在鼠标悬停上显示正确的数据:

for (var i = 0; i < 4; i++) {

    svg.append("circle")
        .data(node[i])
        .attr("cx", 100*i+250)
        .attr("cy", 100)
        .attr("r", 10)
        .attr("fill", "steelblue" )
        .on("mouseover", function(d){
            return tooltip.style("visibility","visible")
                .html('<div style="width: 150px;">'+d+'</div>');
        }).on("mouseout", function(){
            return tooltip.style("visibility", "hidden");
        });
    }
for(变量i=0;i<4;i++){
svg.append(“圆”)
.数据(节点[i])
.attr(“cx”,100*i+250)
.attr(“cy”,100)
.attr(“r”,10)
.attr(“填充”、“钢蓝”)
.on(“鼠标悬停”,功能(d){
返回工具提示样式(“可见性”、“可见”)
.html(“”+d+“”);
}).on(“mouseout”,函数(){
返回工具提示样式(“可见性”、“隐藏”);
});
}

但由于某些原因,当我将鼠标悬停在点上时,结果不是整个字符串,它只是字符串的第一个字符。我显然在这里遗漏了一些东西…

D3希望您提供一个值数组,例如
.data([1,2,3,4])
。您正在传递字符串。因此,D3尝试将字符串的各个字符(因为字符串就像数组一样,可以迭代)与选择的元素相匹配。在本例中,已经有一个元素,因此它将为其分配与字符串的第一个字符相等的
\uuuu data\uuuu
属性。其余字符将进入
enter
选择

正如Lars Kotthoff在他的评论中提到的,在使用D3时,不应该对循环使用
。相反,请尝试以下方法:

svg.selectAll('circle') // empty (yet) selection of circles
  .data(node) // apply data to the empty selection, where node is your array of strings
  .enter() // same as "for all entering (new) elements... "
    .append('circle') // creates as many circles as there are elements in node array
    .attr('cx', function (d, i) {
        // d is "Hello...", "foobarbaz", "This is a short text", etc.
        // i is 0, 1, 2, 3
        return 100 * i + 250; // dynamic, index-dependent x
    })
    .attr('cy', 100) // constant y value across all elements
    .on('mouseover', function (d) {
      console.log(d);
    });

使用
.datum()
而不是
.data()
。你真的不应该在这里使用循环,但是D3的选择和数据匹配。我对解决方案做了一些修改:var circles=svg.selectAll(“circle”).data(node).enter()…好的,但是我如何访问迭代器呢?您不需要访问迭代器
.data([1,2,3]).enter()
类似于
[1,2,3].forEach()
。它为您进行迭代(并计算数据连接,因此它就像类固醇上的迭代一样)。我想在元素id上以相同的距离放置圆,因此实际上需要迭代器。
attr
,以及其他方法,可以将函数作为第二个参数,D3传入当前迭代元素的数据和索引。将返回值指定给属性。请参阅答案中的更新代码。