2015-03-26 10 views
9

ich eine Gruppe mit 9 Elementen (Kreisen), wie:d3js: Wie wählt man das n-te Element einer Gruppe?

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

Aber Wie das n-te Element wählen (dh: der 3. Kreis) der Gruppe groupOfCircles während die IDs oder Attribute der Kreise nicht kennen?

I wird später Schleife über alle Elemente über eine for-Schleife, und Farbe jeweils für eine Sekunde.


Hinweis: Ich hat versucht, Dinge wie:

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

Antwort

18

Der Wähler circle:nth-child(3) sein muss - die child bedeutet, dass das Element das n-te Kind ist, nicht das n-te Kind des Elements zu wählen (siehe here).

Sie auch nutzen könnten:

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

Danke Lars, ich sollte meine CSS-Klassiker überprüfen! – Hugolpz

+0

Wie wäre es mit d3 v4? Du kannst nicht mehr Kreise [0] [4] 'machen. – hobbes3

+0

Die Interna haben sich geändert, aber Sie können immer noch folgendes tun: 'circles._groups [0] [4]'. –

1

Wenn Sie es in d3 Logik tun wollen, muss die anonyme Funktion immer einen Indexparameter neben den Daten:

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

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

+0

Dies ist die Art und Weise, wie ich normalerweise gehe, aber ich es etwas übertrieben, um alle Auswahl neu zu zeichnen, wenn Sie tatsächlich ein einzelnes Element ändern möchten. – Hugolpz

+0

Die Farbe wird nur einmal gesetzt, wenn die Kreise gezeichnet werden. Sie müssen sicherlich nicht alles neu auswählen. während Ihr ursprünglicher Ansatz eine Neuauswahl durchführt. – Imperative

+0

Ich werde tatsächlich 1. den Kreis in grün zeichnen; 2. Machen Sie eine Update-Schleife, um den Zielkreis für 1 Sekunde neu einzufärben. Wenn ich dein 'return i === 3?" ​​Red ":" green "' in meiner for-Schleife wiederverwende, zeichne ich bei jedem Zyklus alle Kreise neu und färbt die Bedingung rot. (Wenn ich d3 gut verstehe) – Hugolpz

3

Sie können Ihre Kreise Array verwenden Sie das Element des Attributs zu setzen:

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

Das ist übermäßig elegant :) – Hugolpz

+0

Naja, aber es scheint nicht auf meiner Geige zu funktionieren. Kannst du eins anbieten? – Hugolpz

+1

Dies funktioniert nicht, da die D3 Auswahl nicht wirklich Arrays ist, sondern etwas wie 'circles [0] [3] .attr (...)' oder 'd3.select (circles [0] [3 ] .node()) .attr (...) '. –

0

Hier ist eine weitere Option durch eine Funktion als Selektor.

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

Wenn der Selektor eine Funktion ist es, das Datum (D) und der Iterator (i) als Parameter erhält. Es gibt dann entweder das Objekt (this) zurück, wenn ausgewählt, oder null, falls nicht ausgewählt.

1

d3 v4 unterstützt nun Auswahl .nodes() verwendet eine Anordnung von alle Elemente dieser Auswahl zurückzukehren. Dann können wir die Attribute n te Element von d3.select ändern (Auswahl .nodes() [n]). Attr (etwas)

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

Verwandte Themen