selection.call() method in D3 can aid in code organization and flexibility by eliminating the need to use chained method calls for every operation.
Last time, we looked at D3, we created some transitions that we then orchestrated, and can run from clicking this update button.To review, here is our button that caused that, and then, our update function runs through the dataset, updates all their values to random numbers, and then our actual transition is defined here. We are going to selectAll the circles, start the transition there, do the x properties and fill, y properties and fill, and then the radius and the fill.
What we are going to show today is, how to better organize this code using the call method of D3 selection object. D3 selection is the result of something like this, it's a very fundamental part of the D3 API, and you can use call to better organize your code, and give yourself some better flexibility. We are actually using call in a couple of places already, like here, for our xAxis, so, we define the xAxis here, and this code that creates the axis knows how to work, or how to operate on a selection. That is what enables us to do .call and pass in the function there for the xAxis.
To get a better idea of how that actually works, we are going to do things a little bit differently. The first thing we are going to do, is separate out our existing transition into its own function. We'll call that, steppedTransition, since we've got that staggering effect there, and it's going to take selection as an argument. Then what we are going to do here is, we are going to grab this whole big chain of things, replace it with a call to steppedTransition, and then if we put this up here, and say selection, then move down here, put that there.
We shall have the same exact behavior now, but we've got that code moved out of the way. You can see there, that it still works the same way, but we've now got it separated. What this makes it easier to do, is a few things. First thing we'll show is, maybe we want a alternate transition, and we'll call this one, plainTransition. We are going to get rid of this stepped nature here. We still need a transition definition, we still want it to take 500 milliseconds, but we are going to get rid of these intermediate steps, like setting it to orange, setting up the second transition, and that duration. We are going to get rid of all of that, we are going to do the same thing here.
Now we are saying, create one transition that takes half a second, set all of these three properties, and set the style to fill. We can then come down here, copy this name, come down here, and instead of telling it to call steppedTransition, we are going to tell it to call plainTransition. If we save that, go to refresh this, and now, click update, everything is going to happen at once.
Another thing that you can do, now that you have these methods broken out that work on selections independently, is you can create other selections. If we filter our selection here, we can modify which pieces of the selection actually get operated on. If we do something like, d.x < 50, that's only going to operate on items on the left side of our chart.
What I am going to do here, because this currently is updating the data for everything on the chart. I am going to change this from an _.each call to a D3 selection.each operation here. We are going to select all the circles, we are going to filter out any of them, whose x is not less than 50, and then, each one that's left will pass through this and get a new data value applied to those three properties, then we'll call that plainTransition again. If we go over here and refresh, click update, you can see only the items on the left side are being subjected to our transitions here.
What we can do, we can separate out this new data here and get that out of our way, newData up there. We've got that broken out just to make it a little easier to see here. We can then operate on, or create a separate item here. Let's do x > 50, it will get its data updated, and then we'll send it through the steppedTransition. Everything on the left half should do a smooth animate to their new place, everything on the right half will do a stepped transition. It's kind of hard to follow there, but that is in fact what's going on. You can tell because, we've got some of these purple items immediately, whereas the other ones go to orange, then blue, then purple.
That is basically, it. One other thing to note, you can pass arguments into these items once they have been passed out and called with call. So if we make this duration, and we'll have our duration passed in to this function, instead of being hard-coded, the stepTransition's got a few of them. We won't bother with that, but now when we call plainTransition, we can pass in some long duration, like two full seconds so the plainTransition will take a lot longer, the stepped one will go as normal. If you then go refresh, run that, you can see that we've got some items slowly moving to their new spots smoothly, whereas the other ones go through that stepped motion at the normal rate. That's just a few of the ways you can use call. it's very good for organizing codes, splitting code up into pieces, and making things more flexible in general.