Introduction to D3.js

Creating DOM Elements from Data Solution

Shirley Wu

Shirley Wu

Data Sketches
Introduction to D3.js

Check out a free preview of the full Introduction to D3.js course

The "Creating DOM Elements from Data Solution" Lesson is part of the full, Introduction to D3.js course featured in this preview video. Here's what you'd learn in this lesson:

Shirley live codes the solution to the previous exercise after answering questions about the type of data passed into the DOM within the array, and about the width and height that are set up when creating an SVG.


Transcript from the "Creating DOM Elements from Data Solution" Lesson

>> Let's do this exercise together. Hopefully you're able to make some headway. But before we get started on this exercise, I wanted to address two questions, one from the classroom and one from chat. And the first question was actually about this rule about the data passing must be an array.

So the question was, within the array does it matter what's in the array, can it be text or? And so the answer is as long as it's an array, what's inside could be anything you want. It could be objects, it could be text, it could be numbers. As long as it's an array that's wrapping around it, and then what's going to happen is that every element in the array is going to get bound to your DOM element.

So as long as that's what you intend to get bound to your DOM element, it should all work fine. And it just occurred to me an interesting scenario of, what if you have an array and some of them are objects and some of them are text, I think d3 still should work.

It should just bind all of that no problem. I wanna know a use case for that though if you have different types of data structures in there, I don't know but, it should be. I'm sure there's edge cases but from my experience, as long as it's an array, what's inside doesn't matter.

As long as what's inside is what you intend to get bound to that DOM element. So that was the first question. The second question was about the width and the height that we're setting on our SVG. So in the previous example, we kind of hard coded the width and height setting.

We hard coded it to like 250 pixels wide and 100 pixels tall. And the question was about how to dynamically, if we want to make it responsive how do we deal with that. And so I know that Mark had answered and that we should have it. So the first step is if we're trying to make it responsive on window resize, then what we want to do is in JavaScript bind an event listener to the window resize event.

And then we want to be updating our, usually we'll have when we're creating data visualization and we want the container to be responsive. We'll have a variable width, or we'll have a width defined and then we'll have a height variable defined. And then within that kind of like resize callback we'll just update the width and height.

And then we'll also set that variable width and height on to the SVG. And then, depending on what you're trying to do within the SVG, how you're trying to position everything, then we can use these width and height variables to, we can kind of rerun the position calculation every time a resize happens.

So I'm just going to kind of show you really quickly before we get on with the rest of the exercise code, kind of that function I mentioned earlier about calculate a grid position. So that's a kind of utility function I created. And what that function is doing is taking the index of our element.

And we're just saying that depending on, and actually what we're also doing is and depending on, I've hard coded in how wide I want each of our petal paths to be. And then we're saying depending on the width of our container, I want to divide that by the width of our SVG element, or sorry, the width of our path element.

And that's how many of the petals that we'll have per row. So in this case, it seems that our container width divided by our petal width is going to be seven. And then given that per row number, I go and calculate the position for each petal. And that is the x position is basically the index modular perRow and then multiplied by the width of the path.

And the y position is the index divided by per row. So it's kind of like which row it's on and times the size of the path. And that's how we're kind of doing the xy positioning. And that's how we can also potentially make our SVG container and also the position of everything within that SVG dynamic based and responsive based on window size.

Yeah, so having said that, let's go and and create all of these petals together. So what we're gonna do is the very first thing is we're going to go and grab or select the SVG. So, and let's then create a path for each movie. So select all the path right now that should return an empty selection.

We're going to bind the movies data. And if you go up and take a look, the movies is an array of objects. And then we're going to say, insert a path element for each movie in our movies array. And so if you go and inspect this SVG and if you go and kind of open it up.

Can never, all right, if you open it up, then you can see that a lot of path elements, specifically 135 of them, have been created. And then what we want to do is now that we have a path for each movie. We want to basically do the same thing that we did in the last exercise, which is we're going to use the data that's been bound up and set attributes with them.

So let's the first one that we can set is our define attribute on our path. And so we have our lookup is I think called a path object. And so what we're gonna do is we're going to do path object and we're going to, sorry, that shouldn't be a string, yes, okay.

So and we're being passed in the data that's bound. And in that bound data, we have so this is our bound data. In here we have something called rated and that's our PG rating. And that's going to determine our define attribute. And so let's go back in and do that.

And so that's path object and we're going to use d.rated. So if we do that, if we did that correctly, we should be seeing some paths. But we are not, so let's debug that. That's because I was silly. So we need to be able to say that the attribute we're setting is the d attribute, and then we're passing in the data, calling the data that's been bound d, passing that in.

And then using that to get the d string that we want, that's there we go. So there's an all of these petals are being rendered up here, overlapping each other. And obviously, that's not what we want, we want them in a nice grid. So we're going to use an attribute called transform.

And within transform, we're going to use translate. So again, let's pass in a function and that function we want both the data that's been bound on that DOM element and the index of that DOM element or that path element. And so in this case, we're going to use index and we're going to write a string and translate.

And in here, we are going to call calculateGridPosition. It's the function that I had shown earlier. And let's pass in the index for each of these path elements. And this right here will evaluate to an array of x and y. And so if we pass that in to those translate string, it should give us back a string that looks like translate xy.

So this is what we ultimately want. And if we go and evaluate that, there we go. We have all of our 135 petals in a grid.
>> People in the chat room are asking if there's a way to fork it and share the code or?
>> Yes, so I believe if you can see, that'd be really cool to see everybody's notebooks.

So you should be able to if you go up to the top right next to maybe you'll see publish. But right up here, you'll see these three dots and you can click on fork. And as long as you're signed in, and you can sign in with your GitHub account, then you should be able to fork it and have your own notebook.

The only thing that I'm not 100% sure about is if the, currently I'm saving your petal paths in local storage. I'm not 100% sure if that will persist if you fork. If it does not persist, what you can do is again go to the workshop utility notebook down here and then update I think the path.

So update the, let's see, Yes, update the petal paths and with your custom petal. So, that should be once you've done that, then it should persist through the rest of your notebooks. But hopefully it will just work. Hopefully the local storage will just work. Okay, so now that we've translated our petals, and we've also defined our string for what each petal should look like.

Let's go ahead and color that again. And we'll do this quickly together again just so repetition I think helps. But if you don't want to, you can just copy it over from the previous notebook. So let's go and use the color object and use the first genre as lookup or if that doesn't exist, then we can just use the other color and color object.

Same thing for stroke, so I'm just gonna copy that over. And there we go. We have all of our paths colored now. Then let's just go in and put in a fill opacity for fun. And we'll put in a stroke width, you can do whatever stroke width you want.

I'm gonna do 2 and there we go. So this is our, now we have a petal for each of the 135 movies.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now