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传入当前迭代元素的数据和索引。将返回值指定给属性。请参阅答案中的更新代码。