2014-01-25 5 views
0

Я создаю очень длинный DIV, содержащие сотни SVG линий, созданные по следующему методу: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())}) 
     } 
} 

Однако, когда я делаю MouseOver на независимо от того, какой линии я только получить данные назад от последнего элемента. Сначала я подумал, что это из-за «mygroup», поэтому я добавил счетчик + 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

Вы создаете кучу затворов в цикле. Каждая из создаваемых вами функций имеет переменную orf в своей области ограничения, но ваш цикл меняет значение orf. К тому моменту, когда функция запускается при срабатывании мыши над событием, orf имеет свое окончательное значение, поэтому ваш выбор #mygroup + orf всегда будет отображать последний элемент.

Вот хорошая страница на затворах, в которой есть раздел, описывающий подводные ловушки замыканий в петле: http://conceptf1.blogspot.ca/2013/11/javascript-closures.html.

В D3 вы можете обойти эту проблему, используя соединения данных вместо внешнего контура. Вот хороший учебник, который должен помочь понять, как это работает: http://bost.ocks.org/mike/join/

1

Вам нужно создать различные обработчик событий для каждого линейного объекта , я имею в виду, что они хранят эти строки, выдает их в связанном массиве или что-то в этом роде. Таким образом, вы, вероятно, переписываете каждый раз.

Если бы вы могли предоставить jsfiddle или что-то я был бы счастлив, чтобы проверить эту теорию для вас ...

Смежные вопросы