2015-03-26 3 views
9

создать группу с 9 элементов (кружки), такие как:d3js: Как выбрать n-й элемент группы?

// JS 
var data=[ 1,2,3,4,5,6,7,8,9 ]; 
var svg = d3.select("body").append("svg"); 
var circles = svg.append("g").attr("id", "groupOfCircles") 
    .selectAll("circle") 
     .data(data) 
    .enter().append("circle") 
     .attr("cx", function(d){ return d*20;}) 
     .attr("cy", function(d){ return d*10;}) 
     .attr("r" , function(d){ return d;}) 
     .attr("fill","green"); 

enter image description here

//xml 
<svg> 
    <g id="groupOfCircles"> 
     <circle cx="20" cy="10" r="1" fill="green"></circle> 
     <circle cx="40" cy="20" r="2" fill="green"></circle> 
     <circle cx="60" cy="30" r="3" fill="green"></circle> 
     <circle cx="80" cy="40" r="4" fill="green"></circle> 
     <circle cx="100" cy="50" r="5" fill="green"></circle> 
     <circle cx="120" cy="60" r="6" fill="green"></circle> 
     <circle cx="140" cy="70" r="7" fill="green"></circle> 
     <circle cx="160" cy="80" r="8" fill="green"></circle> 
     <circle cx="180" cy="90" r="9" fill="green"></circle> 
    </g> 
</svg> 

Но Как выбрать п-й элемент (т.е. 3-й круг) группы groupOfCircles время не зная значений id или атрибутов окружения?

Позже я перейду через все элементы через цикл for и поменяю каждую секунду.


Примечание: Я пробовал такие вещи, как:

circles[3].attr("fill","red") // not working 
    d3.select("#groupOfCircles:nth-child(3)").attr("fill","red") // not working 
    .. 

ответ

18

Селектор должен быть circle:nth-child(3) - child означает, что элемент является п-й ребенок, чтобы не выбрать п-й дочерний элемент (см. here).

Вы также можете использовать:

// JS 
 
    var data=[ 1,2,3,4,5,6,7,8,9 ]; 
 
    var svg = d3.select("body").append("svg"); 
 
    var circles = svg.append("g").attr("id", "groupOfCircles") 
 
     .selectAll("circle") 
 
      .data(data) 
 
     .enter().append("circle") 
 
      .attr("cx", function(d){ return d*20;}) 
 
      .attr("cy", function(d){ return d*10;}) 
 
      .attr("r" , function(d){ return d;}) 
 
      .attr("fill","green"); 
 
    
 
    d3.select("circle:nth-child(3)").attr("fill","red"); // <== CSS selector (DOM) 
 
    d3.select(circles[0][4]).attr("fill","blue"); // <== D3 selector (node)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

+0

Спасибо Ларсу, я должен пересмотреть свои классики CSS! – Hugolpz

+0

Как насчет d3 v4? Вы больше не можете делать круги [0] [4] '. – hobbes3

+0

Внутренние изменения изменились, но вы все равно можете сделать это: 'круги._группы [0] [4]'. –

1

Если вы хотите сделать это в d3 логике, анонимная функция всегда имеет параметр индекса в сторону данных:

my_selection.attr("fill",function(d,i) {return i%3==0?"red":"green";}); 

http://jsfiddle.net/risto/os5fj9m6/

+0

Это то, как я обычно и хожу, но, хотя мне немного сложно перерисовать весь выбор, когда вы действительно хотите изменить один элемент. – Hugolpz

+0

Цвет устанавливается только один раз, когда круги нарисованы. Вам, конечно же, не нужно отбирать все. тогда как ваш первоначальный подход делает повторный выбор. – Imperative

+0

На самом деле я нарисую круг в зеленом цвете; 2. сделайте цикл обновления, чтобы перекрасить целевой круг в течение 1 секунды. Если я повторно использую ваш 'return i === 3?" ​​Красный ":" зеленый "' внутри цикла for, в каждом цикле я буду перерисовывать все круги, а цвет в красном - тот, который соблюдает условие. (Если я хорошо понимаю d3) – Hugolpz

3

Вы также можете использовать массив кругов, чтобы установить атрибут элемента:

d3.select(circles[3]).attr("fill","red"); 

// JS 
 
var data=[ 1,2,3,4,5,6,7,8,9 ]; 
 
var svg = d3.select("body").append("svg"); 
 
var circles = svg.append("g").attr("id", "groupOfCircles") 
 
    .selectAll("circle") 
 
     .data(data) 
 
    .enter().append("circle") 
 
     .attr("cx", function(d){ return d*20;}) 
 
     .attr("cy", function(d){ return d*10;}) 
 
     .attr("r" , function(d){ return d;}) 
 
     .attr("fill","green"); 
 

 
var group = document.querySelector('#groupOfCircles'); 
 
var circleNodes = group.getElementsByTagName('circle'); 
 
d3.select(circleNodes[3]).attr("fill", "red");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

+0

Это слишком элегантно :) – Hugolpz

+0

Ну, похоже, это не работает на моей скрипке. Можете ли вы предоставить его? – Hugolpz

+1

Это не сработает, потому что выбор D3 не является массивом, он должен быть чем-то вроде 'круги [0] [3] .attr (...)' или 'd3.select (круги [0] [3 ] .node()). атр (...) '. –

0

Вот еще один вариант с использованием функции в качестве селектора.

circles.select(function (d,i) { return (i==3) ? this : null;}) 
    .attr("fill", "red"); 

Если селектор является функцией он получает опорную точку (г) и итератор (I) в качестве параметра. Затем он возвращает либо объект (это), если выбран, либо null, если не выбран.

1

d3 v4 теперь поддерживает используя выделение на .nodes() возвращает массив всех элементов этого выбора. Затем мы можем изменить атрибуты п го элемента по d3.select (выбор .nodes() [п]). Атр (что-то)

// JS 
 
var data=[ 1,2,3,4,5,6,7,8,9 ]; 
 
var svg = d3.select("body").append("svg"); 
 
var circles = svg.append("g").attr("id", "groupOfCircles") 
 
    .selectAll("circle") 
 
     .data(data) 
 
    .enter().append("circle") 
 
     .attr("cx", function(d){ return d*20;}) 
 
     .attr("cy", function(d){ return d*10;}) 
 
     .attr("r" , function(d){ return d;}) 
 
     .attr("fill","green"); 
 

 
circleElements = circles.nodes(); // <== Get all circle elements 
 
d3.select(circleElements[6]).attr("fill","red");
<script src="https://d3js.org/d3.v4.min.js"></script>

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