d3js将对象附加到svg

时间:2014-01-25 14:49:56

标签: javascript object svg d3.js

我正在创建一个非常长的div,其中包含由以下方法创建的数百条svg行:

function visualizeit(ORFdata,max) {
    var browser = d3.select("#viewer")
        .append("svg")
        .attr("width", max/10)
        .attr("height",'50%');

    //Add svg to the svg container
    for (orf in ORFdata) {
        var line = browser.append("svg:line");
            var object = ORFdata[orf]
            line.datum(object)
            line.attr("id", 'mygroup'+orf)
            line.attr("x1", function(d){ return ORFdata[orf]["start"]/10})
            line.attr("x2", function(d){ return ORFdata[orf]["stop"]/10})
            line.attr("y1", function(d){ if (ORFdata[orf]["strand"] == "+1") {return 50} else {return 10}})
            line.attr("y2", function(d){ if (ORFdata[orf]["strand"] == "+1") {return 50} else {return 10}})
            line.style("stroke", "rgb(6,120,155)")
            line.style("stroke-width", orf)
            line.on('mouseover', function(d){console.log(d3.select("#mygroup"+orf).datum())})
        }
}

然而,当我执行鼠标悬停时,无论哪一行,我只从最后一个元素返回数据。起初我认为这是由于我的小组'所以我添加了一个计数器+ orf,但它仍以某种方式删除了我以前存储的数据。

当我查看创建的html代码时,svg似乎至少在ID上是正确的。

<line id="mygroup50" x1="103356.7" x2="103231.1" y1="10" y2="10" style="stroke: #06789b; stroke-width: 50px;"></line>

但是在某个地方链接出现了错误的错误......

到目前为止我是如何修理的......

        var svgContainer = d3.select("body").append("svg")
                           .attr("width", max/10)
                           .attr("height", '50%');

    //Add svg to the svg container
    var lines = svgContainer.selectAll("line")
        .data(ORFdata)
        .enter()
        .append("line")
        .attr("x1", function(d){ return d.start/10})
        .attr("y1", function(d){ if (d.strand == "+1") {return 65} else {return 10}})
        .attr("x2", function(d){ return d.stop/10})
        .attr("y2", function(d){ if (d.strand == "+1") {return 65} else {return 10}})
        .attr("stroke-width","25")
        .attr("stroke",function(d) {if (d.strand == "+1") {return 'green'} else {return 'red'}})
        .on('mouseover', function(d) {console.log(d.start)})
}

2 个答案:

答案 0 :(得分:2)

你在循环中创建了一堆闭包。您创建的每个函数在其闭包范围内都有变量orf,但您的循环正在更改orf的值。当鼠标悬停事件时,该功能运行时,orf具有其最终值,因此您的#mygroup + orf选择将始终选取最后一个元素。

这是一个关于闭包的好页面,其中有一节详细说明了循环中闭包的缺陷:http://conceptf1.blogspot.ca/2013/11/javascript-closures.html

在D3中,您可以通过使用数据连接而不是外部循环来解决此问题。这是一个很好的教程,应该有助于理解这是如何工作的: http://bost.ocks.org/mike/join/

答案 1 :(得分:1)

你需要为每个行对象创建不同的事件处理程序,我的意思是将这些行存储在关联的数组或其他内容中。这样你每次都可能会被覆盖。

如果你能提供一个jsfiddle或者其他东西,我很乐意为你测试这个理论......