As a general rule, you don't need loops when using D3. It's (normally) completely unnecessary, given what D3 does with the data. It's true that we do use loops sometimes in a D3 dataviz, but only in very specific situations, to solve very specific problems. For the majority of situations, when we see a D3 code using a loop, we tend to think that that code is not using D3 capabilities correctly (also, in your code, you're mixing the i
in the for loop with the i
in the anonymous function. They are not the same).
So, to access your data array using the second argument, which is the index, forget about for loops: you just need to pass it in your selection.
Here is a simple example, using an enter selection. We check if the dataz
value is blue
. If it is, we set the opacity to 0.1:
var svg = d3.select("svg");
var dataz = ["teal", "brown", "blue", "purple"];
var circles = svg.selectAll(".circles")
.data(dataz)
.enter()
.append("circle");
circles.attr("r", 20)
.attr("cy", 50)
.attr("cx", (d, i) => i * 50 + 40)
.attr("fill", d => d)
.attr("stroke", "black")
.style("fill-opacity", (d, i) => dataz[i] === "blue" ? 0.1 : 1)
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
Pay attention to this: in my snippet above, dataz[i]
is the same of d
(the datum itself).
Explaining the problem with your code:
The i
in the anonymous function is not the i
in the loop. Due to the scope of the function, when you do console.log(i)
inside the anonymous function, you're logging the second argument, or index, which in this demo is always zero:
var dataz = ["teal", "brown", "blue", "purple"];
for (var i = 0; i < dataz.length; i++) {
d3.select("body").attr("fill", (d,i)=>console.log("the value of i is: " + i));
}
<script src="https://d3js.org/d3.v4.min.js"></script>
A simple solution is changing the variable name of the for loop (or the second argument, it doesn't matter). Check this demo, the second argument (i
) is always zero, but the loop (j
) goes from 0 to 3 (you don't need let
here, it works with var
):
var dataz = ["teal", "brown", "blue", "purple"];
for (var j = 0; j < dataz.length; j++) {
d3.select("body").attr("fill", (d,i)=>console.log("second argument:" + i + " - loop:" + j));
}
<script src="https://d3js.org/d3.v4.min.js"></script>