Let's Learn D3.js!
with Shirley Wu
Data visualizations add a ton of clarity and value to our apps, but getting started can be daunting. Shirley Wu teaches us how we can get started with D3.js to make charts, graphs, and more!
Resources & Links
Captions provided by White Coat Captioning (https://whitecoatcaptioning.com/). Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.
Jason: Hello, everyone. Welcome to another episode of Learn With Jason, today we are thrilled to bring back Shirley Wu!
Shirley: I am trying to figure out the boundaries in my box.
Shirley: Yes, yes! I don't know what happened before.
Jason: We cleared out of our house last week, that is why we didn't stream last week, because of the smoke
Shirley: How does it affect the boundaries sorry.
Jason: As a result, we left. I have not restarted this computer in three weeks, when we went to go live, my computer wouldn't start. It was like, you can't stream. I am like, no no no! So I restarted everything, and when I restarted the computer, it moved all of my windows! I was guessing where you are supposed to be. When we flipped over, we had to tweak. Sorry about that!
Shirley: No worries!
Jason: It is good to be back, I am excited to be back in my own house, streaming again, and excited to have you back on the show. This is our 5th show together? It is such a pleasure.
Shirley: It is! We did four with the
Jason: 3 or 4 on that, and another one on Nuxt
Shirley: We failed on Nuxt.
Jason: We did fine, haha. Did that work?
Shirley: It is like Christmas, it works! The next one, all we did was make a blank page that says Shirley is hungry, or something like that, right? Haha.
Jason: Which is a success, we got something deployed.
Shirley: It is beyond hello world, that is a success. You are right.
Jason: Yeah, so today, we will take a departure and do something a little bit new. I am calling you in as an expert to clean up after a mess that I made. And I had Nathaniel Kenwa on the show, we had a two part stream, building a text to vote game, like a quiz, a polling thing. We were able to get it working and set up, it is like Twilio, serverless functions, and they can text a vote on something, whatever the question of the day is. And where we started to get in trouble, though, is when we wanted to show the results on the screen and we realized neither one of us knows how to do data visualization properly. So we started copying and pasting stuff, and we eventually sort of got it to work, ha. But it is definitely not right, haha.
Shirley: Honestly, that is basically how we all start with D3, that is how, like, where we are for a very long time with D3. And I also want to say, I took a look at your code, it looks pretty accurate! You are 90 percent there.
Jason: Copied and pasted the right things!
Shirley: Yes, we all copy and paste in the beginning.
Jason: We have an excellent support from the chat, there's a few people that know how to do D3, you shouldn't do that, do this. So we got through that, and before we talk about what we are doing, I will talk about why we called you in. Do you want to share your background and your expertise?
Shirley: Oh, I thought just because we are friends, haha.
Jason: It is, there's a reason I am calling you, it is 95 percent because you are one of my favorite people, and there is the 5 percent where you are literally the best in the world at this, haha.
Shirley: That makes me blush. Thank you, Jason. You called me in because we always have a fun time together. That is very much hi! My name is Shirley, I am a freelance data visualization creator. And the title I give myself is changing every day, the latest iteration is independent data visualization designer and developer!
Jason: Rolls right off the tongue.
Shirley: I know, right? Ha. All it means is that I am a software engineer that started working with D3, like, eight years ago in 2012, it came out in 2011, so I have been working with it for basically all of my projects, since 2012. And I worked with it, integrating it with backbone, React, view, and I have spoken a lot about it and I have done a lot with it. So I guess that is the 5 percent.
Jason: Haha, yeah, absolutely. You have done incredible project with it, you have stuff that we have with the holding buckets stuff we did, well, actually, we did not get to D3 on that! We were playing with SVGs.
Shirley: Um, no, we did some D3.
Jason: Yeah, we did.
Shirley: Yeah, sorry, I need to remember. The funnest part was is when you picked up SVG pods like this, and it was the fastest, like, what am I doing here? I think the D3 that we did in that episode was mostly with scales.
Jason: That's right.
Shirley: So we translated raw data into, like, sizes, different dimensions and different placements. It was very little D3, actually, and mostly view. That was intentional.
Jason: Uh huh, yeah. I think this is, like, this is I am so I am excited today, you have done stuff from visualizing movie data, you are doing a project right now on your own stream, which I will try to do a shout out command, it is totally not going to work. Your twitch is the same as your Twitter, right? It is the same everywhere, yeah. It kind of worked! So you are doing a project on your own Twitch in your streams, you are visualizing the impact of the movie, Crazy Rich Asians, right?
Shirley: Yes, thank you for the shout out! And I just put that thank you for the opportunity for the shout out. I just put that project on hold, the movie Crazy Rich Asians came out in 2018, and it was a big deal for the Asian community because it was the first time there was a majority Asian/western cast in a big Hollywood movie and a number of us went out to support it, and we are trying to figure out if there have been improvements in Hollywood in terms of Asian American representation. Thus far, inconclusive, yes. Two years, and one of those years was a pandemic. So a pandemic really affects things in terms of how Hollywood moves forward. But the reason I put it on hold starting this week is I realized there's a really extremely important election coming up. And I don't know why it only hit me last week that, oh my God, it is September! It is almost November. I had intended to work with the news room. This is an informal talk where I was going to work with them on the election. And that conversation went out the window when the pandemic hit, and this year's news cycle is a lot busier, they cannot on board me, I am figuring out what I can do myself. And the idea I have, the original reason I wanted to work with the news room is I know that I don't know enough about politics and the election, it is very confusing. I wanted to work with experts, now I cannot. And I realize the spin is I come at this from an outsider, I do not understand U.S. elections. And I am going to try and learn about elections and about this particular election, and how important this election is through data. And one of the things I really want to focus on is access to voting and access to and voter suppression, and those sorts of data. So I will start live streaming and, in October, my goal is to produce somewhere between 15 to 20 byte sized charts that explore all of these different topics. So starting in October, fingers crossed, I am going to try and do a stream, like, three to five mornings of the week to try to produce one chart per day. Like, bite sized enough to go on Instagram.
Jason: If you watch today's stream and you are excited about D3, you want to go further, go watch Shirley. This is going to be a, like, a master class, right? You are just going to see somebody who knows this stuff deeply, building all sorts of data visualizations, you will see the thought process, how the data goes in, all of that stuff, and you are teaching on this. You have a is it (indiscernible) masters?
Yes, thank you! So I did a workshop for front end masters, an updated introduction to D3. And that one was recorded back in mid August, and it should be going up sometime in the next month or two. I am really proud of it.
I did one three years ago, and I feel like this one is much more of an improvement. I think it covers more material, and I think I explain a lot of things clearer than I did, like, three years ago.
So hopefully, hopefully people enjoy it and learn some things from it!
Very cool, yeah.
So I am going to, why don't we celebrate that a little bit. Let's do a front end master's subscription give away. I have a bunch of codes. So I think I can just it says it is going for the next 8 minutes, we will see how many minutes I can let it go for. You can enter with exclamation point raffle, you will get one entry. If you are a subscriber, you will get two.
If you are interested in subscriptions, it is September on Twitch and you can get a big discount on subscriptions if you choose to subscribe right now. A bunch of subscriptions happening now. We will see how many people enter and we will give away a few of these. I have a bunch of them, and you can use these to watch Shirley's front end master's course!
Shirley: Thank you, Jason, and Chad!
Jason: Yes, thank you so much for the sub, I see a lot of people looking for their tickets. That is exciting, while you are waiting for the course to go live, I had one on serverless functions go live. There's a bunch of good content, front end master's is an amazing resource. It will be a six month front end master's membership we will give away. So definitely get in on that! Okay, so let's talk a little bit about what we're going to do today. So we kind of set the scene, Nathaniel Kwon and I built a text to vote thing, we were displaying the last results, and it feels clunky. I will switch to the pairing view. And before we start looking at code, I will do a quick shout out to our sponsors. We have White Coat Captioning in the house right now, doing live captioning for us! So you can see right here, if you go to LWJ.com/live, we have a live captioner, that is handled by Lindsay. Lindsay: =).
Jason: Thank you so much for being here. And that is made possible for us through the sponsorships From Nullify, Fauna, Sanity, and Auth0 to make this accessible to more people. Thank you very much for being here, it is really cool that people are interested enough to invest in this show, right? So, yeah, definitely go check that out, I will drop a link in the chat, LWJ.com/live, you can look at the captions, if you would like to read along in addition to watching. And make sure you follow Shirley on Twitter, Twitter.com/SXYWU. And that is a good follow, Shirley has tons and tons of information. And let's take a look at what we will clean up here. This is the Twilio poll. I checked, I think I broke something with the data sync. So my live updates are not working anymore. We can see what is happening here, we have the results of these polls coming in, and then we are building a bar chart. And there are a few things that are cool about this, hey, look, we have a bar chart. There are a few things that are bad about this. We don't have labels, it doesn't it doesn't, like, if we have to change the numbers, we have to destroy the whole chart and rebuild it again. So we can look and see this code in here, this is the repo we are working out of today. And that repo is built from, let's go back here and look at here is the episode where Nathaniel and I built this, if I want to see how we got here. And all the, you know, everything that we worked on is linked in here. So where we ended up, we ended up with this let me make this bigger. We ended up with this function, where we are showing our chart as we have, just, like a div. And then here, we pull in D3 and when we get a new result, we are building our chart, and we are, like, this is all stuff we copied and pasted. So I don't know what this does. We are pulling in D3, we are doing something with scales and linear, I think, is for bar charts. I am waiting for Shirley to cringe while I explain this code.
Shirley: Oh, no, I think you are doing great.
Jason: So D3 scale linear, if I want to show a full width bar chart, I am saying I want my scale to be, like, let's say, 100 pixels. And then I need to change the numbers in my charts to be, like, width units relative to the whatever the maximum scale is. So if I have 100 pixels, I need to convert my chart to be a percentage of that, as opposed to being, if we have a thousand widgets, it would be a thousand pixels, so it will break the chart. So a thousand widgets is 95 percent of the highest possible value, 95 pixels on this bar.
Shirley: Yeah, that was great!
Jason: A ha, did it. Scale band, I don't know what this is.
Shirley: Should I explain? Haha, so Jason explained the X scale. And that was great. So just like what Jason was saying, the X scale is a linear scale. What that means is if you go, you don't have to do this, Jason. But for for people in the chat, or people that are watching, the documentation is D3 scale, and then in there it will list all of the scales that D3 has, and D3 scales, the way you can think about them, you have the raw data and like Jason was saying, let's say the raw data is 1,320 widgets, or votes, or whatever. And you don't want to have that be mapped to 1,300, right? So scales help you map your raw data into whatever you need to draw on the screen. And with D3, it has and I explained this in the workshop. With D3 and scales, the way you can think about it is, in there's different data types and some of them are continuous. So you can think of that as, let's use movies as a data set. With movies metadata, you can number of votes for that movie, and ratings out of 10 for that movie, and those are continuous, quantitative metadata. You can have discrete metadata. So for movies, the metadata is genres. And on the other hand, when you want to draw something on the screen, you want continue and discrete values. So continuous can be the width number of pixels for width or heighth, or the XY position. Those are continuous. You can have discrete values, like colors, individual colors can be discrete and the way you can can think about D3 scales, all of these are mapping continuous, or discrete to continuous or discrete. So scale linear is mapping continuous to continuous, and that is why you see right here, scale linear, and it says domain are these two numbers and range are these two numbers, map the minimum domain, 10, to the minimum range, which is 0. And the maximum domain, 130, to the maximum range, 960. And have a linear mapping between them. And so you can also have in here, you can find scale log, power, etc. Those are mappings you can do from continuous to continuous. So scale band that you have is okay. It should be a discrete mapping to a continuous, a discrete mapping to a continuous. So what this is, you maybe have a a bar chart is the best example. So you have, you know, something that is discrete, you have bar number one, bar number two, bar number three.
Jason: Haha, it is an odds chart.
Shirley: Haha, you want to map each of those, in this case, you want to map it to an X value. The range what you are outputting to is a downs value, that is why you are using a band scale, you are going from discrete to a continuous value. So that is why that is a really so if you want to go back to your code, that is what is happening with scale band, can you go back to that code? Thank you. So what is happening, you are saying yeah. You are saying, in your domain, you are saying you have data and that data presumably is all of the answers, right, the answer plus the number of votes for the answer. You are basically saying, you know, take the number of answers and then, like, create an array out of it. They always have to be the input always has to be an array.
Jason: And so this here, this is our data. We have two entries, a yes and a no value. Because we didn't label them, I have no idea which is which. So we have two entries, so what we are saying here is if we do data.length, we have two, so the domain is two, so we need two bands.
So D3.range is giving you an array from 0 2, where the end is uninclusive, whatever the word is, it is giving you a range with 0M1 and mapping that to this range of 0 to 100 and then it is also it is doing padding, and the padding you can specify the white space between those.
So it will actually, how do I explain this, it basically calculates not only the X positions, yes.
Thank you. It not only calculates the X positions of each of those bars, when you do dot bandwidth, it tells you how wide the bar should be, the width should be, given the padding you aspecified.
This is the kind of stuff, you have to do a lot of math to figure it out on your own. D3 is doing the math behind you, if you have 100 pixels of space, three data points, I want to show them, not have them jammed into each other, I can do 100 divided by three and it gives me this odd fraction u if I wanted to do, say, 10 pixels of padding in between each one, it is not three bars of padding, you can see it is one, two, three, four bars of padding. Now it is 100 minus 40 divided by three.
And so, you know, then you have 60 and that means that each band is 20. You have to do a lot of math to get there, and D3 did that all of that for us.
And plus, when you calculate the X positions, you have to say, this is the 0th bar, plus the padding, but divide by with divide by two, because, wait, no no no.
With the rectangle, you are okay. Sorry. You have to be, like, this is the 0, the first bar, plus the padding, and the second bar, and plus two more paddings. It is not complex math, it is arithmetic, it is all really annoying.
And you have to hold so many things in your head, it is easy to skip a step, it looks wrong and you have to rewrite the code and as someone that has written code to manually place things like this
Yeah. And I realize, I didn't let's grab the D3 site, too. So D3JS.org. There's a million things you can do, and they are really powerful.
I want to do a shout out to DT who is in the chat, he is a super regular on live stream. Hi, DT!
Good to see a cross over, always nice. So I think, like, another way, too, is I typically tell people to learn things when it is time to learn them. There's an argument to be made for learning something just in case, or learning something in time. And a lot of FOMO and stress comes from trying to learn things just uncase. So I typically advise people to pay attention to what is out there, know what the options are. If you don't have a problem or something you are trying to solve, unless you are learning for fun, don't stress yourself out over it. You will learn it when it is time to learn it. So when it is time is always a gradient between the existing tool is more work to customize than it would to just build something from scratch. And, like, everybody's breaking point for that is different. If you are using something like pie charts or tableau right now, you have hundreds of charts, switching to D3 is a nightmare. You need to rewrite a bunch of stuff. If you are trying to rebuild data viz, you are exploring different tools and pie charts is not giving you what you want, use D3 and build it with the source as opposed to you should not have to bend tools to your will. If you go outside of what they offer, go to the next layer of abstraction, because you are an expert in breaking the tool, that is a weird expertise to have. A lot of WordPress developers became that, they were experts in breaking WordPress as oppose said to dropping to the next layer of abstraction and building the raw web things that would let them do what they wanted to do. Bet, yeah, don't don't learn things unless it is time to learn them, or fun to learn it. There are a lot of things to learn that is fun, that is the premise of the show. In my life, I never voluntarily learn something that is not part of my job. Otherwise I would spend my life, I have to learn everything. There is too much, it is a Firehose, it never stops. Especially with the web, that is a great piece of advise, and that helps answer Ira Driver's question, D3 instead of tableau, you have touched on that. It is in tableau and if it is working fine, I would not recommend switching. And, like Jason said, if there is some sort of a new visualization that you really cannot do with Tableau, I have heard things about Tableau, that is probably instead of trying to switch, I think that is probably a good opportunity to propose. I completely agree with you, yeah.
I am excited to do you want to go in here and clean it up? We have a build chart function. We could go and refactor this.
Yeah. Or we can delete the whole thing, you can walk me through how you would set up a new chart. Oh! I think that build chart function is great, because my understanding of what is happening is that it gets called every single time you have a data update. Right? Yes. So we do this is the part that felt the worst with. We are grabbing the chart selector, that is up here. You are so close!
And then we get the SVG inside of it, we delete it, and add a new one. This feels SO bad. I can promise you, that is not the way to do it. I think what we should do. Delete everything within build charts, after the scales. The scales are great.
Okay. So let me go into this, and it was Twilio, X to vote, we will open that up.
While you are doing that, we will ask you what you want. So it is going to be horizontal bars, and then I am guessing immediately something we can do is to put the numbers right beside the bar. That is great, and then we will put the label of yes or no. We can put the numbers on the right hand of the bars, and then we can put the ohhh.
Hey, thank you for the suv. Good to see you. And then we can put the yes or no on the left hand side of that bar. So 25 and 47 can go exactly where the bar ends on the right hand side, yeah. So we will start withdrawing the bar, and we will start with drawing the bar and the text on the right hand side. This is our function. I will start it locally so I can see our work, I will hope it works, 1st try. Let's see what happens. I have not looked at this code since Nathaniel and I hooray! We are in good shape here. Good. That makes I was scared that was going to break. Haha.
Does this one locally update correctly?
I will vote yes on sandwiches. If it works
Perfect. This will work, if you want to vote, you can continually mess with our data as we are coding here.
Okay Jason, the stretch going is going to be animation.
Ohhhh. Let's see what we can do, we have about 45 mines on the clock. Let's make this happen! I am going to hide this all together. We don't need it. I will pull this out. We will make this smaller. And let's make this one wider. And then we will be able to work a little bit here. Raphy okay!
Everything after the scales, please delete.
After the scales, so all of this.
If you want to comment it out for reference, that is fine, too. We are going to rewrite everything after that.
We will get it out of there. And then can I ask you can you tell me how the data you have, how is it structured? Is it an array of numbers?
We get the data back from, and then we map it to be a name and a value.
I love that people are voting, and you pass in the data. This is a really great place to start. So now that you have that, for my sanity, for the Y scale, I will use the I will ignore the poll. That is awesome. The dot domain, line 46, D3.range, let's do a map on the data and get an array of the names instead. Presumably, the name is yes or no. And you don't need to do a D3.range, the map will give aparray, and the domain and range always requires an array to be passed in.
And then whatout did above is perfect. So let's get started in drawing those bars.
So the very first thing, you have a pretty good idea, which is to create an SVG.
So do the const SVG is equal to, instead of creating, we well we will have a chart, a div, with ID chart, already created.
We will select that. So D3.select, and then use yeah. The hash
Was it hash ID? Just a class. So we can do the class. Yes. So what this does, it wraps the DOM element into a D3 selection, and it just has a bunch of D3 methods we can change. And we can create the SVG element, the dot append, and pass in the string AVG. So if you save that and update, you will see the SVG created in the chart div. How should I get it out of the way? I see it. Go on, let me see my stuff. I will pull this up.
I don't know why it is so hard to, like, so now what we want to do, we make a an escape. Now we want to be making a bar for each data object you have. So let's go and create a new variable, we will call it const bars. And that is equal to, and what we're going to do is we will create these within the SVG element we created, the SVG dots, this is where we will do a little bit of D3 magic, this is the we called this the enter update exit pattern, or fluxion, data binding, if you heard any of these terms with D3, this is the initial learning curve. Once you get over this part, everything else in the library actually will come much more naturally for you. And I also want to put in a disclaimer that with D3, you don't need this to be able to use the D3 library! It has been so modularized, it is like, the D3 library is this big old toolbox, you can pull out any module like a tool and use it separately, and it is fine. For the sake of understanding all of these examples that you are copying and pasting, this is a really good thing to understand. So I am going to tell you what to write first, and then I will explain it. So say dot select all, stream, we will create a rectangle. So rect and then dot data. And then pass in the data that you have.
It is, like, a
A parens, data. The variable data you have. Perfect. Dot join.
I will break these on to different lines to keep track of it.
Yes. I like yeah. Perfect. And then I will do a string, rect. And now if you open up, if you save and then if you open it up
Thanks for helping, prettier. C'mon!
So then within the SVG, you should be able to see two rectangles created.
Cool. So let me explain what happened. I like to think of so that, that whole line was collect all data, join. That is the black magic of D3. What that is saying, that select all line, it says select all the rectangles within SVG, which is so weird, conceptually, because there is no rectangles, what am I selecting? The answer is, you are selecting an empty fluxion. And then you are telling D3 that you have this array of data that you want to bind to this empty selection. And so D3 is, like, okay. So this is an array of data, and it has length, too, and thus and this has zero matching elements, and thus I need to make two new rectangle elements to match the data you just gave me. That makes sense. So anytime the select all and data, D3 basically is saying, I want both of those to match. So if you can imagine, if you have, say, two rectangle elements in the SVG, and there are five elements in the data array, then D3 is going to be, like, I need to make three new ones. And conversely, if you have five like rectangle elements in the SVG, there are only two data elements, then D3 is like, okay, I need to delete three. I need to exit three of the rectangle elements!
I would say, when you approach D3, approach it with an open mind.
[Cracking up]. There is not the same terminology as what you have known before.
So leave all of your assumptions at the door, come in, fresh faced, starry eyed. All right, I am ready. Haha. So there's a little bit of history behind the join, I don't think we have time to go through it. I will leave it there, and I explained all of the history in my workshop. And I will keep plugging it.
For real, this is we are getting a taste, if you want to go deeper, watch the stream, sign up for the workshop, it is going to be really taking all of this to a much more expertise level. You will leave being able to use it, as opposed to having an understanding of what we are going for today. Thank you. Now that we have the rectangles created, we are going to assign some attributes. Because as you can see, the rectangles are created, you are not seeing. By default, the element needs a width and height for it to show up. So we will do those, we will do the width first. W or width? Width. So the width is what you have done with the X, let me see the X scale. Go back up with the X scale. Scale, linear, you are seeing that with this. 0 to 350. Actually, that X scale should be a renamed width scale.
Because what you are saying is that you want, yeah. Perfect.
And because yeah. You are saying the okay.
So then pass in a function.
Do I get the D again?
Yes, a key thing to remember in D3 is anytime you are setting attributes or the dot data, or when you pass in the function, what that function receives is the individual data bound on the specific dom element. And so dot adder will move through every single DOM element in your selection and then, like, receive the bound data and then calculate one by one.
So in this case, we are going to use width scale. And width scale is a function.
So pass in D.value.
Okay. And that will give us back a, like, a value that is now used
Scaled from. to set that width.
Yes. Perfect. Dot adder, height. And then I need to rename Y to height scale? No. So Y is actually named correctly. And we are talking about Y in a little bit. And actually, this time around, we don't need a function because the height is going to be the same for every single bar. So you can think of it as pass in a function if that attribute is variable between each data, the DOM element. If it is constant, we don't need the function. So Y.bandwidth and then parens. This is, where the W is, for whatever reason, I don't understand lower case. Okay. And that remembers the scale band we are talking about, and how it calculates for you the width. And that's one of these. Yes, yeah yeah yeah. One of those somewhere in there. This is
Perfect. That's the bandwidth. You should see the bar overlapped on top of each other. Yes. Awesome. And now, they are being the mentions are correct, they are overlapping on top of each other. You don't need to set the X, the X and Y values, default to 0. All of these default to 0. And the X you don't need to change, because it is X is equal to 0 is that left hand side, that is perfect. You do need to change the Y value. So dot adder Y.
Oh, jeez. A tree. A tree!
Haha. And because that going to be different for a variable, for every bar, yes, perfect. And nowwy are going to use that Y scale.
Just like this? Yeah. And pass in, for this one, the name. And then that is what we used as, what you pass in the domain.
That is the key.
Yes, perfect. So now, if you save, you should see two bars. Yaaaasss.
Victory, that is amazing. High five, we nailed it.
We are done!
This is the fastest we have finished a stream!
This is cool. We took a bunch of copied and pasted code and broke it into the component parts and this makes sense to me. Before I was thinking, I think I know what this means if I change it, this will change. And now I get it, I feel like I can do this on my own. The other part that is confusing, how do we get it to auto update if the data is changing, does it automatically do that? Shout out to Ana! Oh, wait so we need to take that SVG outside of the build chart function. We only want to create one SVG. Like right here. So let's try it again. I will do another vote. Shout out to Ana in the chat. Thank you for joining! Sorry.
This is it updated. Let me do it again.
Nathaniel, if you are watching this, we made it so much harder than we need to. Beautiful. This is all we needed.
We are done!
This is really cool. We are done, that's what I am saying. This is the fastest we have ever done a stream. Remember when we needed four separate streams? I half expected this was going to be a six parter. Haha.
With the amount that we talk, that could happen. Very chatty, haha. And this is very complex, there's a lot going on, what the hell was that? No idea. We are just making stuff up. So we I don't know how or why any of that worked. Should I explain? Sure. So you know how in those functions, you pass in you get pass in, and we call it D, that's the data that is bound on the element? So what D3 passes you is three things, the data is bound in the index of the element. And the acchal DOM element, one element, don't quote me. I cannot remember the 3rd thing, it passes three things. And the reason why this works is because previously, in your code, the Y scale, remember how you had an array and it was 0 and 1? Oh, it was the array of you pass an array of indices. That is why we are using it here. That's why it works. Yeah. So this is wonderful. Instead of having to do all of this view box stuff, which works, but was confusing and it felt fragile, we are setting width here and setting it here, and it was like, eh, this feels clunky. Go ahead. I was going to also, so the width and height you are setting on the scales are separate, like, mentally separate that from the width and heighth you are setting on the SVG element. They aren't actually from an implementation perspective, related at all.
An SVG will scale. If you are from yeah. If I set the view box to be 100 by 100, and then the internal stuff is, you know, whatever scale, then it kind of fits, or it will
I have to admit, I never read view box. I read Sarah Dom's articles about it, I didn't retain it because I never use it. So please don't ask me questions. I don't know the view box. But if you update the dimensions on the SVG, you also have to manually update the width and heighth you are setting on the D3 scales. I pull it into a separate variable and I put it everywhere. And I am honestly, I am not sure about, sorry. I am not sure you you are doing that anyways. Haha. Let's move on. Now, do you want to give it a color? You can give it whatever color you want. And is that an attribute, like dot fill? Yeah. Although, you know what, actually, let's not do that just yet. Let's put the numbers on the right I think that is really fun. So we are going to change around the code we did, the bars code we did, a little bit. And what we're going to do, instead of creating a rectangle, we will create a group element. And you can guess what that does. And then now the width and heighth of all of that is not going to work on the G elements. So what you want to do is yeah. So start, like, a new leave the bars. And do bars dot append rectangle.
And that, if you save it, it should show up the same. If you look at the DOM structure, you have now, for every data element, you have created a group DOM element, you put the rectangle within it.
And now what you can do is then go back to your code.
And then you have another line that is, like, actually, you know how you have the dot add or Y? So we will take that out, or you can copy and paste.
Move it up here? Yes, the only thing about group elements, it doesn't have a Y attribute, instead you need to use transform to translate it around. So instead of Y, and SVG transforms are similar taCSS transforms, with
So like this? You can use the transform? Perfect. So what you can do, within that function, you still want that function, but now do, like, that back ticker or whatever, so you pass in a string and do a translate. Perfect.
Parentheses, and then zero, because you don't want to translate the X position at all. And then you can close all of that. You can use the closed paren, and then a back tick. Perfect.
That is what I needed. That should have not changed anything on the screen. So now what you can do is, and actually, for so now you can see that it is being translated, like, the group and I have a really fun exercise in a workshop that shows you, when you transform something, it actually moves the whole coordinate system around. And this is somewhere in CSS, and SVG, and anytime you are transform, you move the whole coordinate system. So now if you put X and Y positions on the tech tangle, it is relative to that transformed coordinate system. So now we will go and we will give the rectangle an attribute fill. Okay. And then yeah. And that way, you can see when we put in the text. Let's grab we will grab a color from the CSS so we can look at, up here,, and not have how about, I think there is a pink.
There's a pink. You are using steel blue before.
We copied and pasted that. Where are my variables? These are the variables, let's use this one here.
So we will drop that in there. We will see beautiful.
Now this is going to be the fun part. And you will love how easy this will be.
Bars that append
So down here again? Yeah. Bars that append StreamText. Treme text, sorry.
And dot text. And then pass in a function, and we want to use
Like that? Close. You can save that. You can see what happens. Yeah, let's do that. Do you see it? I do. The labels are here. We will do the same thing on the next line with the values. So we have to position these, they are crammed on each other. Yeah. That is very cool. We have vol us here. And this makes for something exciting. I can take this out, and we can say, like, is pizza a sandwich? Haha. And
And now you can vote! You have the ability to vote here. So let's let's make these positions, so they are a little more legible. I assume
I will start with the values. I see what you are doing.
It is the same as width.
I like to do overflow visible on the SVG element.
We can do that in the style sheet here.
Uh huh. So I will point out, that was probably not the most responsible thing to do, the SVG is wider than the DOM thinks it is. So for positioning or alignment, it gets weird. So we want to do actual sizing and stuff, and make sure the SVG is the right width, so it sizes properly. In the interest of not bogging down in CSS, we will continue.
Now the X positions are where you want it. The Y position is still a little bit off. So let's go and actually, here. Within bars, you can create a new variable called text or something. It is above both of those. Both of those append text. So 65, yeah. And then do bars.append text, sorry, bars.append G. Group. Yeah. And then, let's do a transform on that. Attribute, transform. Uh huh. And translate it by a path of the Y.bandwidth. You have to wrap it. Yeah, yeah. It is like this.
You will get used to it, if you do it a lot. That is what people say about me, I am slightly annoying, you will get used to it. I don't think that at all. So you can append to text. Now it is centered on
We did this. Cool. A ha.
You might notice that it is still not, like, vertically centered. So I don't know why this works, but I learned these from the D3 samples. So if we do this on the text, line 68, adder, and the attribute is DY. So the difference, Y, and then coma, and I do .35M, and then it just vertically centers. Waiting for DY. Huh, it does not look centered, does it? Is it moving? Maybe it can't be on the group element. That is odd. I never had, can you put it on the text element? That is an odd thing.
Here we go.
There we go. What an odd thing. I can do this on the group element, you can put the attributes you want the children to have. That is weird. But we just finished. And then you can like, you know, on the X you can, like, add a little bit of padding.
Yeah, for this one, we would do attribute, X, pass in 5. If you want to do the right line instead, again, I don't know why this is. But you can do attribute text anchor and instead of align, so instead of text align, it is text anchor. And instead of left center right, start, middle, end.
Okay. Which one should I put it on? If you want to, you put it on the no and yes. So the first one, and X minus 5 or something like that. Text anchor? Yeah. Is that right? Yeah. And we want end? Yeah. And then you can do the X is minus 5. Minus 5. If you want to do it that way. Perfect. So usually I would use a margin. So I will have that margin object so it fits nicely within the SVG. Or you can do that. That is fine.
We are hitting it with a hammer. The styling part, I would not do it that way, unless I am being hackie and lazy.
Would you do it in the, like, in the actual D3?
Yes, and the extra work would not be that much, as long as you take the width and height into a different variable, and that variable updates on window resize, the scales would update and the bars would automatically update also. So it is not that much more work, to make it responsive. Very cool. So did we want, do you want to we have about 6 ish minutes before we tear down. Do you want to do animation, or add anything else? Yeah!
Let's do it. We can do animation. Animations in D3 are transitions, because you are transitioning from one data state to the next. That is not the official definition, but how I think about it. But, okay, so let's do it this way. Let me think. So what we want to do on update is that the width of the bars would animate, and also the X position of the text, just the right hand value text, would change. I wonder if D3 transition will automatically, like, animate the text itself? Anyways. Let's not try to get there. So in build charts, maybe towards the top, create a variable. So constT, we will do a const T is equal to D3 transition. And then give it, so, D3 transitions have a default duration of 250MS. For us, we will set the duration to and we specify in milliseconds. So let's say, like, 500, just to show what you can do. And then now, go down to where we drew the rectangles. And how D3 transitions work, you do you put dot transition and pass in that, like, T variable we created. That is above and the attributes we want to animate. So here? So yeah. But we only want to animate that width. Not that the others will animate, they are constant. But yeah, take it above perfect. So what is happening there is we are telling D3 to animate the width to what we have in line 68. So you might know, you know that animations have to have a state A and a state B. Somewhere that it starts from animates from and animates to. So line 68 is animate to. And then you are like, where are we specifying the animate from. And animate from is, either you can specify it above line 67, the dot transition, or D3 will animate it from whatever it is currently in the DOM. So either, if you are you have just created it e it will animate from the SVG default. It will animate from the width of zero, which is pretty cool to see. I will see what happens. Look at it go.
That is all you need. And then you can put the dot transition T right above the X. Here. And then you can perfect. That is all you need. Everybody vote now, so you can see it change. It will animate for us in realtime. Can you put the dot text underneath, too. It will animate it from 0 to 52 or whatever? I highly doubt line 83. I doubt it will do that. It is kind of cool, a cool surprise if it does.
It did not.
With the (indiscernible), you can. My updates are not working for some reason. Really? It, like, it was working and then the property intertext of null. What? So something on my code. This is because we are updating the, where was it this part. This is this is just the old code that we are not using anymore.
Okay. So that, so now if we vote, we should see it update. Look at it go. Okay.
No. Hold on. Why is it doing that?
Why is the text doing that?
It looks like it is
Can you take the text.text above the I wonder if that is messing it up. D3 is, what are you trying to make me do? Let me try again. Why are you doing that? I wonder, hmm. Do you think it is getting rebuilt, like, because of the [sigh]. Can you try hmm.
So what happens if we take that out? And then we vote.
So it is going to
It pops here. It is losing, do you see how I did that? If I vote no, the yes column is weird? Yeah. And then when I vote yes, it fixes itself. So something is strange.
And then it asks if it is because of the group. Could it be, is the group the width of what is this?
Those are, woah.
It looks like it is
Woah. Multi creating stuff? Yeah, wait. This is so weird. Hold on. Go back to what the.
Oh. So it is creating a new rectangle each time instead of reusing. Do I need to key this somehow?
I just realized what is happening.
So this is why there's, like, an old way that the joins used to be okay.
I know what is happening. And it should a little bit annoying to explain. So let's do it first, and then I will try and explain. We have three minutes. Yes, okay. In const bars, the dot join, what we are going to do is instead of that string G, we will pass in a function. Okay. And then you receive in the function, call it enter, I think. No, call it G. Open curly parens. And then const enter is equal to D3 dot select, put in the G. Then do enter.append rect. Sorry. Append parens. I see what you mean.
And then enter dot append, let's call it text. And then we will give it an ID, dot outer ID name.
And then do the same thing again, and then give it class name.
Instead of ID, call it class.
And then enter dot append yes. The same thing again, this time, class value.
And then return enter.
And then outside of that, instead of dot append rect, select rect.
And then let's take out that const text all together.
And then we will take the Y.bandwidth, divide by two, and we will set it as the Y attribute on both of the texts.
So just take out the yeah.
And take out all of that.
Bars instead? Yeah. So bars, yeah yeah yeah. Very smart. Yes. That is the select, and the first one, you want to select, yeah. Perfect. And so the first one you want to select, dot name. And then the second one, you want to select dot value. Select, yeah. So select, not append. Select bars.
I have not remembered that correctly. So I will check something. So I don't think I remember that correctly.
So that is join is this new way of doing things, the new exit that I don't 100 percent remember. Let's see. So take out line 58. Okay. On line 57, call it enter. Okay. And then we will see if that works. No. Uh oh.
Ana asked if it is because of the group?
That might have been something else.
Yes. So let me explain what is happening. The reason why the previous one was not actually working is because the rectangles and text were getting appended and created in the DOM every time there was an update. And we only want the rectangles and text to be created when the group element is first created.
So that is what the enter means.
Online 58 to 62, that is what in D3, we call it an enter selection. When we were talking about, like, two, like, zero DOM elements, two data elements, we create two.
So we say create the rects and text when the new group element is being created.
So that is what is happening there.
And outside, because bars is, like, the selection of all of the bars, now we are saying, you know, select the rectangle, select the text, and then set all of those attributes on it.
So I am confused as to why there's a dot join order, build chart
Let's see. Maybe it is, like, something individual? It seems like it is a problem in that enter, in the dot join.
Uh huh. So we do wonder.
It does not like enter for some reason.
After the enter, try, I will message you something in chat.
Try putting it in the curly braces in line 63.
Yes, line 63.
This is territory I did not want to get into. Right after the curly braces, put in the coma, and update and update and exit.
Something about this. Do we need to put empty groups in it?
Unfortunately, we are all the way out of time.
What we need to do is roll back, I will roll back before transitions, that was working.
That was not working correctly.
I will take the transitions out. No, even before, the dot join is, you are not supposed to make it like that. Oh, no. That is what I mean. So I taught everybody the wrong thing.
Hahaha. Well, so what we're going to have to do, then, is if we want to maybe we can patch this and clean it up. Thank you for the sub. So we can fix that and we will patch it in the the repo. Check the repo, we will do an update, I will add an explanation, why and link it in the show note. Thank you for hanging out with us. And we need to pick the winners. I will close the entries, we have 47 people entered. We will pick 5 winners. I will pick. And we will do two. Three. Four. And five. The winners are the dislexiac developer, Adrian engine, tent man TV, (indiscernible) codes, and Divan Dinidi. You won a six month front end masters membership. Send me a whisper or DM on Twitter. So probably easiest to DM me on Twitter. I will get you a code that is for you. Where should people go to follow you for more? I am distracted by a sense of failure. It is not a failure, we are all learning and we are going to get it patched up, there will be notes. We need to wrap up, because we have to keep it to 90 minutes. Hello, please find me at Twitter SXYWU, my portfolio website is the same thing, dot com. May Instagram, trying to revive my Instagram, is the same handle. And that is where I will put in my byte sized charts in October, hopefully 20 of them. I will stream that process on twitch, the same handle. All of my streams are archived at my YouTube. Excellent. This is super fun, thank you so much for hanging out. One more shout out to our sponsors, we have Netlify, Fauna, Sanity, Auth0, making it possible to get live captioning from White Coat Captioning. Thank you for hanging out with us, check the schedule, incredible stuff coming up on the show. Later this week, Eve Porchello is talking about GraphQL and check out the rest of the schedule, so much great stuff coming up! Please take a look and we will see you next time, stay tuned, chat, thank you for hanging out with us. Lindsay, thank you for doing the captioning today, we will see you next time!
Thank you for having me, bye bye!
Live captioning by Lindsay @stoker_lindsay at White Coat Captioning @whitecoatcapxg