Adding annotations

We'll add annotations to our chart to tell our viewer what the different parts of the chart are showing. To do this, we'll create a generic function, since there are so many things to label.

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 Fullstack D3 Masterclass course and can be unlocked immediately with 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 Fullstack D3 Masterclass with a single-time purchase.

Thumbnail for the \newline course Fullstack D3 Masterclass
  • [00:00 - 00:08] Okay, so now we've drawn all of our data. Now we want to get into drawing the annotations.

    [00:09 - 00:26] If someone comes in and is looking at our chart, they're not going to have any idea what these gray or blue bubbles are, what is this sand circle, or this orange ish area, or these yellow lines. So what we want to do is draw annotations for each of the elements.

    [00:27 - 00:43] And if we look at our finished product, we can see that there's a lot of different annotations. So let's go ahead and make a function that's a little bit more generic that I 'll draw each one of these elements for us.

    [00:44 - 00:54] So first, let's create an annotation group. So we can just combine all of these into one element, keep our elements organized.

    [00:55 - 01:16] So we want to add a new G, and then we're going to create a, let's call it draw annotation function, annotation. And this is going to take the angle of the annotation, the offset in terms of the circle's radius, and also the text.

    [01:17 - 01:29] So using this function, we should be able to draw each one of those annotations around the outside of this chart. So first, we can grab the, we're going to want to draw a line and also text.

    [01:30 - 01:41] And the line is going to start on that data element and go all the way to a specific radius outside the circle. So to do this, we want to grab X1 and Y1.

    [01:42 - 02:00] And we have this, what is it, get coordinates, let's use autocomplete, I think it's get coordinates for angle, and we can pass the angle in and it also wants an offset. So for here, we want to pass that offset in.

    [02:01 - 02:07] So this is going to be the start of that line. And then we also want the coordinates for the end of that line.

    [02:08 - 02:28] And the end is going to be the same angle, but the offset is going to be some set offset that all of these annotations are going to live around, around the radius of this chart. So let's set this to about 1.6, which is 1 1/2 times the radius from the center to the edge of these, these grid lines.

    [02:29 - 02:38] So I'll sit around here. All right, so now that we have these coordinates, let's draw our line.

    [02:39 - 03:09] So to draw the line, we want to add a line to our annotation, let's call it, yeah, annotation group, group, and then we want to append a new line element. And remember for a line to position it, we set X1, we set X2, and we set Y1, and we set Y2.

    [03:10 - 03:21] So these are going to match up with our variable names here. All right, so X2.

    [03:22 - 03:36] And then instead of X1, we want Y1. And down here, we want Y2.

    [03:37 - 03:43] And let's go ahead and give this a class. And fix this, I don't know what is going on here.

    [03:44 - 03:48] We just want to set the attribute. We don't want to append a new attribute.

    [03:49 - 03:58] Let's set the class name so we can give it a style so we can see where it is. Let's call it, annotation line.

    [03:59 - 04:11] All right, so let's, before we draw an annotation, let's just go ahead and add a line. Add it and draw our text.

    [04:12 - 04:25] So our text is going to be added to the end of that line. So we're going to set X is going to be X2 and Y is going to be Y2.

    [04:26 - 04:38] Because remember we position our text using X and Y attributes. Let's set this to annotation text and then set the text to whatever is passed in.

    [04:39 - 04:52] So let's go ahead and start drawing annotations so we can tweak this if we need to. So first we want to add annotations that describe what this outer and inner bub bly ring are.

    [04:53 - 05:15] So let's use this new function we made so we can do draw annotation. First we want an angle so we want them to be in the top right so we can do math .py times let's do two three and then two six so they kind of sit around that top right corner.

    [05:16 - 05:55] And remember this is an radiance and a full circle and radiance is too pie so a quarter turn is going to be or an eighth turn is what we want for this top right corner so it's going to be math pie times a quarter. So after that we want the offset so for the cloud cover we already have a cloud offset variable here that we use to draw them and then for text let's do cloud cover.

    [05:56 - 06:49] Okay there we go so we're seeing the text in the top right but we're not seeing a line so let's go over to our CSS file all at the bottom and let's add annotation line with a hyphen and for this let's let's see we're using this gray anywhere else so we want to use kind of the text color that we have for the page and then let's kind of decrease though pasty a little bit so 0.4. Okay so that's it for the line and for the text we want to do something similar but it's not a stroke it's the fill because it's just the background of the words.

    [06:50 - 07:30] Let's keep it fully opaque but bump down the font size let's do 0.7 so about 70 % font size and then let's scooch it down vertically so it's centered at the end of that line so if you see that we can use dominant baseline to the middle oh my goodness baseline. Okay so that's good so far one thing that's kind of bugging me is that the beginning of the text is almost overlapping with the end of the line there.

    [07:31 - 07:59] How did we get baseline dominant that's why it hasn't moved. Yeah so now it's vertically centered but it's still kind of edging up against the line so let's bump this x value over about two six pixels so the label and the line aren't kind of sitting on top of each other.

    [08:00 - 09:30] So this is looking good let's copy and paste this and the next we want to do is this precipitation ring precipitation let's scoot it down a little bit so they're not sitting on top of each other and let's also use that precipitation oh my goodness precipit sometimes code sandbox doesn't get all of the characters it's going to be precipitation offset so we use this to draw that ring so it's going to start right at the center of that ring. Okay so these first two are looking good the next we want to do is draw annotations for the rest of the elements but we're running out of room in the top right over here so let's go ahead and let's go ahead and draw them kind of like down in the bottom right also these lines are looking really dark so let's double check that that does not look like it's 0.4 opacity maybe it'll fix itself hmm strange.

    [09:31 - 20:07] Alright so the next we're going to do are these UV index lines for when the UV is over a threshold so let's scoot all the way down to the bottom so about three quarter turn because one turn would be halfway so maybe a little bit less than that and then let's use I think we have a UV index offset UV offset there you go UV offset and we want to be a little bit explicit here because we've chosen a little bit of an arbitrary threshold let's use that in our label so let's say UV index over and then let's put that threshold in here so UV I think it's a big threshold yeah. Alright great so it's getting come off a little bit but we can fix that in a minute the next we want to add is label for this area in here so let's scoot that about 0.7 I think there seems to be a little bit of room above here the reason I'm putting these in the corners is because we have this blank empty space in the corners here because we have a square SVG but a circular data element shape so it's nice to use the empty shape the empty space so we have kind of like a compact chart so wherever it is in our website it can fit maybe there's text flying around it so it's nice to use the empty space for annotations as long as you're not feeling like it's really cluttered so let's do this let's do about 0.5 also let's spell precipitation correctly and let's add temperature here so we're gonna hard code this value because we have static data but if there's more of a dynamic data set then it would be better to figure out what the data point was that this was hovering over and then started at the beginning middle or end of this area just to make sure it labels that very directly and then the last thing we need to do is that freezing temperature circle in the middle just in case it's not super clear so let's scoot it down actually this is a bit of a long label so let's throw it like around here and then we need it to be offset in the right place so this is a little bit trickier because we don't have that offset already but we do have the radius scale so we can convert temperatures to radius but remember our offset is in units of the full radius so we need to divide this by dimensions that bounded radius okay great so now we can see this is butting right up against the end of that circle so the next thing we want to do the last thing we want to annotate is for these bubbles it's not clear what blue light gray and dark gray are so let's add a little bit of a legend there so in order to do this we want to create a circle and a text for each color so we have each of those types in an array called precipitation types that we used for this scale and let's just loop over those so for each and we're going to call each of these precipitation type and then grab the index and we need to know where to put these so we want to put them right underneath this label so we can use this same coordinates for angle function let's copy and paste it and let's call this label coordinate so we're going to use this function we're going to pass in an angle and we're going to pass in an offset so for the angle let's use the same thing we used up here so that's math pi times 0.26 and then the offset is going to be about the same that we used you can see we have this hard code number that we used for our labels out here so for our label coordinates what we want to do is we want to draw a circle with that color and we want to draw a text saying what that type is so let's append those to our annotation group we're going to add oh my goodness append I'll just take slower circle and we also want to add a line or a text element there we go so for a circle remember we need to set the CX and CY attribute so the CX is going to be the first item in these label coordinates and the CY is going to be the second item let's give it a radius so we can see it so let's go around four pretty small and let's also set the color so fill in we can actually use our precipitation types scale color scale there we go and pass in that precipitation type alright so that should color them with the right color but they're all kind of sitting on top of each other so oh and it's not working because this needs to be attribute so let's stagger them so they each have their own row so for the CY let's add 16 times the index so the skin move them about 16 pixels underneath the last one and let's add one to the index so we start one row underneath where that label is let's just close up those brackets okay and let's also scoot them so they sit underneath the precipitation label to make it really clear that they're associated with this label here and then another thing is the colors aren't matching exactly because we have them a little bit transparent just to show those overlaps so let's mimic that by setting this to about 0.7 opacity just similar to those circles okay great so the see how the color matches a little bit better alright so we want the text to be around the same position and remember text is positioned with X and Y and then let's add that label just so we can see where these are going so our label is going to be this precipitation type that we got from our for each loop and we can actually just use the same styles we're using for the other labels by grabbing that same class and reusing it here so it'll shrink it a little and vertically align it and the other thing we want to do is bump this over a little bit so they're not sitting on top of those circles okay great and the last thing we want to do here is our labels are getting cut off a little bit so we could increase the margins on every side of the chart but one little hack that I like to use if it's only a little bit outside of the bounds of the SVG is for that SVG element I will set overflow to visible and that way all the text is visible you just need to make sure that you're not super overflowing and then budding into other parts of your web page but this is just a nice trick for if things like if you have no top margin but you have a line and it might it might hit the top of the chart and extend about two pixels out using overflow visible it's just a really nice way to not have to fludge those margins alright great so now when users are looking at our chart they're gonna have a really good sense of what these different elements are and including legends like this is just a really nice way to explain what things are but also tie everything in together.