Add Axes, Titles, and Legends to Svelte Beeswarm Visualization

Adding axes, titles, and a legend to our beeswarm chart

Project Source Code

Get the project source code below, and follow along with the lesson material.

Download Project Source Code

To set up the project on your local machine, please follow the directions provided in the README.md file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.

This lesson preview is part of the Better Data Visualizations with Svelte course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.

This video is available to students only
Unlock This Course

Get unlimited access to Better Data Visualizations with Svelte, plus 70+ \newline books, guides and courses with the \newline Pro subscription.

Thumbnail for the \newline course Better Data Visualizations with Svelte
  • [00:00 - 00:27] Hey y'all, in this lesson we're going to tackle our favorite part of charting, which is peripheral elements. You might remember from the last lesson that peripheral elements can be a bit tricky to work with, a bit hard, but we're going to knock it out in this lesson to build an axis on two dimensions, the x-axis, which is going to represent happiness scores, right, within a range, and then the y-axis, which will give labels for each of these continents.

    [00:28 - 00:40] You know, that's the current grouping variable, but it's very unclear to the user that that's how these countries are organized, at least for now. So these bits of peripheral elements, axes and axes labels are going to make the chart a lot clearer.

    [00:41 - 00:46] So let's go ahead and get started. The first thing we're going to want to do is create an x-axis.

    [00:47 - 00:57] And in order to keep our code cleanly separated between distinct purposes, we 're going to place this axis in its own component. Remember that components are just like app.spelt.

    [00:58 - 01:08] They're just big, spelled files or hopefully small, spelled files, but they have a discrete purpose, right? They're also reusable, but in our case, we're not really benefit from the reus ability.

    [01:09 - 01:21] As much as we are just having axis specific code in its own file, right? So what we're going to want to do is create a new file called axis x.spelt.

    [01:22 - 01:34] That's going to live in the components folder. And go ahead and delete the example file, if you'd like, and then create a new component by right clicking the components folder and clicking new file.

    [01:35 - 01:41] Here you'll then type axis x.spelt. I'm going to capitalize the x with this title case because I think it looks better.

    [01:42 - 02:07] By the way, in case you were curious, the way that I dynamically toggled the visibility of this sidebar is with command B. That will open or close the sidebar on the left, the explorer as it's called, or you can manually drag it to close as well. So now that we have an axis x component, let's go ahead and import it in app.sp elt and render it within our SVG.

    [02:08 - 02:23] So the way that we import, you might remember, is by importing the name of the component that we want to call it within our application, and then from the path where it currently lives. If you have that spelt editor extension installed, you might just be able to click enter.

    [02:24 - 02:27] As you can see right here, I have this kind of auto complete. I click enter.

    [02:28 - 02:37] It will find where that lives relative to my current path and import it. Personally, I like to use this alias, which is the dollar sign that we've already set up.

    [02:38 - 02:56] And the reason for this is that anywhere that I import axis x, if I ever changed a path of app, it would always look within the components folder, app base. So I prefer this alias, but you can definitely do paths like, like so if you ever need to, I would just recommend using an alias if and when it makes sense.

    [02:57 - 03:06] So now that we have access x, you're going to see up first the compiler is complaining or spelt is complaining because access x is not used anywhere. Let's go ahead and render it.

    [03:07 - 03:20] The question is where do we want to render it? And the answer is we want it within our inner chart because we want it to reflect the margin left and margin top that we've provided, but we don't want it on top of our circles, right?

    [03:21 - 03:27] We don't want any grid lines to overlap with circles and cut them off. And so we actually want it before this each block.

    [03:28 - 03:46] And the reason for that is because SVG, which is what we're writing here, renders in the order in which it is written. So if I put a line here, or if I put a rectangle here, and let's just say it was, you know, it was zero, zero, and it had a fill of black.

    [03:47 - 03:50] I'm just going to illustrate something. This is all behind the circles, right?

    [03:51 - 04:04] But if I move this rectangle under the each block and click save, it would cover every circle. And the reason I'm doing this, of course, you don't write this code, I'm just illustrating that SVG renders in the order that it is written.

    [04:05 - 04:13] So if we want our x axis to render below our circles rather than on top, we want to put it here. So I'm going to do axis X, and I'm going to close that.

    [04:14 - 04:22] Obviously by default, nothing is going to appear because axis X is a blank file . Question is, what do we want our axis X to do?

    [04:23 - 04:25] Where do we want it to live? What do we want it to present?

    [04:26 - 04:39] We want our axis X to present context around the x axis. And therefore, we want it to live at the bottom of our chart and provide reference lines for each of these variable numbers.

    [04:40 - 04:52] And the numbers that we want to render are given from our x scale. So with that kind of high level explanation, we can actually get a feel for the props that we need to pass down from app.s felt into axis X.

    [04:53 - 05:05] The first thing that we need to pass is X scale, which is equivalent to X scale . The second thing we need to pass is height, which is going to be equal to inner height, because remember we are within the translated chart.

    [05:06 - 05:11] So we want to reflect those margins. And then we also want the width for an axis label.

    [05:12 - 05:23] So I'll pass width equal to inner width. Now if I hit save, you're going to now go to axis X dot felt and accept these props inside the script tag.

    [05:24 - 05:34] Remember that the syntax for this is export let and then whatever prop we want to accept. Remember at let X scale export let width export let height.

    [05:35 - 05:46] So now to verify that we have these three, let's go ahead and console log these three variables. We see we have an X scale, which is a function, a height and a width, which means we're doing something correct.

    [05:47 - 06:01] If I wanted to make sure that this was live updating, I could prefix it with this dollar label and then resize my window and you'll see that width consistently updates. Okay, we have successfully imported the given variables within axis X dots felt .

    [06:02 - 06:04] Now what do we want to do within this file? We don't want to console log things.

    [06:05 - 06:16] We want to render items. And so you might remember that the way that we render, usually within an axis is with this each block, where we want to render a series of ticks as text elements.

    [06:17 - 06:30] But what are the series of ticks? The answer to that, as we did in our last module, is going to be derived from the dot ticks method that currently exists within X scale.

    [06:31 - 06:37] So here you can actually go into X scale and look at all of these methods within. And one of them is in fact ticks.

    [06:38 - 06:47] So if I wanted to see if I wanted to console log X scale dot ticks of four and then save, you would see we return two, four, six and eight. That looks perfect.

    [06:48 - 07:07] Those are exactly the elements that we want to render on our X axis. So rather than console logging it, let's go ahead and call this variable ticks and we'll make it equal to X scale ticks for now we're pre fixing it with this dollar label because if X scale changes, we want to update the ticks as needed.

    [07:08 - 07:25] Now that we have the proper ticks ready to go, remember that this is going to be equal to two, four, six and eight for now, let's go ahead and render it. First we'll go ahead and place the entire axis in its own G element, this own group, and we'll call it axis with a class of X.

    [07:26 - 07:30] Then within the axis, we need an each block. Now what are we rendering?

    [07:31 - 07:36] We're rendering each ticks. So each tick as tick.

    [07:37 - 07:51] Remember that the syntax for this is each and then an array for our case two, four, six, eight. And what we want to call the iterated elements within that array for us, we're going to call each ticks tick.

    [07:52 - 07:55] Then we want to group each tick in its own group. Okay.

    [07:56 - 08:07] And the reason for this is because we want both a text element and a lot. And so what we're going to want to do here is call this tick just so that we kind of know internally what we are rendering.

    [08:08 - 08:12] And then let's go ahead and transform. You know, the auto complete is getting it right in this case.

    [08:13 - 08:27] Let's go ahead and transform, translate it equal to X scale tick on the horizontal axis and zero on the vertical axis. Now before I complete what's inside here, let's describe what we're doing.

    [08:28 - 08:35] We know that we want to four, six and eight, not to be rendered at two, four, six, and eight pixels, right? The very, very left side of the screen.

    [08:36 - 08:41] We definitely don't want that. We want them distributed equally across the actual axis.

    [08:42 - 08:50] So the way that we're going to move these tick labels to their actual position on the canvas is by rescaling them, right? Two, four, six and eight are raw values.

    [08:51 - 09:01] We need to pass them into X scale to return their points on the axis, their points on the canvas. So that's what this translation is doing.

    [09:02 - 09:14] The reason that we're doing it in this larger G element is that we don't have to repeat this bit of code for the X element of both our text, which is going to be the label and the tick line. You'll see what I'm talking about in just a second.

    [09:15 - 09:30] So for now, now that we've translated this, let's go ahead and add text and let 's give it an X of zero and a Y of height we could do. And then let's render the text element right here and see what it looks like.

    [09:31 - 09:38] The first thing that you're going to see is that you need to end your each block. And then what you'll notice then after is we have two, four, six and eight.

    [09:39 - 09:59] And notice that the X positions of these are zero, but the translation is pushing them to their proper point where this is eight and it represents a circle, which also has, you know, the same CX position, roughly the end point of our X scale range. So now that we have these text elements, we can start to see our chart coming to life.

    [10:00 - 10:04] Let's also add a tick line. And remember the syntax for a line is quite simple.

    [10:05 - 10:11] It has an X one and X two, a Y one and a Y two. In our case, we want X two to be zero.

    [10:12 - 10:16] So we want X one to be zero. We also want X two to be zero.

    [10:17 - 10:27] We want Y one to be zero and we want Y two to be height. Now the reason that we are spanning the entire chart, let's go ahead and see what this looks like.

    [10:28 - 10:32] And then obviously a line needs a stroke. So let's add a stroke of black.

    [10:33 - 10:46] Now we see these grid lines span the entire chart, which is basically what we wanted to do is provide these reference lines, right? These grid lines that provide context for the entire vertical dimension of our visualization.

    [10:47 - 10:49] Now personally, I don't love this black color. I think it's a bit ugly.

    [10:50 - 11:00] So you could replace it with a light gray. I know personally that this color is going to look quite nice, but you could also play around with different RGB values or whatever else.

    [11:01 - 11:03] But I like this color a lot. It's a very faint gray.

    [11:04 - 11:09] The other thing I notice is that these text elements are kind of hugging the line. I don't love that.

    [11:10 - 11:18] So I'm going to push them to the right, maybe three pixels. And if you think it needs more space, you could change this to six or whatever else.

    [11:19 - 11:20] Maybe I'll leave it there. That sounds good.

    [11:21 - 11:24] So what are we doing here, right? We are creating an entire group.

    [11:25 - 11:30] And the group itself has no position. It doesn't have an X and a Y, but it can be transformed.

    [11:31 - 11:40] And that's why we're passing this translation, which moves the entire tick, right? Both the text label and the line, it moves at all 70 pixels to the right, right ?

    [11:41 - 11:46] That's what this translation is doing. It moves this entire group, 210 pixels to the right.

    [11:47 - 11:50] And then within that, we can provide smaller X values. We don't have to do complex math.

    [11:51 - 11:58] We can just move the six pixels to the right of this translated point. And the line is just all zeros other than the height, right?

    [11:59 - 12:08] So that's why we try to use translations on group elements whenever we can, because it makes for a bit cleaner code, right? So we have a pretty good X axis.

    [12:09 - 12:21] Things are looking pretty nice. Of course, if you personally want to change some styles, you're definitely empowered to, you know, change the fill of your text to be gray or change, you know, add a stroke behind it or whatever else.

    [12:22 - 12:29] But I personally am content with these styles. So let's go ahead and finish up our X axis by adding a title.

    [12:30 - 12:40] So we currently have each of these four labels, but we don't know what these numbers are representing. And so we want to add a simple title, which basically shows what these numbers are referencing.

    [12:41 - 12:49] And the way that we're going to do that is by adding a text element within our group. So let's do it at the bottom here.

    [12:50 - 12:53] And let's call it text. And then what do we let's add a class first so that we know what we're referencing.

    [12:54 - 12:57] And what do we want to render here? We want to render something at the end of our chart.

    [12:58 - 13:03] So let's give it an X of width. And then vertically, we want to be at the bottom of our chart.

    [13:04 - 13:09] So let's give it a Y of height. And then let's just go ahead and close this and give our title.

    [13:10 - 13:15] This isn't going to work for now. We're going to need to fix some things, but this will kind of visualize what we need to fix.

    [13:16 - 13:26] So let's do happiness out of 10. And then I'm going to do the ampersand R-A-R-R semicolon, which represents the right arrow in HTML, Unicode.

    [13:27 - 13:34] It's a character entity. Now if I save this-- oh, man, if I save this, and go over here, what do we see?

    [13:35 - 13:43] We see X-axis has a series of ticks. And we also see that this is falling off the side of our screen.

    [13:44 - 13:50] So you can't even see it. And the way that we want to handle this are some of the SVG properties that we 've already went over.

    [13:51 - 14:04] Most namely, you might remember, text anchor, which basically represents the horizontal alignment of a text element. So we're going to give it a text anchor of end so that instead of falling off the right side of our screen, that is where the text element ends.

    [14:05 - 14:17] If I go ahead and save this, you'll now see that we actually see our text element because it ends at the end of our chart rather than begins at the end of our chart. Finally, you'll notice that it's overlapping with this eight.

    [14:18 - 14:26] It's overlapping with all of our text labels. We're going to use a final property for vertical alignment, known as dominant baseline, which could be auto.

    [14:27 - 14:31] It could be a start. Or in our case, we want it to go below its current point.

    [14:32 - 14:38] So hanging off of the bottom of the bounding box. And for that, we're going to do dominant baseline hanging.

    [14:39 - 14:45] Now you might notice that it's still a little bit close, a little bit too snug. You've got a DUI of four, five, or six.

    [14:46 - 14:48] I'm going to do four. And I think this looks pretty good.

    [14:49 - 14:59] Obviously, you could play around with this number as much as you wanted, but at a certain point, once it starts to fall off the chart, as you see here, you would need to update your margin. So here we have a margin bottom of 20.

    [15:00 - 15:08] This would need to be 30 if we wanted to add more room for our happiness label. So I'll go ahead and add 20 back and change this DUI back to four because I think this looks good enough.

    [15:09 - 15:21] But know that you can play around with these numbers as much as you want. If something is falling off the side of the screen or off the bottom of the chart, you might need to adjust your margin numbers and your alignment of your text element.

    [15:22 - 15:26] So we've basically completed an X-axis. And I think this looks pretty good.

    [15:27 - 15:33] Thanks to this simple one liner where this has a dollar label, this X-axis is also going to be responsive. It's dynamic, right?

    [15:34 - 15:39] So we've completed our X-axis in about 15 minutes. So I think that's great.

    [15:40 - 15:48] Let's now move on to a Y-axis. And we're going to follow a very similar pattern to our X-axis where the first thing we're going to want to do is import it.

    [15:49 - 15:56] Of course, for now, this is going to scream at me because axis Y does not exist . It might scream at me.

    [15:57 - 15:59] Yeah. As you see, the entire app might break.

    [16:00 - 16:05] So let's go ahead and create a new component and call it axis. See if I'm capable of doing this.

    [16:06 - 16:14] Now, what do we want in axis Y dots felt? Now you can see this recreates because axis Y does exist.

    [16:15 - 16:24] Well, the only thing we actually need in axis Y dots felt for now as a starting point is going to be Y scale. So let's go ahead and export let Y scale.

    [16:25 - 16:35] And then you might remember that we need to pass it as a prop in our markup in app dots felt. We're passing Y scale as a property into the axis Y component.

    [16:36 - 16:48] We can then accept it with this code and verify that it exists by writing console log of Y scale. See that we do in fact have the function with multiple methods with it.

    [16:49 - 16:56] Here, you might notice that we can't use dot ticks. In fact, it doesn't even exist as a method within our Y scale.

    [16:57 - 17:13] Now, the reason for this from a technical perspective is because Y scale is not a linear scale. Remember that X scale was created with scale linear, but Y scale was created with scale band, which is used for ordinal variables for categorical variables, right?

    [17:14 - 17:25] So we can't do a dot ticks, which is meant to, you know, evenly divide a range by a number of intervals for something that's categorical. So we can't use Y scale ticks.

    [17:26 - 17:27] This will not work. Okay.

    [17:28 - 17:36] Next, that need to do is get the domain, the raw values of the domain. So we'll do console log Y scale of domain.

    [17:37 - 17:44] Now, if I refresh this, you'll see Africa, Asia, South America, North America, Europe, and Oceania. So this works, right?

    [17:45 - 17:54] And the reason this is all we need to do is because think about it, right? All we need to do is render the six continents that we have in our data in their equivalent Y positions.

    [17:55 - 18:10] You know, the domain method is just another method on Y scale, which remember has a whole lot of things that you might be able to access if they're relevant. I could also get just for example, you don't need to write this, but I could get the range of Y scale, which is 380 to zero, right?

    [18:11 - 18:15] So these are just accessible on our existing Y scale function. Okay.

    [18:16 - 18:20] So we know that we're going to want to use Y scale domain. And we want those to be our ticks.

    [18:21 - 18:30] So let's say ticks equal Y scale domain. Now now that we have our six continents, right, we just want to render those in an each block yet again.

    [18:31 - 18:44] So let's first put them in a G wrapper, just like we did with our X axis. And then let's open and close our each block, let's say each ticks as tick and then close that block.

    [18:45 - 18:48] All right. So this is going to work, but there's nothing inside each block for now.

    [18:49 - 18:56] So what do we want? We want to treat it exactly as we did with our X axis by opening up a new group and calling it tick.

    [18:57 - 19:12] And then we could transform, translate within here, but the only element we're actually going to have within this G, G class, just G tag is going to be a text element. So let's just open and close the G tag and let the position be on the text element itself.

    [19:13 - 19:24] Okay. So let's open a new text element, give it a Y of Y scale of tick, okay, and an X of zero.

    [19:25 - 19:36] And let's add the tick element within like so. Now you see all six of the continents in our data set nicely presented on the left side of our screen.

    [19:37 - 19:45] So what's happening here, Y scale of tick? Well, remember that each of the tick elements is simply the text Africa, Asia, South America, North America, Europe, Oceano.

    [19:46 - 19:51] And remember that in our Y scale, that's exactly the input that we're expecting from our domain, right? These six continents.

    [19:52 - 20:08] So by passing Y scale of one of these values, we're returning its equivalent position within the Y scale range. So here, this would be 298 for the last element in our domain on line 82.

    [20:09 - 20:13] So we have all of these text elements. And honestly, I think this is looking pretty darn good.

    [20:14 - 20:21] These text elements look good, and I think they're ready to go. So let's add some slight styling to our axes globally.

    [20:22 - 20:40] And what we're going to want to do is go into our app.s felt and apply some rules to all of these access elements, all at once, okay? And the reason we're going to do it in our app.s felt is because we want to apply some global styles, rather than having to repeat the same bit of code in a style tag here.

    [20:41 - 20:48] And in a style tag in access, X dot felt. So let's open a new style tag in app.s felt.

    [20:49 - 21:02] And what we're going to want to do is prefix this declaration with global so that these rules apply everywhere in our application. Let's go ahead and add a declaration for tick text.

    [21:03 - 21:13] So this is saying anything that has a class of tick and then within that tick is a text element, right? So this would apply here, for example, because line nine has a class of ticks.

    [21:14 - 21:26] So the text element inside would assume the rules that we're about to apply. Let's also apply it to our access title, which is its own class that only exists within access X. Now what do we want to do?

    [21:27 - 21:32] I'm going to make the text smaller. I'm going to make the font weight a little bit lighter.

    [21:33 - 21:36] So I'll say 400. I'm going to make the fill this light gray.

    [21:37 - 21:43] I'm going to make it HLS H.S.L.A. stands for Hue, Saturation, Lightness, Alpha.

    [21:44 - 21:50] These are things that you'll come across as you do more and more visualization design coding. And then I'm going to make it so they're not selectable.

    [21:51 - 21:53] Right now I can select these text elements. I don't really like that.

    [21:54 - 21:57] I'm going to do user select none. So go ahead and save this.

    [21:58 - 22:03] And already start to see all of these look much, much nicer. I think they look pretty nice.

    [22:04 - 22:16] Maybe you could change some styles as you saw fit so I could maybe create a new class for global access title. And maybe I want to make this a little bit bigger because I think it's a title.

    [22:17 - 22:19] It should be bigger. So I make it 14 pixels instead.

    [22:20 - 22:27] And then yeah, from here play around with whatever elements you think need a little bit of work. Personally, I think that this title right here should be pushed down a little bit further.

    [22:28 - 22:34] So I'm going to push it down, see if it fits, see these P's are getting cut off ever so slightly. So I'm going to go back into app dots fell.

    [22:35 - 22:39] I'm going to apply a little bit more margin bottom. It's 25 instead of 20 and voila.

    [22:40 - 22:43] I'm really happy with this chart. I think it's looking pretty great.

    [22:44 - 22:51] And our axes are basically completed. So for our final step of peripheral elements, so go ahead and add a chart title .

    [22:52 - 22:55] Like I get that you're showing happiness. I get that there are continents on the y-axis.

    [22:56 - 23:00] But tell me the insight, right? I love it whenever chart titles tell us what it haunts us to see.

    [23:01 - 23:08] So let's add a chart title, which is very simple because it's just regular HTML . And we're going to do this before our entire chart container.

    [23:09 - 23:21] We're going to add a new H1, which remember stands for heading one. Let's just give it some title you could call it happiness by country or if you want to be more like, you know, cool with your chart title.

    [23:22 - 23:26] You could do like the happiest countries in the world. Let's go ahead and save that.

    [23:27 - 23:34] You now see a chart title, but it's not very well styled. So let's finalize our chart title by adding a new H1 element, right?

    [23:35 - 23:37] That's a header and adding some styles. First, we'll make it bigger.

    [23:38 - 23:44] I'm going to do 1.35 rem. Or if you want to be consistent with your pixel notation as we have throughout, you can maybe do 20 pixels.

    [23:45 - 23:49] Again, you're going to play around with these numbers, right? You're going to do whatever works best.

    [23:50 - 23:59] Maybe you could do a margin of six pixels below. So this would be zero pixels top, zero pixels, right?

    [24:00 - 24:04] Six pixels below bottom and zero pixels left. That's the margin.

    [24:05 - 24:11] You could also literally just write margin bottom of six pixels, whichever one you prefer here. Then we're going to make it bolder.

    [24:12 - 24:15] We're going to do a font weight of 600. And let's go ahead and center it as well.

    [24:16 - 24:24] So now we have something that looks pretty good. Maybe personally from here, I might make the font size slightly bigger, 22.

    [24:25 - 24:35] And I might make this title case instead of sentence case. Voila.

    [24:36 - 24:40] I'm pretty happy with that. So our title is now finished.

    [24:41 - 24:46] And the last thing we need to do in this lesson is add a legend. Granted, this is kind of an in-between step.

    [24:47 - 24:56] I think we've made really good progress. So feel free to take a coffee break before we spend 10 minutes on our final step, which is going to be the legend itself.

    [24:57 - 25:03] And so once you have that break, let's go ahead and get started with the legend . And let's describe what we want to do, right?

    [25:04 - 25:11] We have these series of colors. We have pink, orange, yellow, green, and teal.

    [25:12 - 25:18] And this other color that's maybe like a wheat, I don't know, khaki. I'm not a color expert.

    [25:19 - 25:28] But anyway, we have all these colors. And what a legend can do is basically offer context for which countries these circles are representing vis-a-vis their color.

    [25:29 - 25:44] Of course, this is going to be double encoded with our y-axis because we have these continents listed already. But what the legend will also offer is this ability for interaction because you can hover over a specific color, a legend item, and it can create interactions within the chart.

    [25:45 - 25:53] So even if it is double encoding, even if it is redundant, I still think it's a good exercise to create our legend. So let's go ahead and follow this pattern.

    [25:54 - 26:01] We're going to import legend from the components folder and it has a title of legend.spelt. Of course, it doesn't exist yet.

    [26:02 - 26:10] So we'll go into our components file and we'll create legend.spelt. Now what do we want to render within our legend?

    [26:11 - 26:22] Most obviously, we want each of the continent names and their respective colors . Now the cool thing here is that we can render all of this information using only one scale and that is the color scale.

    [26:23 - 26:29] Let's go ahead and render legend and pass in the color scale. And then save this.

    [26:30 - 26:40] In legend.spelt, we need to accept this new prop. So let's export let color scale and then let's verify that this works by console.logging color scale.

    [26:41 - 26:48] Now here if we go back to our console, you'll see that x scale might exist if I didn't break it. Here we go.

    [26:49 - 26:56] Color scale exists right here. And just to be clear, I'm going to go ahead and delete this ticks console logs so that our console was cleared up.

    [26:57 - 27:00] Great. Now back in legend, color scale exists.

    [27:01 - 27:08] Now what are the methods that exist within a color scale? We have copy, domain, length, name, prototype, range and unknown.

    [27:09 - 27:20] The two things that we're going to want to focus on are color scales domain and color scale range. And like I said, we can get all the information we need from only these two bits of code.

    [27:21 - 27:31] So you'll notice the top array, because this is the first thing in our console log, is the domain six continents listed in an array. The range are the six colors listed within the range.

    [27:32 - 27:41] So we already have all of the continents, all of the colors, which is exactly what we want to render within our legend. So our creating our legend is going to be a breeze.

    [27:42 - 27:53] We're going to basically loop through each element in our domain, render each continent, and then use the color scale itself to render a little circle that shows that continent's color. Okay.

    [27:54 - 27:58] So let's wrap this all in a single div. You might be asking why a div, why not a G element?

    [27:59 - 28:04] The reason is in app dots felt, this legend lives outside of the SVG element. It lives up here.

    [28:05 - 28:08] Okay. Because this is not SVG, we can't use a group element.

    [28:09 - 28:11] We need to use a div. Okay.

    [28:12 - 28:19] And so let's go ahead and create a div and give it a class of legend. You might notice that I use classes a lot, even if I don't reference them.

    [28:20 - 28:31] The reason for that, honestly, first of all, if you could practice to use these legends in case you ever do need to style later. But second of all, I think it's really nice whenever you want to find like, oh, what is this in reference to?

    [28:32 - 28:35] Like, what is this group? You know, obviously visibly you can see, okay, it's like the left.

    [28:36 - 28:47] It's just access. But if there's anything more complex, adding these kind of, you know, descriptions of your elements by using classes, it's just a good practice, I think, to keep your code concise.

    [28:48 - 28:56] So if you're ever inspecting it, if you're ever looking closely, if you ever need to kind of see where something lives, you could just global search it. I think these are all good practices.

    [28:57 - 29:03] So with that being said, I'm going to give it a class of legend. And within this div, we're going to use the exact same, each block is last time .

    [29:04 - 29:18] We're going to loop through the domain of color scale. And we're going to call each of these element items a continent, because remember that as we already looked at in our console, that is exactly what we're rendering, our six continents.

    [29:19 - 29:30] So we're looping through the domain as continent. If it makes you more comfortable, you can definitely do something like ticks equals color scale dot domain, and then loop through ticks yet again.

    [29:31 - 29:35] This is the equivalent code just to be clear. It's really a personal preference.

    [29:36 - 29:43] Now inside of this each block, let's open and close a p tag and render our continent. And let's close our each block.

    [29:44 - 29:45] Nice. What a beautiful legend.

    [29:46 - 29:48] I think we're done. Obviously kidding.

    [29:49 - 30:00] There are some very apparent issues with this legend right now in that everything's in the top left corner. So we're going to need to do some additional CSS styling really from here on out.

    [30:01 - 30:21] It's all CSS to make these legend items look prettier, align one by one on the horizontal axis and then wrapping nicely and with a little circle to show what color is in reference to that continent as well. So first, let's go ahead and add these circle labels with these circle items.

    [30:22 - 30:27] And those are going to be span elements. A span is just like an inline text element.

    [30:28 - 30:34] And so here we're actually not going to render any text within the span. We're going to use the span to render these little circles.

    [30:35 - 30:45] So for now, again, this isn't going to be relevant right now, but you'll see why we need it later. Let's add a background color of color scale of continent, just like the auto complete wanted.

    [30:46 - 30:59] Let's go ahead and open and close that span like so, or you can make it self closing like that either one of these works. But basically, each of these p tags, you see that it spins the entire screen with.

    [31:00 - 31:02] We don't want that. But within the p tag, there is a span.

    [31:03 - 31:07] It's just currently has zero pixels of width. So that's why you can't see it.

    [31:08 - 31:17] If it did have width, you might be able to see it and then you would understand better what it is that we're trying to achieve. And then it would need like a display of block and whatever else.

    [31:18 - 31:20] But again, we're going to get into this later. So it doesn't matter.

    [31:21 - 31:30] For now, let's go ahead and fix some of the other issues. So the first thing we want to do is arrange these continents horizontally.

    [31:31 - 31:38] So we're going to want to open and close a new style tag. And within here, we actually do want to target the legend that we already created.

    [31:39 - 31:48] We wanted to give it a display of flex. And this basically means align all of the elements either next to one another or on top of one another.

    [31:49 - 32:04] For our case, we're going to give it a flex direction of row, which this is the default to be clear, but we're going to be explicit, which basically says place these items next to one another. Now if we save what would happen, they would be rendered without any space between them like so.

    [32:05 - 32:15] The next thing we want to do is add justify content of center. And what this basically does, watch whenever I click save, is it moves everything to the center of the horizontal axis.

    [32:16 - 32:35] And the last problem that we need to tackle is that if it's on a really small screen, maybe I can't even get it this small on my computer right now, but if this were a small screen, these elements would just overflow the screen. So we need to add this property called flex wrap, which can take either wrap or no wrap.

    [32:36 - 32:46] We're going to make it wrap, which basically says that if and when necessary, wrap these elements to the next line. And of course, you can't see it now, but I promise we will need that as we add more elements.

    [32:47 - 33:07] But again, if this is confusing, I would recommend looking up the internals of how flex box works because it is a really handy tool that you'll want to make good use of in your visualizations. Again, here we're just making a flex, saying make it on the row axis rather than column, center the items and wrap them in if necessary.

    [33:08 - 33:13] So what else do we need to do? Right now you can tell that our elements are kind of one long string.

    [33:14 - 33:27] There's no space between them. The way that we can handle that within our legend item is going to be this property called column gap, which basically says how much space should I apply between each flex element here.

    [33:28 - 33:31] We're going to add a column gap of 10 pixels. So this is horizontal space.

    [33:32 - 33:39] Now you see how they spread out already. We need to do the same on our vertical axis because as you can see here, they 're kind of too snug, too close to one another.

    [33:40 - 33:46] So let's add what's called a row gap of five pixels and click save. Now you see that gets pushed down.

    [33:47 - 34:00] If you wanted to do these in one property, for example, you could do something like so where gap, the first argument is going to be the column gap, the second argument is going to be the row gap. Either of those will work.

    [34:01 - 34:05] I believe maybe this didn't work. I'm not totally sure.

    [34:06 - 34:10] Gap might only to, yeah, no, it's sorry, it's the opposite. Should be five pixels, 10 pixels.

    [34:11 - 34:14] Yeah. So row gap comes first.

    [34:15 - 34:20] But I prefer to keep them separate so that we really can identify what it is that they're referencing. And let's go ahead and click save.

    [34:21 - 34:26] And now these are evenly spaced out. They're looking quite nice.

    [34:27 - 34:32] So what else is missing here? First, I think that the legend itself is a bit too close to the chart.

    [34:33 - 34:42] So I'm just going to add a really small margin bottom. Maybe I'll do a margin bottom of five pixels and that should push the entire chart down relative to where the legend is positioned.

    [34:43 - 34:52] And now the final and kind of importance step here is to make these span elements visible, right? We have all these P tags and within those P tags, there's a span that is nonexistent.

    [34:53 - 34:56] It exists, but it's not rendered. And so what do we need to do here?

    [34:57 - 35:08] We need to style the span tag using a few additional properties to make it visible, to make it rounded, to make it look nice. So let's go ahead and go into our style tag and add a new class for span.

    [35:09 - 35:15] We're going to want to give it a width of nine pixels and a height of nine pixels. Now if I save, you're going to see nothing changes.

    [35:16 - 35:24] And the reason for that is going to be actually the display of this element. You'll see height has no effect on this element because it's inline, same with width.

    [35:25 - 35:41] It, the, you know, Firefox dev tools or Chrome dev tools are going to tell you, make this inline block or make this block because these width and height properties don't apply to inline elements. So we'll listen, we'll say, okay, Firefox, we will make this inline block and hit save.

    [35:42 - 35:57] And now we can finally see our circle elements, but they're not circles. They kind of do look nice with these squares, but if we want them to look, you know, like the elements that they're referencing, these circles, we probably want to apply a few additional styles to make them circular.

    [35:58 - 36:18] So the first way that we can make them circular, or the only way, is by adding a border radius. And so this could be a pixel value, for example, it could be one pixel if you wanted a really small one, or if you want a perfect circle, you can just do a border radius of 50%, which is going to turn each of these, what were rectangles into circles.

    [36:19 - 36:28] And finally, the last thing that we need to make these look like their referent ial elements is going to be a border. So let's do a border of one pixels.

    [36:29 - 36:33] Let's make it solid and let's make it a faint black. So you could just do black, to be clear.

    [36:34 - 36:46] You could say this, but I think these are too dark. So what I'm going to be doing is writing RGBA, and then I'm going to make it 0, 0, which would be black, but I'm going to give it half of the alpha value.

    [36:47 - 36:57] So 0.5. So here, RGB of 0, 0, 0 would be black, but I'm adding the additional alpha argument and making it 50% or 0.5 to make these slightly more faint.

    [36:58 - 37:00] So look at the circles as I hit save. You'll see the difference.

    [37:01 - 37:06] You'll see they're just ever so slightly more faint. You can make this even lighter if you wanted, but I like the 0.5 value.

    [37:07 - 37:16] So I'm going to leave it there. And now we have all of these beautiful circles, all of these beautiful continents, this legend that actually makes sense.

    [37:17 - 37:25] And some final polish, if you wanted to apply it, I want to make these P tags, these continent labels look a little bit nicer. So what am I going to do?

    [37:26 - 37:27] I'm going to target the P tags. I'm going to make them smaller.

    [37:28 - 37:33] I'm going to give them a font size of maybe 11 pixels. Nope, that's way too small.

    [37:34 - 37:36] 14 pixels. And then I'm going to make them uppercase.

    [37:37 - 37:41] I just wanted to play around with this styling. So now you see each of these.

    [37:42 - 37:48] Maybe I'll check in as back to 12. Now that I see how it looks uppercase, no, I'm going to do 14 again.

    [37:49 - 37:59] And then finally, to make each of these individual legend items vertically aligned, so you might notice that there's a bit of vertical discrepancies. This would be a lot more clear if these were smaller elements.

    [38:00 - 38:10] You see how the circle is far above. We could apply this new property to the P tag itself, making these also flex elements.

    [38:11 - 38:25] And then using align items of center, which will push the elements up so they 're aligned on the same vertical baseline. So to make this difference clear, see how now if it's 10, these elements are like actually aligned with one another rather than having these discrepancies.

    [38:26 - 38:33] So that's how we could achieve that using flex. And then now I think that the only issue remaining is that these are too close to one another, right?

    [38:34 - 38:39] The circles are basically bleeding into the text elements. So I can apply those exact same gap properties.

    [38:40 - 38:48] Remember column and row gap. So go ahead and add a row gap of, sorry, I think column gap of three pixels.

    [38:49 - 38:55] And now you see these do spread out. So if I want to make it really exaggerated to make this clear 30 pixels, now there's a lot of space.

    [38:56 - 39:08] So that column gap makes these individual legend items have space between the circle and the text. And of course you are totally welcome to play around with whatever styles you think fit best for the legend.

    [39:09 - 39:16] Maybe you think that it's done need to be smaller. Maybe you want to play around with the color of the text elements themselves, making them also a bit fainter.

    [39:17 - 39:23] You can play around with whatever you think fits well here. But with this, we have finished this lesson.

    [39:24 - 39:42] So 40 minute lesson and we basically done three things. We have created axes labels and axes titles on the X and the Y axis showing happiness out of 10, showing continents, which we don't really need to title for this because it's pretty clear.

    [39:43 - 39:55] Then we've created peripheral elements on top using these grouping continents or I guess regions and a title. And so it's very clear to the reader now what we are visualizing.

    [39:56 - 40:00] We're visualizing the happiest countries in the world. I guess all of the countries by their happiness score.

    [40:01 - 40:06] And then if you were curious what they're grouped by, here are their regional variables right here. Also presented here.

    [40:07 - 40:13] And here are the X axis values that they are in fact rendering. So with that we have completed our legend.

    [40:14 - 40:27] We have completed our peripheral elements and we're finally ready to move on to the next lesson where we're going to add a tool tip to each of these individual circles to add some nice polished, nice user interactivity. I'm really excited and I'll see you there.