 Hey, everyone. Hi, hello. Thanks so much for joining. So first of all, thank you so much for signing up for this workshop. If you have not signed up and you're crashing, you're more than welcome if there is room. Is there any more room? If anybody wants to be kind and squeeze in four in a row or anything, that's more than welcome. But yeah, thank you so much for signing up and joining. And do you like my setup? I have like two microphones. This is the first time this happened. So I asked for a microphone for the room because I'm getting a little bit sick or was getting sick. And my throat is a little bit sore, so I can't quite project. So that's why I have a microphone. And then apparently the other microphone is for the YouTube live stream, which is really cool. So hey, everyone, my name is Shirley. Hopefully maybe you saw Naughty and I's talk yesterday. And then that's Naughty in the back. And she is absolutely amazing. I think she's overqualified to be a TA. But if you have any questions during the, so I'm primarily running the workshop. And then Naughty is going to answer any questions during the exercises or anything. And she's going to help. Actually, if you want to just help answer questions, that's fine too. But if you have any questions during the exercises or anything, then you're more than welcome to ask me or Naughty. Whoever one of us look less busy. So yeah. Yeah. So I guess we can get started. Cool. Anybody uncomfortable with where they're sitting or like, oh, whoa. Hello. I guess that area. Yeah, like if you can find a chair, then you can sit there. Maybe we can ask the hotel for more chairs maybe. We're going to be a fire hazard. Yeah. So this is the workshop slides. And then if you just go to this URL that I've written, and then it's the very first one. So that one should link here. And then the very first one. So if you can open that up, and then you can follow along there. Go Bears. What? Go Bears. Is that, is there, wait, do I have a? Hi, Go Bears. Yeah. I'm like, do I have like a password on it or something? I guess you and I are both from Berkeley. Yes, Go Bears. Yeah, so open this one up. And then, by the way, how's everybody's energy levels this afternoon? Because I just ate a lot at that buffet, and I'm scared. Wait, I like how after you said Go Bears, you pulled out a Stanford jacket. Yeah, so hopefully everybody feels awake. So today, I'm really excited to do this workshop. And we're going to recreate this. So this is if you were at the talk yesterday. This was one of the ones that I mentioned. It's called Film Flowers. Yeah, so let's see. So it's this one. And I think it's basically every single one of these flowers are a movie. You can like click on one of them and then see the corresponding movie. And then the petals are random guidance readings, colors, and number of petals, and size of petals. And this is one of those fun ones that are, it's like, yeah, it's just kind of fun to do. So today, for this workshop, our goal is to recreate this visualization. And we're not going to put in the colors, but we'll get as far as this. So we'll be one step away from the colors. And then maybe the stress goal is you figure out how to put in the colors. But yeah, how does that sound? Yeah. Awesome. So yeah, I know it's right after lunch. I know that buffet was freaking amazing. I had a second plate that I shouldn't have, because I'm like, this is really great food. But if you have any questions, raise your hand, interrupt me, but please do it nicely. And then at any given point, I might ask, how is it going? And then just let me know. Yeah, so let's get started. So for this particular workshop, I'll be covering these things. So SVG paths, introduction to D3. So D3 scales, selection, data binding, enter append, and finally, nesting elements. And if we have some time at the end, then we can also cover D3's enter, update, exit pattern. So yeah, how many people have worked with SVG before? Hands up. I just like the back. Cool. Awesome. And then how many people have tried out D3 before? Oh, brilliant. OK, cool. So hopefully, by the end of the day today, you'll have a decent good grasp of how SVG paths work, and then a good grasp of basic core D3, how D3 works. So that's the goal. So let's get started. Here's some of my favorite basic SVG elements. So here's, well, actually, let me back up really quickly and say SVG elements are very similar to HTML, in that it's an XML dialect. But there's a little bit of differences in how you might style them or how you might position them. So here's four of the SVG elements I use the most. And SVG elements are really great for visualizations, because it's like the building blocks of SVG are like rectangles and circles and lines and paths. So for rectangles, for example, you need to be able to define the x, y coordinates and the width and height to draw a rectangle. Can you guys see it fine in the back? Or is it too small? Too small? I actually don't, wait, actually, let me try and see if I can make the resolution. Did that get any better? No, right. OK, so how about this? Just have it open on your laptop, because everybody has a laptop, right? OK. Have it open on your laptop, and then follow along. Yeah, because this service I use, if you can see I'm zooming in and it's great because it's scaled to fit the screen exactly as it should, but it means that I can't actually zoom. So yeah, so if you can't see anything, please refer to the slides. And you should have the slides open anyways, because there's links to the exercises, links to co-snipets and everything. So yeah, so this is all of the SVG elements I use the most often, and today we'll be playing with the path primarily. So SVG paths, I actually like asking this question, which is, how many of you use Illustrator or know how to use Illustrator? Awesome. So for those of you that have ever used Illustrator, or actually even if you use Photoshop a lot and there's a pen tool in Photoshop, remember how when you draw a path in Illustrator or with a pen tool in Photoshop, you basically like put down your first anchor point, right? And then you put down, and then you click again, and you put down, sorry, not anchor point, sorry, you put down your first point, you click and you put down your first point, and then you click and you put down your second point, and then it draws this temporary line between them, right? And then, actually, and then it kind of looks like that, and then there's like two little anchor points that show up, and then you can drag those out. Like maybe the anchor point will come out to here, and maybe you'll drag the anchor point out to here, and as you drag those two anchor points, the path starts curving like this, right? Do you guys have experience with that? Cool. So in SVG paths, when you draw curves, so there's a few different, yeah, you can't really see, but there's a few different commands for SVG paths. There's the first, there's an M, so that's the move command, and the way we use this is we might say M00, and that means move my cursor, basically move to position 00 where 0 is x and 0 is y. So in this case, it might happen that you said, okay, move me to 00, and then for us to draw a curve in SVG paths, the command is C, and this one I'm going to, so C goes first anchor point, AX1, AY1, and then second anchor point, and then finally your X2, Y2, and I will explain that right now. So let's say, so actually, let me try and color code this. This is this, and this is this, and finally, this is this. Wow, these are great markers. I just heard it, yeah. Yeah, is it going to be all right if I tilt it? Okay. Did that make sense? And I can explain more, like I can do more examples. So let's do it this way. So let's actually draw a curve. So let's see, okay, let's define, here's my X axis, here's my Y axis, here's my 00, and then can anybody tell me why I drew the Y going down? Yeah, the screen always, with SVG, your X increases as you go right, and your Y increases as you go down. And that's how it is for most drawing, if not all drawing programs, right? I think, yeah, yeah, I think so. So yeah, let's do this. Let us draw a curve, should we call this maybe 10? Wait, that's 10 over and 10 down. Let's say our ending point is at, it's probably 100, right? So 100 and then 10. So this is our beginning, actually. So this is our beginning, and this is our end. And let's actually together start writing down the SVG path command, yeah? So help me with this. So for this point, the way that we tell SVG paths that we want to begin at this point, we say move, right? Because we start, we always move is like, you tell SVG path, like, pick up the pen and drop it at this point. So we start at this point, and we say move 10, 10. And then let's do this. So let's say our first anchor point is right here. And let's call this 20, maybe 20, 0. And then let's say our second anchor point, let's call this 80, 0. And so we're going to draw, I should have done this in red. And so the final curve will look like this. Yeah, so help me with this. What should my SVG path command look like now that I have M1010? What should be the next command? I hear you. Yes, good. C, and then what's my X and Y, the first X and Y. Awesome, thank you. And then the next one, cool. 80, 0, and finally, that was easy, huh? That's it. That's all you need to draw a curve. And that's pretty much the most powerful thing you can do with an SVG path, like draw a curve. And that's all it took. So as long as you remember, your first starting point, you move to it. And then you give it your first anchor point, your second anchor point, and your ending point. And that's your curve. Then let me teach you another one that I use a lot of times, which is L. Do you guys want to guess what L is? Yeah, line two. I'm going to fit that down here. And that one is also just X, Y. It's very straightforward. So basically, that one is wherever it basically says, wherever your cursor is right now, do not pick up your pen. Or basically, wherever your pen is, do not pick up your pen and just draw a straight line there. So basically, this is your ending point. So if, let me see. So then I guess I will now just keep calling ending. I'm going to use red for my ending points. So this is basically an ending point. So let's do, shall we try doing the cherry blossom petal from yesterday? Are you guys interested in that? We'll go through that together, because the goal is for you to make your own petals. So once we figure out how to do the cherry blossom petal, then I'm going to give you guys about 30 minutes to try and come up with three petals of your own. And that's why you should also have pens and paper right next to you, because I found that it actually really helps if you can write out for yourself all of the different paths as you're coding along. So let's start out with this. Let's start out with, this time let's do like, here's my X. And here's my Y. Let's start out. Hold on. Oh, wait, no, no, no. I shouldn't do it that way. OK, let's do this. You know that? Here's my 0, 0. Here is my 100, 0. Here's my 0, 100. And then how did I draw my petal? Cool. OK. I am torn. Oh well, we'll do it this way. OK, so let's draw a petal that looks something like this. And then we're going to figure this out together. So very first point. This probably looks like 50, 0, right? So what's my first command? And then 50, 0, right? OK. Now we have, let's figure out all the points for this one. OK, this one, let's say, this looks like 75. And then my Y would be 100, right? Right, right, right? Yeah, I'm pretty bad at math, so you need to correct me. OK, 75, 100. Actually, let me do it with the right colors. And then first anchor point is blue. OK, so we're going to just like guesstimate, because obviously we can't quite figure it out, right? So guesstimate for me what that anchor point might be. 80. And then this one, then 30. Yeah, there's no wrong answer. It's just like the petal might look a little bit different from that, is all. Yeah. And then second anchor point. Oh, it probably should be 80, right? Should we try 90? And then the Y, 70? And so now it should be the command is, what should the command be now? We're drawing from here to here now. See, 80, 30. Cool, 75, 100. Just to make sure, I'm writing big enough for the back, right? Can you guys see in the back? This is all right? No? Bigger? OK, I'll start writing bigger. OK, now right here. What should this be? 50, 60, 50, 60, what? What? What? 55. 55? Wait, hold on. Hold on, remember that this is 155 would be like really? Yeah, so 65, you guys want to do 65? We're going to put this all in the computer soon, just to see what it looks like, by the way. Yeah, so let's do that. So I'm going to try and write bigger. Is this big? Is that good in the back? All right, cool. So now, again, another line. Thank you. Another line, 25 and 100. And finally, another curve back. Remember, this time around, we're trying to curve this way. So our first anchor point is actually over here. And then our second anchor point is over here. So let's do that. So this one, I heard 10 just now. 10, 70? Cool. And then, I'm getting confused with my colors. OK, 20, 20, right? 20, 30 colors. So that's a, what do I do now? See? See 10, 70, 20, 30. And then we end here, right? Oh, wait, that's a red. So this point is both our beginning and our end. So 50, 0. And that's it. Did anybody put in the numbers? And then is it like really weird looking? Oh, and a final note of you can put in z. And z just means closed path. OK, let's try putting that in. You're going to have to read it to me because I can't see it. OK, we start with, it was m50, 0, right? And then c, what was c? 80, 30. Oh, yeah? So what? Oh, really? Wait, hold on. Wait, I don't? OK. Oh, there we go. Wait, hold on. Oops. Thank you. Does that help? We'll try that in a little bit. OK. Oh, I forgot to mention. Click here for started code. And then let me actually go through. This is like a little bit of an online editor that a lot of the D3 community uses. It's called blockbuilder.org. And then all you need to do is sign in with your GitHub. So where I have my little picture, it should have a login for you. Login with your GitHub. And then just fork my starter code. Fork it for yourself so that you can start saving it for yourself. And then it's pretty straightforward. It live updates. And then the one that I like using the most is that little. Oh, you can't see it. Hold on. Let's see. OK. So I typically like hitting this one so that the editor is right by the preview section. And I think for now, that's all you need to know. I think. And then for that piece of code, this is basically my original code for the flower pedal. And we're going to put in another one right now. And then I should have, yeah. Oh, thank you. 90, 70, 75, 100. And then 50, 65. Oh, do you see it showing up right there? And then the next one is another L. 100, thank you. 10, 70. 20, 30. Thank you. Whoa. How does it feel? It's a little bit like narrow, huh? I like it. OK, cool. Was that fun? Was that fun with friends? OK. All right. So. The mic. The mic. Look, it actually is pretty good right now. Thank you. OK, so we're moving on. And we're going to cover two things before we break off for an exercise again. And we're going to cover scales. And we're going to cover selection and data binding. So from now on, we're actually covering D3 functionality. So I guess before we get going, I guess let's talk about D3 a little bit. So I'm guessing everybody in here has heard of D3. And a lot of you have tried D3. So for reference, here is the D3 website. And here is the documentation. I tend to go to the API reference all the time, which I have to admit is like really humongous and kind of intimidating. Just because there are so many different modules that have like so many different things that you can do. So my goal for today is that hopefully we'll cover enough of the basics that you feel all right going through the reference. We'll see. But for now, the first thing we're going to talk about is this one right here with the scales. And then we're going to talk about selections, which is like the one right after that. Yeah, let's see. OK, so let's start out with the scales. Does anyone want to guess what scales are good for before we start? Thanks. Was that you? Thanks. OK, I guess I did walk myself into that one. Thanks. OK, so I don't know if I should be standing up or standing. OK, so this is what a very typical D3 scale looks like. So one of the most basic ones is scale linear, which just means that with your domain, you have an input, your domain, and you have an output, your range. And it is basically a one to one mapping. So linear one to one mapping between your input and your output. And there's a few others that I'll mention further down the line. But for now, let's just use scale linear as our example. And so the way that I like to think about scales is like, I'm sure you've done lots of scales in math class back when you were in school or maybe even now. But I guess when I was, the way that I like to think about scales in the sense of D3 in terms of data visualization is that we use scales to map from the input data to the display. And what I mean by that is oftentimes in data visualization, we might have a data set that's like, you know, there's the date and there's some sort of a value. Let's take, for example, you know, average city temperature across a year or something. And maybe you want to put that as a scatter plot or like a line chart or something as your visualization. And so in that case, you might think of it as your x-axis is your time. Like the date across say a year and your y-axis might be say the temperature across time. And so in that case, your domain would be the date or the time. And that date, you can map it to the x-axis, the x value. And that's your output. So your domain in that case is the date and your range, your output is the x value. And then maybe you have another one that's your temperature is the domain. So your input and your output is the y value. And maybe for whatever reason, you also decide to map some other data attribute to opacity, et cetera, et cetera. So in data visualization, we think of the input, the domain as the data attribute. And we think of it as we're trying to map the data to something on the screen. So let's take, for example, some of these things. So I just drew something like I just wrote down some things. So for example, maybe your domain is your minimum is zero and your maximum is 100. And your range, your minimum is zero and your maximum is one. So if you input zero, you'll get back zero. If you input 20, you'll get back to 0.2. If you input 75, you'll get 0.75, 100, and you get one. Or like maybe, for example, maybe you want to do something like your data has a minimum max of zero to 100. And then maybe for your range, you want to do 500 is your minimum. Like you want to map your zero to 500 and you want to map your 100 to zero. And the reason why this might be something you want to do and the reason why we use scales so often in D3 and in data visualization is because, should I route this or? Huh? Whoa! Cool. Who wants this? Does anybody want this? If not, I'll just leave it here. Thanks for taking them. Okay, so the reason why we might want to do something like the input being zero, 100 and the output being 500 and zero is because maybe sometimes you'll have say, maybe this is your temperature. Let's say in Fahrenheit because that would be really shitty if your city goes to 100 Celsius. So let's do Fahrenheit. Is my mic still okay? Back there? Okay. And then maybe this is your y. This is your y value. Which means that, let's say this is your screen, which means that this should be your zero zero and this is your zero 500. So then that means that for what we're trying to do, we're saying, okay, if one of these days, the temperature is zero, then we will want to map it to 500. So for example, for that, what we have is maybe the first day is zero. So we map it to here. And then the next day we have 20, so we map it here. And the next one is 50, and it's 250 here. And it's 75, so it's about right here, 125 on the screen. And then 100 is here. And that's just nice because so this was a zero degrees one and this was the 20 degrees one and this is the 50 degrees one. This is 75 degrees and this is 100 degrees. And this is nice because without that scale, maybe you will have had to do something like, okay, so it's zero degrees, but then we need to, or it's zero degrees, but then we need to put it all the way down here. So you have to do the calculation yourself of inverting the things for the screen because y-axis goes down like that. And now if you have a scale, you just say, okay, map my minimum to down here and map my maximum to right here. And so it's just like you don't even need to do with the math yourself. So scales is like the way I like to think about it is it does all the math I don't want to do for me to put things onto the screen. So this is what the code might look like for a scale. Again, a little bit small, so follow along on your screen. So I have some, this is just kind of fake data, but so maybe I have a, I say I want a screen height, I want a height of 600 as in like, I want my visualization to fit into a height of 600 pixels, let's say. And then let's say I have a data set and maybe it's something like it has a date attribute and a temperature attribute. And then here, and then maybe I only listed out two, but like maybe there's like, you know, 50 or 100 of them or something like that or like 200 point data points, however many there is. And all I have to do is say d3.min pass in my data array and give me back the minimum date, d3 max, give me back my maximum date. Is that pretty straightforward? Take in this data array and give me back whatever the minimum date is and whatever the maximum date is. Really straightforward, right? Because you guys all do JavaScript, right? Yeah, right? Sorry. Sometimes, so I've taught a lot of work, and sometimes if you teach data visualization workshops, sometimes the audience are like data scientists or designers and sometimes they won't have like coded much in like beforehand. So like sometimes I have to explain like JavaScript concepts and stuff to them. So like sometimes they'll ask me what this arrow is, like what the fat arrow is and all of that. So just make sure everybody is like perfectly good with the like fat arrow and all of the syntax is okay. Yeah? Cool. Okay. So the minimum max is really straightforward. There's another one. There's a another d3 functionality that's like really useful and it's called d3.extent. And what extent does is it gives back, you tell it what attribute essentially like you tell it like what you want the minimum max of and then it returns that in an array. So like here you're just saying d3.extent pass in the data array and then you say okay out of that data array for each of the data objects, give me back the date attribute and then d3 will give it back to you as an array of min and max. And that's cool because you want to pass the domain, d3.domain takes in an array of min and max. So in this case, we're basically taking the min and max from here and passing it into the domain but you could also have just put in like I called this extent here, right? We could have just did.domain.extent and that would be the exact same thing. And then of course here what I'm doing is saying the range is I want to map the minimum to height. So like I want to map the minimum to the bottom of that visualization and I want to map the max to zero which is like basically the top of the visualization. Alternatively, I could have given it some padding or something and be like okay I want to map it, map the top to 20 or something like that. But that's how I commonly use scales. And before I go on, how does that sound? Quite straightforward, right? Yeah? No confusion. Okay, because you're going to use scales later in an exercise so if you have questions, you should ask them now. Okay. Okay, so here are some of the scales I use the most often. I use scale linear which is like basically like it sounds a linear mapping from the domain to the range. I also use scale log a lot. So that's a logarithmic mapping. Yeah, from the domain to the range. So scale time is really great for dates. So you put in, so for that one, the input needs to be a JavaScript date object. And then the range could be anything. The range could be like, usually the range is, actually the range should be numbers. And so that one's really helpful, especially if you have like for example an x-axis. Again, that's like the input, the data input is date objects and then you want to like map it to your x-axis. And then there's some scales for ordinal scales. So the previous three are the continuous scales that I use the most often. And for ordinal, ordinal just means that your data might be categorical. So instead of categorical and has an order. So whereas continuous could be like 0, 1, 2, 3, or like 0, 0.1, 0.2, like it's a continuous scale. Ordinal could be something like, something categorical. Naughty, what's a good ordinal scale example? I'm going to call on you. Sorry. Thank you. I really like wasn't, I couldn't remember one. Thank you. Weekdays. Weekdays, yeah. Yes, this is a good one. Oh yeah, t-shirt sizes. Yeah, anything categorical, anything discreet. Thank you. It's kind of hard thinking up here. There is an inherent order to use it. Sorry, what? Ordered. So there's no, you can't say that you can't subtract weekdays from each other. Like it's nothing, but there's an order to them. Monday comes before Tuesday. What's the discreet one that doesn't have order? Color, country. No, no, I mean, what's it called? I can't remember. Like scale, because it, because it. No, we didn't say scale. So, okay. Okay. Okay. Thank you. Yeah, those were good ones. Okay, so scale band for that one. Let's see, D3. So here is the reference for D3 scale. And so some of the ones I mentioned, so there's continuous and you can have linear power log identity time. Sorry, the ordinal ones I mentioned just now was it's a band. It's like basically what happens is for, so each of these blue like boxes are basically a cat, like a, like this could be Monday, Tuesday, Wednesday. So like your domain is like Monday, Tuesday, Wednesday or you know, small, medium, large. And then your range will be like, it will literally calculate for you. So this first box should start at 10 pixels. And the next one should start at like 30 pixels and then 40 pixels or something like that. You can just set, you can tell it, I want the padding between each of these boxes to be 10 pixels or something. And then like it will calculate all of that for you. It's really nice. So, yeah. So it looks like, it looks like, so this is like D3 scale band. And you can say my domain and you can say the range that it should take up. So like maybe here it's like, the domain was the three things and maybe your range, yeah, it actually says that really nicely. So your range, maybe this was like 0 to 600 or something like that. And then maybe I like told it that the paddings were 10 each and it will calculate the starting and ending point essentially. Or sorry, it will calculate for you, yeah, it will calculate for you the start and end for each of the domains that you put in, the categorical domains that you put in. So some really nice functionality in here that you can check out if you have the time. But yes. So those are the ones that I use the most often. Yeah. Okay. So we're going to, so that's the end of scales. Yeah. Scale ordinal is not a thing. Is it not? Wait. Nadi, I told you you should teach this workshop. Yesterday I told everybody that Nadi is teaching this workshop. Thank you. I learned something. Actually, so it was actually, I think I remember it being in v3 and then when it went to v4, I think I just like didn't find it. Like I think I just like always just went straight here or something and like thought that he took out ordinal. Like I thought he took out scale ordinal. So yeah. Yeah. Apparently there's scale ordinal. Cool. So, oh yeah. And then this is the colors that Nadi is talking about. So you can have, yeah. So you can input, usually it assumes, wait, given the number t in the range zero one. Yeah. So it assumes like you give it some number between zero one and it will give you return you a color. It's really nice. Cool. Let's move on. Okay. So we're going to get into d3d3 now. So let's start with selection and data. And let's start out with this piece of code. So this piece of code basically draws this very ugly bar chart. And so let's talk about how it's doing that. And let's talk about, first of all, here's our SVG and there are five rectangle elements in there. And here we're saying, okay, d3, can you go and select all of the rectangle elements that you find in this document. So select all the rectangle elements that exist. In which case it will go and select all five of these rectangle elements because that's what's in the DOM right now. And if you actually console log what d3.select our rectangle returns, this is what it looks like. This is how d3 represents its selections underneath the hood. And in a bit, we'll play with this and then I'll ask you guys to console log things. But for now, what you need to know is that underneath the hood at d3 selection is basically an array of arrays. Wait, it basically wraps all of the DOM elements into an array that it can then do a bunch of operations on. And then here we say .data and we pass in our data set. And our data set always has to be an array. It can be an array of numbers. It can be an array of strings. It can be an array of objects. But it always, always has to be an array. And that's just because this is what's happening underneath the hood. So when you do .data, when you bind data, what d3 is essentially doing is it's saying, okay, we've just selected all of these rectangle elements. And now I've been given this data set, this array of data. We're going to map them one to one. So here was the data, right? Like this is the data and it's 100 to 50, 175, 200, 120. And here's all of the rectangle elements that got selected. So d3 underneath the hood when you do .data just says, okay, 100 goes, so the first data element goes to the first rectangle element, second one to the second, third one to the third, fourth one to the fourth, et cetera. That's why both of them, like that's why the DOM selection, the rectangle selection is an array underneath the hood. And that's why the data that you pass in needs to be an array because it's going to do that one to one mapping. And again, this is what it looks like underneath the hood. If you go and now console log what d3 select all .data returns, this is what it returns. So now here's the interesting thing. How does d3 bind data? And so it literally is putting in for, it's literally putting into the rect element, like this attribute underscore, underscore, 120. And so if you open up any of the previous rectangles, you'll see that if you open up the first rectangle, it will have underscore, underscore, data 100. And this one will say 250, 175, 200. And that's how later on when we talk about how to use the data that's been bound, that's how d3 is getting the data that's been bound to the element and using that. So let me show you what I mean by that. So now that we've bound data to the elements, we want to say, so right now we're doing attribute x, attribute y, attribute width, and attribute height. And that's how you draw a rectangle. Sorry. I'm just trying to keep a straight face. So attribute x, y, width, and height. And so essentially what's happening here is we're looping through each of the rectangles in the selection and we get passed in a data and an index. So you can see here, for example, for the x attribute, I'm getting passed in a d and an i. And that d is that data that got bound to that element. So a little tiny little thing. That's what happens if I console log the index, the data, and the element itself. So let me try and see if I can walk us through it. Okay. Let's do this. Let's walk through the x, y, width, height attributes together. So we have data 100. We have data 250. We have 175, 200, and 120. Okay. And then we have rectangles. One, two, three, four, five. And let's together calculate what our x, y, width, height is for each of the rectangles. Yeah? Okay. So help me here. So x is supposed to be i times, and I think rect width I define as 100. Thank you. Rect width is equal to 100. So rect width, I just realized, you guys in the back can't see this, huh? Okay. Okay. I'll write bigger. So for the first rectangle, what's my x? Thank you. Y is height minus d. Wait, but what's my d? Yeah. Yeah. Hold on. Actually, let me do this really quickly. So d is equal to 100. Sorry, you guys in the back. i is equal to zero. d, let's say d is 250 for the second one, right? And then this is 175, 200, 120. Okay. So what's y? What's y for my first one? Thank you. And then what is w for my first one? Oh, thank you. And then height is what? D. So d would be 100? Cool. Okay. All right. Let's do x for this one is? Thank you. 100, y is 600 minus my data. What's my data? 350, my width is the same as 100. Okay. We don't have to do width because it's the same every time. Height, cool. We'll do the third one and then we'll move on because I'm pretty sure you guys got the idea, right? Yeah. So x, thank you. Y, 600 minus 175. 425. Thank you. And then height, 575. Cool. So did that help? That's essentially what d3 is doing underneath the hood because it just basically for each of the attributes it executes the function that I've passed in given the data and the index. So here I want you guys to take like 10 minutes and I believe... Uh-oh, hold on. Do I not have... Oh no. I don't have the code for this. Hold on. Okay. Give me like a minute to try and find that block. Or sorry, that code so that you can play with it. Actually. Okay. So now try refreshing and then go to this link. So it should be right after this slide. There will be this link. Open it up and that will be the bar chart. This ugly bar chart. And then what I want you to do is take five to ten minutes and open up your dev console and just like try, you know, like comment out pieces and then just console log. For example, just console.logrect down here and then try looking at what that outputs. So here, for example, when I console log just the D3 selection you can see if I open up groups, it gives me this array of rectangles and those are actually rectangles in the DOM. And then, for example, if I uncomment the dot data part then the array of... If you go under groups, you see that array and if you open up these rectangles all the way at the bottom you'll see the underscore underscore data that's bound right here. And that's how D3 is quote unquote binding the data to your selection of DOM elements. And that's how underneath the hood D3 is basically when it loops through the DOM elements to, you know, your function to like, you know, if you want to set X attributes or Y attributes and all of that that's where it's getting the data from that you've bound. So let's give ourselves five minutes to just go through this code and, you know, comment things out, console log things just so that you can get a little bit of an intuitive understanding. Try to like, you know... I also suggest trying to put like, for example, instead of like doing return I times with or something try like doing zero or something and like seeing what happens like play around with what the functions return so that you can get an intuitive feeling of what's happening. And if you want to like do it with your table partners and then like you guys can kind of explore I think the two most important things is understanding what each of these functions return or sorry, each of these lines return and number two, playing around with what each of these functions return for each of the attributes and how that affects the overall visualization. Cool. Let's go on to 3.20. In a particular moment there's no rectangle element so it selects nothing, zero. The answer is an empty selection. So how are those bars, those five blue bars, even appearing? And the answer is that part, that's the magic. That's what I like to call D3's black magic. So those three functions that are chained together, the dot data, dot enter, dot append, those three together are what creates those rectangle elements that you saw earlier. So let's go into how that's working. So first of all we have the function dot data and you saw previously that dot data what it did was it looks at the selection, the D3 selection and then compares it to the data that we pass in. So previously it had five rectangle elements and it had five data elements and it was able to just kind of one-to-one map each of them. But this time around, as you can see, now D3 is like, well, wait, I have zero rectangle elements so it's completely empty over here and I have five data elements on this side and D3 goes, oh, okay. So for me to be able to sync that, I need to be able to match them up one-to-one. So for that to be able to happen, I need five rectangles to match the data. Super straightforward. So then it will return that and dot data will return that information and it will say, okay, to have the data and the rectangles, to have the data and the DOM be in sync, we need to create five new rectangle elements and then dot enter will go and say, okay, dot enter will say, okay, so we need five new rectangles to put in placeholders and bind that data and finally dot append will say, okay, create a rectangle element for every one of those placeholders. That's the three functions that's being changed together and that's what's happening for each of those functions and that's it. That's how those rectangles get made. Super straightforward, right? It's like, that was it. And I always forget actually how quick this explanation is so do you guys want to learn how to do update and exit also? Yeah, awesome. Because originally I didn't have it in the plans, but so to follow along for that one, go back to my website or like the slides, the slides.com. And go to this slide, this set of slides called front end masters D3V4 and open that up and so I'm going to really quickly go to the section that's update and exit in here which I'll tell you in a little bit what slide number that is because I feel like this is actually the fun part. Did anybody get to it? Oh, there we go. Okay, so update and exit is slide 25. Actually let's start with slide 26. Yeah. So just now we covered enter append which as you can guess, what it does is it helps us create DOM elements that don't yet exist based on the data we pass in. So when a user maybe first, when someone first gets to our visualization, when we first load a web page and we start our visualization, it might be that we just need to create a bunch of elements like a bunch of bars, a bunch of rectangles or something like that because they're coming into the web page for the very first time, obviously the DOM is going to be empty. So then we're going to be entering depending on a lot of rectangle elements. But let's say after that, maybe you have a real-time visualization or something like that. And maybe that real-time visualization is a series of bar charts and then every, let's say, minute it updates or something like that. So in that case, maybe some of the bars have to get exited. Like maybe some of the bars have to be removed from the DOM. Maybe some of the bars need to be updated. And maybe some new bars will happen and it needs to be entered. And so how do we do that? And that's what D3's Enter Update Exit pattern takes care of. So that Enter Update Exit is so that we can go from one state to the next and update accordingly. So the way that it works is... I said 26. Okay. I think I say... So I'm... Oh yeah, this is a pretty good example. So the reason why we have the Enter Update Exit paradigm is this thing called Object Constancy because you might have in the dataset, like for example, this one is, I guess, top states by age bracket. And it says Florida and Pennsylvania, West Virginia, et cetera. And when I change the data, the underlying data, so this one is 65 years and older. Actually, this dataset is always fun because Florida is far above the others in terms of 65 years and older because Florida has a lot of retired people. Let's see, maybe... Let's see what under five years, like which states have the most tallers? Actually, yeah, I don't know who that would be. Apparently, it's Utah. Wow. Oh. Oh. Are you from there? A lot of friends from there. This is the Mormons, right? Okay. That makes sense. But did you guys also see what happened? Okay, let me switch back. Do you see how there was an animation? There was a transition. It went from... because Florida is no longer in the top 10, so it got pushed down and then there's a bunch of new ones that appeared. So you can see some of them move down, some of them move up. Let's try this. Do you see that? Some of them remain on the screen. Do you see how some of them are remaining? Some of them might get updated. Some of them get removed. Cool, yeah? So this is the concept of object constancy, that for example, if you have Florida and Florida drops, say, all the way out of the age bracket, all the way out of the visualization, then you want to be able to show that between one state and the next. You don't want just, like, this is Florida and then suddenly it's Arkansas, but you don't get that consistency between the first state and the next. I think... and I showed that... So to do that, the secret of being able to map, being able to kind of maintain that across different data states from one dataset to the next is this key function. So up until now, for the .data function, we pass in a data array, right? And that was it. All we did was pass in a data array. Now, what we can do is pass in this thing called a key function. And what a key function does is controls which data, which datum is assigned to which element. And so for the key function, we always, always want to return whatever is the ID of that datum so that it can get assigned to the right DOM element. So let's take this, for example. Let's say, for example, that... this is what's currently on the screen. So let's say, for example, that we've already created our first set of rectangles. This is actually what's currently on the screen. And here's all of the data that's already been bound, right? This is actually our previous dataset. Now, 101, 250, 175, 200. And let's pretend for now that this data that's been bound is also our key. And then now let's look at the next dataset. This 230, 120. The first thing you can notice is that there's now six elements instead of the five. So what that data does is the first thing it calculates is it calculates the update selection. And it says, oh, hey, in the new dataset, there's 120 and 250. And that's also in the current selection of rectangles. So that must mean that these two rectangles match the data, so they'll remain on the screen. This is our update selection. Remember that term, update selection. Update selection is the selection of rectangles or a selection of elements that will remain on the screen. And then D3 will say, okay, now let's figure out what's extra in the data, the new dataset, that's not in the rectangle elements on the screen. And it says, oh, it's these ones, 230, 300, 145, 75. None of that is over here in the rectangle elements. And so it would say, okay, I need to be able to create four rectangles to match the data. And that's the enter selection. And finally, that data will say, what are the rectangle elements that do not exist in the data? And that's the 100, the 175, and the 200. And so D3 will say, okay, this is the exit selection. And these are the rectangles that we need to get rid of. These are the three rectangles that we need to get rid of so that we can match the new dataset. Cool, yeah. So enter, update, exit selection. Now that we have that, oh, this is where I show you what console logging it looks like. So what this whole thing returns is this. So this is your enter selection, the enter placeholders. Here is the exit selection, the three rectangle elements that we're supposed to remove. And then here is the two, this is the update selection, the two rectangle elements that can remain on the screen. So if you console log right here, oh, sorry, this bar is right here, that's what it looks like underneath the hood. The enter selection, the enter placeholders, exit selection, and update selection. And then we want to save that into a variable. In this case, I call it bars, so that right here I can say bars.exit, and that gets me the exit selection. And then take that exit selection and remove them from the screen. That gets rid of all of the rectangle elements that aren't in the new dataset, removes them from the DOM. Next, this part should look familiar, right? This bar is the enter that append rect. That's exactly the same as before. And then that basically will say, get the enter selection. For each of those four rectangle elements, append, or sorry, for each of those four placeholders, append a rectangle. And then we want to set the attributes with a stroke. And for the enter selection, I like to chain the attributes that don't depend on data. So like if you can see in here, it's just the rectangle width and the stroke, because neither of these are dependent on, like it will not change no matter what the new dataset is. And finally here, we basically say, give me the enter selection, as well as the update selection. So the bars one is the update selection. So combines the two selections, the enter and update selections into one. And that's essentially basically what should be on the screen for the new dataset. And then calculate the x, y height and fill for the enter and update selection. Basically update the attributes that are based on the data at enter and update selection. And that's it. So actually with these few lines of code, you can actually, actually with these few lines of a code, you can actually have that same effect that we looked at earlier with the age population. The only thing that we're missing with this one is we just don't have the line for animation. And that line for animation is just like one line. But this will take care of drawing all the rectangles and updating them on any data change. Isn't that really cool that it's like only like what that's like 15 lines or something and it takes care of like basically all of the animations and transitions that you saw earlier? Yeah, that's all you need. That's D3. That's the core of D3. Cool. So it is 340. Okay, so it is 340. So this is the thing that I want to do next. I'm kind of pretty excited for this one. So go back to the workshop slides. And what we're going to do is turn the petals that you created earlier into a flower. Are you excited? I'm pretty excited. So here's what we're going to do. I'm going to click on the starter code. And this is the same movie data that I used in my visualization. And I've already kind of like, what's the word? I cleaned it a little bit for you. So use this movie data. And you can see there's like data for the rating, the IMDb rating, the number of votes, the title, the parental guidance rating, et cetera. So here's the three things that you want to do. Here's the mapping. So the type of petal is your parental guidance rating. The size of the flower is the IMDb rating out of 10. And the number of petals is the number of IMDb ratings. So I've created the scales for you in this starter code right here. So what you have to do is figure out your domains for the size and the number of petals. And then here is basically the path lookup. So like I just say these are the parental guidance ratings. And you just need to add in three more petal paths to right here. Does that make sense? And then add three in there. And then right down here. I've given you instructions. I've also given you instructions right here. Let's do this for about, let's try until four tentatively. And then we can go through the solutions together. And do this with your table partners. And I forgot to mention for this one, you don't need the update exit. All you need is the scales, data, enter a pen. So for this one, all you need to do is take the data and create the petals. You are amazing. Oh, and I will not be offended at all. If you want to click on the complete code and then take a look at this like, so this is the complete code. But if you're going to look at the complete code, I will urge you to not copy and paste things over, but rather type it out yourself. Uh-oh, okay. Just have it side by side, type it out yourself and try and figure out what each line is doing. And try and solve that with your table partners. And then the hint I give you is that you need to use SVG transforms translate, rotate, and scale functions to be able to get all the petals. But you should end up with something like that by the end. Yeah? Awesome, good luck. Oh, there we go. Okay, how did that go? Did I just go from like zero to 60 really fast on you? No? Okay, so how many people were able to get a flower? That's awesome. Nari, you don't count. But thank you. So shall we go through it together? Awesome, okay. So everybody's going to help me. Okay, let's get started. So first, let's set the domain for scales and we agreed that there were two scales. So the size scale is with the rating, right? And then the number of petals scale is with number of votes. So let's use d3.extent like we talked about earlier. So let's call that const size extent. It's equal to d3.extent and we pass in the movie's data. And then we use d.rating. You can console log that size extent. And then const, let's do the same thing for numPetals. So let's say numPetals.extent is equal to d3. Can you guys see it in the back? Or should we turn off the lights with that help in the back? Yeah? Now we need to figure out how to turn off the lights. Oh, you can see it? Okay, I'm d3.extentmovies and then this time we use d.votes. Let's console log that to numPetals.extent, inspect element. Here, hold on, I'll move it out of the way. Awesome. So the minimum that we have is 5.6 for rating out of 10 and the maximum is 10. Wow, I wonder which movie is out of 10 out of 10. And then the number of votes minimum is 16,000, maximum is 1.6 million. Okay, so far so good, yeah? So we figure out the min and max domain for both of the scales. And now we have to set the scales. Set domain on scales. And that would be the size scale. So the size scale that we've defined up above right here. So you can see the size scale is a scale linear with a range of 0.1 to 1. And then the numPetals scale is scale quantized. And I don't know if anybody looked it up, but scale quantized is a super useful thing that takes a continuous domain and maps it to a discrete range. So what that means is if you think about it, number of votes, just now you saw the number of votes is like 16,000. Oh here, you guys can. From 16,000 to 1.6 million, right? So that's like a continuous number. That's our domain. But number of petals, we want that to be discrete. We want that to be 5 petals, 6 petals, 7 petals, 8 petals, 9 petals, et cetera. So scale quantized will help us map that continuous 16,000 to a discrete number of petals. And that's what scale quantized is doing. So we set size scale.domain is size extent. And then numPetalsScale.domain is numPetals extent. Now that we have the domain figured out, let's just make the petal data for just the first movie. And so first of all, let's figure out the number of petals for that first movie. And so we're using numPetalsScale. And thank you so much for pointing it out because there was actually a bug in this version, in the complete version where I forgot to use dotvotes. So numPetalsScale, and then we just pass in the number of votes for the first movie, right? So that would look like movie, first movie, dotvotes. Number of votes for the first movie. Movies, sorry, movies. Okay, let's console log that and see how much that is. So movies, zero dotvotes, numPetals. And cool, so it's 354,000 and we're going to make 6 petals. Whoa. Wait. So far so good? Okay. Now that we've figured out the number of petals for our first movie, we now need to create our data array, right? So basically we want to create five petals, so that's five path elements, right? Or sorry, we want to make six petals, so that's six data elements in our array, right? And so you can do this a number of ways, but the way that I like to do it is I like to use low dash, pass in numPetals, which is six, and that just gives me the index. And this low dash dot times, all it does is you pass in a integer and it just does the four loops, that number of times. I think you can also just do four loops, that number of times, whatever that you're happy with. I like using low dash times, underscore times, numPetals. And then for each of the petals, we want to do, we want three things, right? So for each of the petals, actually maybe I'll just comment it. For each of the petals to draw them, the first thing we need to know is the rotation of the petal. The second thing is we need to know the type of petal or the path of the petal, right? So the three different petals that you guys made earlier, we need to know which one we're using and so that's parental guidance ratings. And finally, we want to use, we want to know the size of the petals, the size of the flowers. So that is size of petals and that's where we're using the IMDB ratings. Okay, which means that what we want to do is, first of all, the rotation is basically you want to rotate it. So SVG's rotate takes degrees, so anywhere between zero to 360 degrees. So our rotation should be our index out of our number of petals, right? Because that will give you like, it's the first petal, so that's zero and then like, and then one out of six and then two out of six, two divided by six, et cetera, multiply by 360, which is our number of degrees. So that's our rotation. So rotate and then path of petal is, we can just say, I call it path lookup. So up here I have, oh yeah, path lookup. So path lookup and then movies, zero and the parental guidance of that movie. And finally, the size of the petals. So size and we're using size scale and for size is, we said IMDB ratings. So movies, the first movie dot rating. Cool. So, and then I need to actually return that to console log petal data. Look at that, path is undefined. Did something wrong. But oh yeah, look, so the rotation is right, zero, 60, 120, 180, 240, 300. And the size should be the same because it's the same movie. So let's figure out what went wrong with the path. So path, we said path lookup. Maybe I said paths lookup, no path lookup, movies, zero dot PG. Why would that be wrong? Path lookup. You don't have enough petals. I don't have enough petals. You don't have enough path lookup in the array. You only have none actually. Thank you so much. So let's see. Yep. And now, yay. So I have the paths and I have the rotation and I have the size. So I have all of the data I need to make my path or make my petals. So far, does this all sound good? Okay, I'll take your silence as a yes. And so now that we have the data and then delete all my console logs, all we have to do is do the data dot data dot enter dot append from earlier. So SVG dot select all path dot data put in the petal data dot enter dot append path. So that's what we talked about earlier dot data dot enter dot append. And now if you actually inspect the DOM, oh my God, you can see there's six paths that were made just as we expected. So let's do the first thing. And that is the first thing that we need for a path is the path string. And we set that on the D attribute, which I just realized I never said. I forgot to mention that earlier. So to draw a path, all of the path strings that we were doing earlier with the curves and the lines and the move twos, that needs to be set on the D attribute of a path. That would probably have been important for me to mention. So sorry about that. So for the D attribute, what we want to do is use the path that's been bound. So D dot path. And look, we already have a little thing that's been drawn here. And then we want to, actually before we do that, did anybody look up SVG transforms? So for the people that did, does anybody want to talk about it briefly? The SVG transform. So it is basically you can apply these transforms to any of the SVG elements. The ones that I use the most often is translate, scale, and rotate. And they do exactly what they sound like. So translate will move over that element by an x, y position. Scale would be, scale of 1 is 100%. Scale of 0.5 would be 50%. A scale of 2 would be 200%, et cetera. Oh, and then if you put in only one number, then it will be scaled to both the x and y direction. But if you put in two numbers, then it will be scaled to the x direction and then the y direction. And then you have a rotation and you put in the angle out of 360. So let's do that. Let's first do the translate. So if you notice right now, this pedal is right here because that's my 0, 0. And there's absolutely no translation. And if you notice, I actually start, I think I center all of my pedals at 0, 0. So the first thing I want to do is move the pedals over. And so I'm just going to say translate 100, 100. Oops, 100, 100. And that's just like a random, I'm just picking up random magic numbers of 100 and 100. But I do want to say very briefly that when I'm translating something, what's actually happening is you can think of it this way. So let's say we have an SVG and this is 0, 0. The way that I like to think about it is that when you set the x and y coordinate of an SVG element, whatever, so basically everything, let's say I draw this rectangle and this is at 10, 10. This 10, 10 is relative to the parent SVG. So it's kind of like how if you do a div within a div and then you set the outside div to position relative and you set the inside div to position absolute. That's kind of what happens with SVG naturally. So that's like if you did div is position relative and this is div is position absolute. That's kind of like what's happening inside. But here's an interesting thing. So right now this one is x is equal to 10, y is equal to 10, right? So like for this rectangle, I'm saying x is equal to 10 and y is equal to 10 and that's being positioned absolutely relative to the parent SVG. But if I do a translate, then here's an interesting thing. If I do this rectangle and I translate it 10, 10 and I have x is 10 and y is 10. Something really interesting happens which is that it actually gets, let's say this is 20 and this is 20, it actually gets positioned here. This ends up with this. Isn't that fascinating? Okay. So what do you have? I guess why this actually results in this. So this is 2020. Anybody have a guess why this is happening? So the reason, huh? The coordinates just then changed. Yeah. Exactly. So the reason why this is happening is that when we do our translation, essentially we're saying, okay, pretend that this element has this invisible parent div and that parent div has moved down to 10, 10. So instead of now for this rectangle, the new coordinate system is now here. So this actually is the 0, 0 for this rectangle now and then this is the new 10, 10 for this rectangle. Isn't that fascinating? I love the translation. No? Okay. But I'm saying this only because this will also come in handy when we're doing the next step. We have one more exercise after this. So yeah. So essentially this is really helpful because as you can imagine all of our paths are relative to 0, 0. So we've defined all of these paths as like start at 0, 0 or 0, 50 or 50, 0 or whatever and then it's curving to like 100 or something. It's still got its own coordinate system. But when we use transform and translate, we don't actually have to make up new numbers or anything. So we just have to say translate 100, 100 and then it will basically shift the coordinate system around so that, yeah, so that that happens. Okay. So I'm not that great at CSS. I'm pretty sure this is how CSS transforms work too. Is it true? Yeah. Okay. What? CSS has unit but in SVG it's unit less. Okay. Like if you do CSS transforms and such. Cool. Yeah. So let's translate it 100, 100 and then the next thing we want to do is we want to rotate. So previously we've calculated our rotate. So all we have to do is use that. We say D dot rotate. Oh, oh, hold on. I'm using a string literal. So dollar sign, open bracket. Ooh. Did that happen for any of you? Wait, you haven't been typing along or anything, right? Okay. Sometimes people type along and then they're also like, ooh, because that happens for them. So yeah, so that happens because we've now rotated all six pedals. And then finally we want to scale. So scale and then we use what we previously calculated. So that's D dot size. And it just gets scaled smaller. And then because I don't want it to be filled, I just say fill none and then stroke. I'm going to say black. That's it. Any part that you want me to elaborate on. Do you have your own flowers? Were you able to get your own flowers? Cool. Okay. Are you ready to move on? Because it is, I believe, 4.36. And so we have 24 minutes to make the rest of the flowers. Are you ready to make the rest of the flowers? Nope. Was that Yuzel? Okay, wait, let me ask you this way. So did we cover it enough such that if you go back and look at the code yourselves, you'll be able to get it, or do you want me to elaborate on any of the parts so that when you go home and look at it yourselves, you can understand it? Because that's my goal right now. Out of the three steps that we talked about, tell me about any of the parts where it didn't feel quite intuitive and you want me to cover again. The person that said no back there, what do you want me to elaborate on? Are you sure it's fine? Okay. Are you ready to move on? Oh, there it is. Okay. Yeah. Oh, yeah, yeah. Yeah, yeah, yeah. Huh? Oh, yeah. Yes. That makes sense. Please go do that. Yeah. Because you guys have been here and here for the last three and a half hours. No, three hours or so. Yeah, I went to a pee break though. So I snuck out for that. Yeah, no. Please go. And then in that case, are you all right with it running over a little bit? Yeah, a tiny bit? Yeah. Okay. So five minutes. Relax. Go outside. And then we're going to make the rest of the flowers. Let's get back into it. It is now 453. So I'm going to try and finish up. Hey, hey, hey. Thank you. Okay. So it is 453. And we're going to try and finish up the last few part of the last part. Yo. Thank you. Hi, guys. Up here. Okay. So we're going to try and finish up the last part as quickly as we can. And that is to finish. We're going to draw the rest of the flowers. And to do that, we need to be able to nest elements. So nesting elements is basically like, we want to do that in SPG. We want to do that when we want to apply the same styles and transforms to a group of elements. And so in the case of the flowers, basically we have a group element in this case that consists of both the petals and leaves. And then I've applied the transport, applied translate and scales on them. And then within them, I have the paths that make up the petals and it just has the rotation applied. Because the rotation is unique to the petals, whereas the translate and the scale is applied to all the petals. So we can do the translate and scale on the group elements and we can do the rotation on the path elements. So that's what we're going to go full forth and do. And hopefully we'll be able to finish before the 530 group picture and the food. So let's start out with, okay, I'm going to go through this as quickly as I can. So this is the next piece of code and this just shows you how to nest elements. So essentially this is, here's the data set and then we have a group of G elements and a set of circles within those group elements. And what that looks like is, oh so as you can see the data is there's a set of circles that have a red fill and a set of circles that have a blue fill. So let's see how that's working. And so at the very here, I'm using, I'm saying SVG select all groups, that's tiny. And then so I'm using the SVG group element to nest child elements because in SVG, unlike HTML, so with HTML, we'll be doing, we'll nest all of these different elements. We can nest divs within divs, we can nest paragraphs, we can nest spans, we can nest almost pretty much everything we want with HTML. And then you can apply styles to them or you can translate things. But within SVG, the only element that you're allowed to nest children is the group element. So if you try to nest a rectangle within a rectangle, a circle within a rectangle, any of those nothing will happen, like it will not work. Only group elements can have things and group elements can have group elements nested within it. And yeah, so group, group elements, circles, rectangles and stuff, you can nest all of that within a parent group component. And so in this case, what we're doing is we're saying the same data enter a parent pattern as before. And we're saying I'm, you know, here's my set of data. And basically, my data is that first like buying that first object to my first group and buying the second object to the second group. So then what I'm doing is basically saying the first group of the first data set or sorry, the first data object has a fill of red. And so once I found that I'm using it in the outer fill and then I'm returning D dot fill. And that's why previously you saw all those circles have a red fill. And then the second one is has a fill of blue. So then like back here, you saw all of these circles had a fill of blue. So that's what's happening. Yeah, so this gets created two groups. And then down here when we're doing the when we're creating a circle for when we want to create a bunch of circles for to nest within the group. Essentially, what I'm doing is for the circles, I say I'm select all the circles in those groups. So the groups that we just created and select the circles within those groups. And then for the data, notice here, notice that instead of passing in a data, the data array like we did before, we're actually passing in a function. This is interesting. So like here when we're doing a data array, we're passing in a function. So what this is saying is basically with D3, if you create nest elements, those nested the children actually inherit the data of the parent. So what that's what's happening here is it's saying, okay, so here's the here's the data that's already been bound to the parent. So this fill red and a circle array. Tell me the data array you want for the child circles. And so here what I'm doing is I'm saying, okay, cool, this data that's been bound to the parent for these circles, what I want is to use array of circles. So here I'm saying circle array of 22550 return that. So the child data is essentially this, like, take that array of 22550 and return that. And that's the data array from my child circles. And then we do the same enter a pen. Oh, wait, yeah. So we do the dot data enter a pen. And so here's what's happening. Right. So we're basically saying, here's the parent group with the, with the data. And then we're going to just grab the array, the child array. And that's the new set of data. And that data gets mapped to the circles that we want to enter. So it's basically like what we talked about before with the data enter a pen, except now instead of, you know, like having, well, okay, yeah. So it's basically like before when we had data enter a pen, except now we're inheriting some data that we can do something with as long as we return an array again. Because remember dot data always, always expects an array. So that's what's happening here. And so all of this results in a group container with a data that says fill and circle. And within there, we have the circles that have those data, that data, that data bound to it. I went through that really fast. Do you want me to repeat? Should I repeat that? Okay. Let me try repeating that again really quickly. Let me see if I can draw that really quick. Two objects. The first one has fill is red. And then let's call this just child. And that child has an array to 2550 and 150. Find this data or when I use this data set, it creates two group elements, right? And then this is this red one gets bound to this. And this blue one gets bound to the second one. Now the fun thing is when we try to create any elements to this. So like now if we say, okay, like this selection of groups. Now try to create any children, like let's say the children are the circles. These children actually get, they actually inherit the data that's been bound to the parent. So they actually inherit this data. And they will also be able to say they will also know because we want to make a circle for each one of these child arrays. We just say, okay, actually give me back a selection of circles. I want to create a three child array. So that's why we're returning d.child. And then we're saying I want this to be applied to this one, this to be applied to this one, and this to be applied to this one. And then for the second, for the second group, I want this here, this here, and this here. And that's what's happening. That's a lot of lines. So yeah, so we're saying for its children, I want to use this array of data to create my children elements. So the last thing we want to do is make all the flowers. And this might sound like a lot of work, but it's actually very, very minimal work now that we've created one flower. So to go from one flower to many flowers is actually very little work. Right into it. Yeah, so set domain for scales. I'm just going to copy that over. And then number two is now instead of creating data for the petals, now we need to create a group for each flower, right? And then we need to translate and scale those flowers. So let's do that. So we have, let's call each of those flowers. Let's call that selection of group elements flowers. And we say svg.selectall. And then the data in this case is the array of movies, right? Because each flower is equal to each movie. So we do .movie or .data is movies. Oh yeah, if you want to type long, cool. Movies, enter, .append. And append groups. Now, if we inspect element, if we inspect svg, we'll see like a few hundred group elements that have been made, or we should. That seems like less than I was expecting. So now we've created all the group elements. We've created a group element for each movie. And then right now let's just apply the translate and scale. So transform is what the attribute is called. And then what I want to do is pass in both the data and index. The X, I'm just going to say, I believe, oh, so I'm just going to have three on each row. So mod three times, let's just move them over by, no, let's move them over by, yeah, let's move them over by 200. And I mod three plus 0.5, which just means like just move them over by a half. Basically math.floor, I divide by three. So basically whatever my index is divided by three, and that's the row that I'm on. And then again, this is just so just do 0.5 times 200. And then I want to do the scale transform. So that was const scale is equal to a size scale. And then we pass in the rating. Yes, the rating for that movie. Now we return translate X, translate X, Y and scale is scale. Thank you. And then nothing should show up. But now you'll see for each of the groups, you'll see the translate and the scale. Okay, now we have the flowers. So let's make the petals for each flower. So now instead of selecting them from the SVG, we want to select them from the flowers. So basically instead of looking, instead of working within the SVG container, now we want to work within each of the flower groups as our parent container. So for each flower, select all the path elements that are going to be our petals. And then here's a fun part. So if you want to, you are more than welcome to do, let's do it this way. So .data, let's first console log. Let's just first console log and see what happens. And as you can see when I console log here, it's the data from the movie. It's the data that's been bound to the parent flower group container. And so what we want is, like we did before, we want to use this movie data to create the right number of petals, right, and rotate them accordingly. So use this, so use this data. So now we want to say numPetals is equal to, it was the numPetals scale. And then now we use d. If we do numPetals, so still six, that makes sense. And now we want to return the array of petals, right? Now we want to return the array of petals, so I'm still doing times. So six petals. And then now, now all I want to do is the rotation divide by numPetals times 360, same as before. And then the right path, so it was path lookup d.inq. But, I need to do, I need to add in the rest of the petals on that. So d.pg, thank you. And now let's see if we have the right number of petals being made for each of the groups. Enter. I'm really happy about that, but didn't enter the path. Thank you. You are saving me right now. So now the paths are being made for each of the flowers. So now we only have a few more steps. So we need to set the attribute for the path. So the d attribute for the paths for each of the petals. And then we also need to rotate them. And that's it. So let's do that. Let's first rotate them. So transform d, rotate, d.rotate, and then adder, d, return d.path. Did that happen for you? And that's it, right? Now we just need to do, actually, tie to something really awesome. Which was that you set. I'm going to say fill none. And then tell me what was the, for the strokes, you did something where you used the color scale. So did you, is it just here you also set color? D3.interpolate rainbow. Ooh. D3.interpolate rainbow. And did you do I divide by none petals? Yes. Cool. And then d, d.color. Yeah! So much better than the black, right? Yes. All the colors. All the colors. And you even did a blend mode.style. Was it a blend mode? What's the same word? Mixed blend mode. Oh, does not work? Mixed does blend mode. Mixed no ed. Mixed, oh sorry. Blend mode and multiply? Yeah. That's what I mean yesterday. Noice. Wait, how do I make that bigger? I don't know, it doesn't. Yeah. Now you're just showing off. I'm not showing off, Ty is showing off. So pretty. Fancy. So pretty. Does that make you happy? This made me happy. Actually, let's try actually doing it as a fill instead of the spoke. This makes me happy. Look at this. What did she do? Wasn't paying attention. That rainbow at the end. Faced all the difference. Okay, so I'm going to put this into the complete code. So that you can take a look at it. With, of course, the rainbow. All the rainbows. All the rainbows. What do you mean, Meryl Streep? Meryl Streep, Ty. It's his brilliance. Look at all of that. And I really sincerely hope that you got something like this too. And I know that three and a half hours is still like not that much time to like, you know, cover all of that we did today. But hopefully it helped you get at least a little bit familiar with SVG Pads and with the basics of D3. And then hopefully you got some pretty flowers out of it. And if you are really proud of your flowers, and I hope you are, I really, really want to see them. So please screenshot them and tweet them to me. My handle is this. This is my handle. Right here. Please tweet me so I can be really, really proud of you. Okay, so they're making fun of me because they know me. And now I have to justify my handle. So that, that's my initials. My initials are surely Suyangu, so S-X-Y-W-U. And I actually made the handle without realizing the implications of my initials. And then my TA at the time was like, surely, really? And I'm like, what are you talking about? And she's like, you're a handle. You're a GitHub handle. And I was like, what about it? She's like, read it out loud. And I was like, oh, I was like, oh. And that was like seven years ago. And I have now fully embraced it. So if you need to, just remember it as sexy Wu without the E. And if that makes it easier for you to tweet me your flowers, then so be it. So thank you so much for joining today. Thank you so much for all the funds and the participation in the rainbows. And I hope you have a great rest of the conference. Yeah.