2014-01-25 50 views
0

我创建包含数百个通过下面的方法创建SVG线很长的div:d3js附加对象为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())}) 
     } 
} 

然而,当我做无论鼠标悬停什么线我只得到数据从最后一个元素回来。起初我以为是'mygroup'造成的,所以我给它加了一个计数器+ orf,但它以某种方式仍然会擦除旧的存储数据。

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

<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

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

下面是一个封闭的好页面,其中有一个部分详细描述了循环中闭包的陷阱:http://conceptf1.blogspot.ca/2013/11/javascript-closures.html

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

1

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

如果你能提供的jsfiddle或东西,我会很乐意验证这一理论为你...