2015-03-26 15 views
9

utworzyć grupę z 9 elementów (kółka), takich jak:d3js: Jak wybrać n-ty element grupy?

// 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> 

Ale Jak wybrać element n-ty (tj: 3rd okrąg) grupy groupOfCircles chwilę nie znając wartości identyfikatorów lub atrybutów kręgów?

Będę później pętli nad wszystkimi elementami za pośrednictwem pętli for i kolor każdy na jedną sekundę.


Uwaga: Próbowałem rzeczy, takich jak:

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

Odpowiedz

18

Selektor musi być circle:nth-child(3) - w child oznacza, że ​​element jest n-ty dziecko, aby nie wybrać n-ty dziecko elementu (patrz here).

Można również użyć:

// 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

Dzięki Lars, powinienem przejrzeć moje klasyki CSS! – Hugolpz

+0

Co powiecie na d3 v4? Nie możesz już wykonywać 'kręgów [0] [4]'. – hobbes3

+0

Ustawienia wewnętrzne uległy zmianie, ale nadal możesz to zrobić: 'circles._groups [0] [4]'. –

1

Jeśli chcesz to zrobić w logice D3, funkcja anonimowa zawsze ma parametr wskazujący na bok dane:

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

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

+0

To jest sposób, do którego zwykle dążę, ale uważam, że nieco przesadzam, aby przerysować wszystkie zaznaczenia, gdy faktycznie chcesz zmienić pojedynczy element. – Hugolpz

+0

Kolor jest ustawiany tylko raz, podczas rysowania okręgów. Na pewno nie musisz ponownie wybierać wszystkiego. podczas gdy twoje pierwotne podejście dokonuje ponownego wyboru. – Imperative

+0

Ja rzeczywiście 1. narysuję okrąg na zielono; 2. Wykonaj pętlę aktualizacji, aby zmienić kolor koła docelowego na 1 sekundę. Jeśli użyję ponownie 'return i === 3?" ​​Red ":" green "' wewnątrz pętli for, w każdym cyklu będę przerysowywać wszystkie okręgi i kolorować na czerwono ten, który przestrzega warunku. (Jeśli dobrze rozumiem d3) – Hugolpz

3

Można również użyć tablicę okręgi ustawić atrybutu elementu:

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

To jest zbyt eleganckie :) – Hugolpz

+0

Cóż, ale wydaje się, że nie działa na moim skrzypce. Czy możesz go zapewnić? – Hugolpz

+1

To nie zadziała, ponieważ selekcje D3 nie są tak naprawdę tablicami, musi to być coś w stylu 'circles [0] [3] .attr (...)' lub 'd3.select (circles [0] [3 ] .node()). attr (...) '. –

0

Oto kolejna opcja za pomocą funkcji jako selektora.

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

Jeśli przełącznik jest funkcją robi się punktu odniesienia (D) oraz iteracyjnej (I) parametru. Następnie zwraca albo obiekt (ten), jeśli został wybrany, albo null, jeśli nie jest wybrany.

1

D3 V4 obsługuje pomocą wybór za .nodes() zwraca tablicę wszystkich elementów tego wyboru. Następnie można to zmienić cechy n tego elementu przez d3.select (wybór .nodes() [n)]. W ciekawy (co)

// 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>

Powiązane problemy