Let's say you've got a selection with some data bound to it and you use the typical inline anonymous function to access that data:
d3.select("#whatever").each(function(d,i,q) {console.log(d,i,q)})
We all know the first variable is the data and the second is the array position. But what does the third variable (q in this case) represent? So far it's always come back zero in everything I've tested.
The secret third argument is only of use when you have nested selections. In these cases, it holds the index of the parent data element. Consider for example this code.
var sel = d3.selectAll("foo")
.data(data)
.enter()
.append("foo");
var subsel = sel.selectAll("bar")
.data(function(d) { return d; })
.enter()
.append("bar");
Assuming that data
is a nested structure, you can now do this.
subsel.attr("foobar", function(d, i) { console.log(d, i); });
This, unsurprisingly, will log the data item inside the nesting and its index. But you can also do this.
subsel.attr("foobar", function(d, i, j) { console.log(d, i, j); });
Here d
and i
still refer to the same things, but j
refers to the index of the parent data element, i.e. the index of the foo
element.
A note on Lars's reply, which is correct but I found one more feature that is helpful.
The j
element gives the index of the element without regard to the nesting of the parent elements. In other words, if you are appending and logging as follows, the final circles are treated as a flat array, not as a group of nested arrays. So your indexes will be scaled from 0 to the number of circle elements you have, without regard to the data structure of your nesting.
var categorygroups = chart.selectAll('g.categorygroups')
.data(data)
.enter()
.append('g').attr('class','categorygroups');
var valuesgroups = categorygroups.selectAll('g.valuesgroups')
.data(function(d) {return d.values; }).enter().append('g').attr('class','valuesgroups');
valuesgroups.append('text').text(function(d) {
return d.category
}).attr('y',function(d,i) { return (i + 1) * 100 }).attr('x',0);
var circlesgroups = valuesgroups.selectAll('g.circlesgroups')
.data(function(d) {return d.values; }).enter().append('g').attr('class','circlesgroups');
circlesgroups.append('circle').style('fill','#666')
.attr('cy',function(d,i,j) { console.log(j); return (j + 1) * 100 })
.attr('cx',function(d,i) { return (i + 1) * 40 });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With