Introduction to D3.js Passing a Function to .data()
Transcript from the "Passing a Function to .data()" Lesson
>> And so here, the next part is what I think is the most interesting part. And this is what we call a nested selection in D3. And so, for each film flower, we have a different number of petal path elements depending on the data for that movie. So to be able to dynamically create the correct number of path elements, we use the same select all data enter append pattern as before.
[00:00:31] So this is what it looks like. We again have our group selection up here. And we say, take that selection of groups and within each group, we want to select all the paths with that don't yet exist. We are going to bind data to that empty selection of paths and we are going to create the correct number of path elements with the correct data bound depending on whatever we return in here.
[00:01:07] So, what goes inside in this data binding part is what I think is the most interesting. So it turns out the .data function also accepts functions, not just arrays. And so the key is to write a function that returns an array of objects. Because remember again, at the end of the day, .data needs to have an array to know how many data elements to match how many DOM elements.
[00:01:43] And so let's take a look at this. So we have select all paths in our group elements, which is currently empty. And then what we're going to do is we're going to pass in a function and that function will be passed in the data that's been bound on that parent group element.
[00:02:08] So you can see that here, we'll pass that data in, and we can use that data to say, okay, so this first group element, the data says the number of petals is five. So we can say d.numPetals. And in this _times is a kind of utility function that I use really often with Lodash.
[00:02:33] And this _times just says, whatever the number is passed in here, create an array of that length. In this case, a length of the number of petals and the array should have whatever is returned in this second function. And so for example, in the first group with our minions data, we're going to create an array of length five.
[00:03:16] And within there, what we want is to be able to say, okay, so the first petal we want to rotate at zero degrees, and then the second petal, we want to rotate it by 360 degrees divided by whatever the number of petals there are. So then, for example, so that's the index times 360 degrees divided by the number of petals and what that gives us is the first path will have a rotation of zero, the second path will have a rotation of 75.
[00:04:03] The third one will have 144, and etc. And for the second group, the data that's been bound is the movie inception. And in that case, there's a lot more IMDB votes. So the number of petals that we calculated was nine. And so if we invoke this function, this _times function on inception, what we get is an array of length nine.
[00:04:33] And within it, is objects that include a rotation, where the first rotation is zero, the second rotation is 40 degrees, the third one is 80 degrees, and so on. And so this will evaluate again to the array of objects, and then we're going to enter append. So what we end up with is a set of five paths, [COUGH] for minions with the data bound to them.
[00:05:05] And for this one, a set of nine paths with the data bound on them. So, if we toggle to see the resulting D3 selection, I actually think this is the most interesting part, which is you can see it's an array of 135. And so it has 135 movie, so it's an array of 135.
[00:05:33] But within each of that is an array of five, array of seven, or array of six. So the structure it really is kind of a group parent element, and then all of the children elements in this nested structure. And you can see that we have the rotation in here as well as, I kind of copy and paste over the parent data.
[00:06:05] So you can see this one is rotation 72, and the actual what I'm returning within the .data is the number of times and I create a copy. So here what I'm doing is I have a new object and I create a copy of the parent data. And I also add in that rotation to get the data that's been bound to each of our children path elements.