所有元素都采用相同的值

时间:2014-07-22 14:16:16

标签: javascript d3.js

我试图分配不同元素的不同因素。但每个人都被赋予相同(最后)的属性。这是怎么回事?

for (var i = 1; i < 12; i++) {
    d3.select("#id_" + i)
        .text(parseFloat(data[i - 1] / 1000000).toFixed(2))
        .on("mouseover", function (d) {
             d3.select("#tooltip")
                .style("left", "200px")
                .style("top", d3.event.pageY - 30 + "px")
                .select("#info")
                .html("<b>" + keys[i - 2] + "</b>");
             d3.select("#tooltip").classed("hidden", false);
                })
        .on("mouseout", function () {
             d3.select("#tooltip").classed("hidden", true);
    });
}

链接:JSFIDDLE

3 个答案:

答案 0 :(得分:2)

试试这个:

for (var i = 1; i < 12; i++) {
  (function (i) {  
      d3.select("#id_" + i)
        .text(parseFloat(data[i - 1] / 1000000).toFixed(2))
        .on("mouseover", function (d) {
             d3.select("#tooltip")
                .style("left", "200px")
                .style("top", d3.event.pageY - 30 + "px")
                .select("#info")
            .html("<b>" + keys[i - 2] + "</b>");
             d3.select("#tooltip").classed("hidden", false);
                })
        .on("mouseout", function () {
             d3.select("#tooltip").classed("hidden", true);
        });
  })(i)
}

答案 1 :(得分:2)

您编写的代码是命令式编程的示例,您可以告诉计算机如何执行某些操作。

D3是声明性编程的一个例子,你告诉计算机该做什么,让计算机决定如何做。

D3并非设计用于循环分配您问题中的值。而不是循环和条件以及其他“如何”,你应该专注于你想要发生的事情。

为此,您应该使用所谓的“数据绑定”,将数据集绑定到svg以绘制文本(这里是初学者教程/简单说明http://bost.ocks.org/mike/circles/

关于您的问题,您应该将数据放在一个对象中:

var data = [
    ["key": 1, "value": 0.0, "x": 84, "y": 310],
    ...
    ];

然后将此数据绑定到svg元素,然后您可以告诉D3使用这些属性绘制文本,而无需指定确切的实现。

svg.selectAll("text")
    .data(data)
    .enter()
    .attr("x", function(d, i) {
        return d.x;
    })
    .attr("y", function(d, i) {
        return d.y;
    })
    ...
    .on("mouseover", function(d, i) {
        d3.select("#tooltip")
            .style("left", "200px")
            .style("top", d3.event.pageY - 30 + "px")
            .select("#info")
            .html("<b>" + d.key + "</b>");
        d3.select("#tooltip").classed("hidden", false);
    })
    ...

函数function(d, i)将实际对象d作为参数,并将i作为对象在数组中的位置。

答案 2 :(得分:1)

您使用工具提示的问题是i是相同的值(12),无论哪个元素被鼠标悬停。要查看此内容,您可以在鼠标悬停处理程序中记录i。有几种方法可以恢复被鼠标悬停的元素的索引。最简单的(尽管可能不是最干净的)之一就是从元素ID中恢复它。

for (var i = 1; i < 12; i++) {
    d3.select("#id_" + i)
        .text(parseFloat(data[i - 1] / 1000000).toFixed(2))
        .on("mouseover", function (d) {
            var index = this.id.slice(3,9);              //ADDED THIS LINE
             d3.select("#tooltip")
                .style("left", "200px")
                .style("top", d3.event.pageY - 30 + "px")
                .select("#info")
                .html("<b>" + keys[index - 2] + "</b>");       //USE THE INDEX
             d3.select("#tooltip").classed("hidden", false);
        })
        .on("mouseout", function () {
             d3.select("#tooltip").classed("hidden", true);
    });
}

我还怀疑你的意思是keys[index-1]而不是keys[index-2]。后者超出了数组的范围。