2014-09-11 3 views
0

Я хочу разместить круги SVG вокруг некоторых кругов SVG. Я нахожу нужные круги, используя d3.selectAll().filter(). Это почти работает - создается круг. Но я не могу понять, как установить центр нового круга из центра старого круга, поэтому новый круг создается на 0,0. Ничего, что я пробовал, сработало.Установить атрибут круга из атрибута другого круга, используя d3.select?

// first I find the circles I want 
foundNodeCircles = d3.selectAll(".node").filter(function(d,i){return d.label == nodeRE;}); 

// Then I create a new, larger circle for each circle that I found: 
svg.selectAll(".nodeHighlightRing") 
.data(foundNodeCircles) // make one ring per node circle 
.enter().append("circle") // make the ring 
.attr("class", "nodeHighlightRing") // specify its qualities 
.attr("cx", function(d) { return d.cx;}) // BROKEN: set center to center of old circle 
.attr("cy", function(d) { return d.cy;}) // BROKEN: set center to center of old circle 
.attr("r", 10) 
.style("opacity", 0) 
.style("stroke", "green") 
.style("stroke-width", "1.5") 
.style("stroke-opacity", "1"); 

В в дополнение к d.cx, я попытался this.cx, d.attr["cx"], this.attr["cx"], d3.select(this).attr("cx"), d3.select(d).attr("cx"), и несколько других вещей, которые, казалось, менее вероятно, будет работать. Никто не добился успеха.

Я думал, что вопрос this или this one поможет, но я, очевидно, делаю что-то другое.

+0

Можем ли мы увидеть, что вы получаете в найденномNodeCircles, или сделать скрипку, мы могли бы что-то сделать. –

+0

Спасибо @ saikiran.vsk. jshanley правильно догадался. Мне нужно больше узнать о мире скрипки. – Mars

ответ

2

Проблема заключается в том, что ваша переменная foundNodeCircles проводит выбор d3, а метод соединения данных .data() ожидает массив, представляющий ваши данные.

Если вы используете foundNodeCircles[0] для объединения данных, вы будете ссылаться на массив элементов, которые содержались в выборе, а не на сам выбор. Затем, когда вы устанавливаете свои атрибуты, d будет ссылаться на сам элемент DOM, поэтому вы можете использовать выбор d3 для выбора d и вызвать .attr для извлечения атрибута или просто использовать метод DOM .getAttribute.

svg.selectAll(".nodeHighlightRing") 
    // BIND TO THE ELEMENTS RATHER THAN THE SELECTION 
    .data(foundNodeCircles[0]) 
    .enter().append("circle") 
    .attr("class", "nodeHighlightRing") 
    // EITHER OF THESE METHODS SHOULD WORK 
    .attr("cx", function(d) { return d3.select(d).attr("cx"); }) 
    .attr("cy", function(d) { return d.getAttribute("cy"); }) 
    // ... etc. ... 
+0

Очень освещая. Я * * путался с выборами по сравнению с массивами и данными по сравнению с элементами DOM. Мне по-прежнему странно, что я не могу использовать 'd.cx' здесь, но я подумаю, что урок будет изучен еще один день. – Mars

+0

Ах, потому что элементы DOM - это не просто объекты Javascript (массивы, хэши, что бы они ни были). Вернее, атрибуты не являются регулярными полями Javascript. И 'd3.select (d) .attr()' работает, потому что он делает объект выбора D3 из объекта DOM, и это только объекты выбора, которые имеют функцию '.attr()'? Не уверен, что моя терминология полностью верна. – Mars

+0

Да, вы на месте. JavaScript имеет встроенные методы управления элементами DOM, а d3 использует их под капотом. Когда вы вызываете '.attr' на выбор, d3 вызывает собственные методы' Element.getAttribute' или 'Element.setAttribute' (в зависимости от того, передаете ли вы 1 или 2 аргумента, соответственно) на элементе, содержащемся в выборе. Вот почему два метода, которые я опубликовал, эквивалентны. – jshanley

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