Getting Started With Svelte - Draw Your First SVG Element

Drawing your first SVG elements in Svelte

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:14] In this lesson, we're going to begin our simple scatter plot by rendering circles on the screen. Obviously, you can't have a scatter plot without circles, so let's get started with the bare minimum of rendering circles in our browser.

    [00:15 - 00:24] We're going to get started by deleting all of the contents in AppDots felt, just like the web page says to. Go ahead and click Command A to select everything, and then the Delete key to delete everything.

    [00:25 - 00:40] Now, if you save, you'll notice that there is nothing on the page which is, in fact, the intended behavior. First, in order to render data on the screen, we need to get data in the form of a .js or .json file.

    [00:41 - 00:53] Here, for example, was the .js file that came in the existing template with a name, a description, and a reminder. Now, in Svelte, if we want to import data, we need to do so in our Script tag.

    [00:54 - 01:09] So go ahead and open and close a Script tag, and remember that this is where logic lives, and write the following code to import data. We're going to import, and then the name of whatever we want to call our data, and then the path where we can find that data.

    [01:10 - 01:29] In our case, it'll be the dollar sign, data, which basically means no matter where we are in the project to find this folder, and then the name of the data is data.js. So if we save that, and then go down and console.log data, what do we notice?

    [01:30 - 01:45] An array of length zero with this object inside is being rendered, which matches one to one with the file that we see in the Explorer. But in our case, we don't want to use data that looks like this to render circles representing students, right?

    [01:46 - 01:56] We want to loop through real data that actually exists, that actually represents students. And so in order to do that, I've pasted the array I want you to copy here.

    [01:57 - 02:20] So go ahead and copy here or select the entire array, and go back over into your Visual Studio code, and paste over data.js. Now upon clicking Save, if we go back to our project, you'll see that we now have a new data object, or a new data array, of length 18 with each of these objects representing a student.

    [02:21 - 02:34] Each student has a grade, a number of hours studied, and a name. And we're going to use this data to actually render elements on our screen, which brings us to the exact question of rendering data.

    [02:35 - 02:45] How do we render 18 different circles one at a time on our screen? And the answer is the Svelte EachBlock.

    [02:46 - 02:59] So this felt each block functions as follows. We go ahead and write pound each, and then we give it an array, for example, one, two, and three, as, and then whatever we want to call each of those array elements.

    [03:00 - 03:08] In our case, let's do number. Then, before we close this block, which we can do with forward slash each, we want to render elements within.

    [03:09 - 03:26] So we could write a p tag, and inside of that p tag, print the number, and now you see one, two, and three being printed at the top of your screen. So we know how to render elements, but we don't want to render one, two, and three, we want to iterate through our 18 students.

    [03:27 - 03:37] So let's replace one, two, and three with data. And instead of number, let's call each element D, which is a common practice and visualization design.

    [03:38 - 03:50] Whenever you're iterating through data, you call each individual element D. Now you notice that there are 18 funky looking objects with the type object, which is definitely not what we want to render.

    [03:51 - 04:01] Instead, we want to render what are called the object properties, right? The elements within the object, like grade, hours, and name, that we want to paste instead of these objects.

    [04:02 - 04:14] In order to print the object properties themselves, we can go ahead and replace this single D with D dot, and then whatever property we want to print. For example, D dot name.

    [04:15 - 04:30] Now we see all of the names for every student in our data. We could extend this further by writing studied for D dot hours hours and scored D dot grade percent.

    [04:31 - 04:44] Now we have sentences, each of these representing a different student in our data array. Now you're in a data visualization class, you probably know this isn't the best way to present this quantitative information.

    [04:45 - 04:50] This is why we're making charts. So rather than printing these P tags, we want to print circles.

    [04:51 - 05:04] And in order to do so, we need to look a little bit at the SVG documentation for circles. So I'll bring this over and kind of show you how circles work in SVG and what it is that we'll be rendering.

    [05:05 - 05:23] And here you can see the circle SVG element is a basic shape with simple attributes like CX, CY, and R representing radius. Here you see one circle rendered within a parent SVG element, and we see that these attributes are needed in order to render the circle itself.

    [05:24 - 05:38] So back in our code, if we go back to this each block, we no longer want to print circles, we want, or we no longer want to print P tags, we want to print circles. And at first this is going to have no effect.

    [05:39 - 05:51] As you can see over here, nothing actually prints in terms of the circles. One reason for this is because we need these encapsulated in an SVG parent container.

    [05:52 - 06:00] But still you're going to see that although an SVG exists, nothing exists within it. And the reason is these circles are lacking any attributes.

    [06:01 - 06:05] Let's go ahead and write those attributes. We know that we need a CX, for now we'll make it 100.

    [06:06 - 06:10] A CY, we know that we can make it 100 as well. A radius, let's make it 10.

    [06:11 - 06:22] And then a fill, which we can say is purple, a stroke, which we can say is black and a stroke width of 1. Now if we save, we actually see circles on the screen.

    [06:23 - 06:28] You look really, really closely. And you might think there's only one, but actually there's 18 of them.

    [06:29 - 06:40] They all just have the same attributes, so they're blended behind one another. Now in our each block, we don't want to just render 18 circles at position 100, 100.

    [06:41 - 06:58] We want to use the data that we already have, remember this array, and position elements according to their actual values. Now in our case, the X element or the X value is going to be according to the students grade on their final exam.

    [06:59 - 07:07] So rather than 100, let's write D dot grade. Now the CY value is going to be based on the number of hours studied.

    [07:08 - 07:19] Now if you make that change and you click save, you'll start to see something that kind of resembles a scatter plot, but maybe not a very pretty one. You'll see most of the elements are up in the top left corner.

    [07:20 - 07:27] It's hard to discern any trends and it looks upside down. And the reason for that is because these are raw data points, right?

    [07:28 - 07:43] We are taking 44 and 50, 60 and 99, 23 and 50, 15 and 34, and just using those numbers to position our circles. When in reality, we might want the chart to be a lot bigger than this kind of 0 to 100 paradigm.

    [07:44 - 07:57] So we want to take advantage of the full space. In order to do that, we need to create what are called scales to position these elements according to other elements, like chart dimensions, for example.

    [07:58 - 08:09] So in order to do that, we need to install our first D3 module, a module called D3 scale. So what I want you to do is open a new terminal by clicking this button.

    [08:10 - 08:20] Or if you can't find that, if you're having trouble, you can go back to your terminal right here and write the exact same thing. But I want you to write npm install D3 scale.

    [08:21 - 08:26] Click enter. After a few seconds, you'll see that it writes some logs and that it did in fact work.

    [08:27 - 08:36] And now you can close this terminal if you want, or you can leave it open. But now that we have D3 scale, we can import a module that we need from it.

    [08:37 - 08:45] In our case, we're going to be using scale linear from D3 scale. Now you might be asking, how do I know that's the one that I want to use?

    [08:46 - 09:02] Well, if we go over into D3 scale, we can find its documentation here, where it talks about all the different options that we have. In particular, you'll see it says for continuous quantitative data, you want a linear scale, you can use an ordinal scale.

    [09:03 - 09:21] It really outlines what kind of scale you need, and then it has documentation on how to use them using examples like this one. So eventually these will become second nature to you, but usually you'll think of what your input is and what your output, and that will kind of reveal what scale you need for your chart.

    [09:22 - 09:36] In our case, we need scale linear, because we're mapping these quantitative values, 34 and 15, to our chart dimensions, which are also quantitative. So to construct a D3 scale, we need to write something like this.

    [09:37 - 10:00] Let X scale equal scale linear, and then add a domain where this is the input and a range, where this is the output. So let's think about our X scale in particular, and the input is pretty easy, because the X values are based on a student's grade.

    [10:01 - 10:15] Now, at least in this chart, we're going to assume that the regular range of potential possible grades is 0 to 100. So we're going to place inside of our domain an array with 0 as the minimum and 100 as the maximum.

    [10:16 - 10:31] Now we also need a range, and the question of what we supply for the range is a bit trickier. Now, we do know that we want our 0 position to be the leftmost side of the chart, so the beginning of our range should be 0.

    [10:32 - 10:49] But the width is a bit more tricky, because our SVG itself needs to span the entire page. For now, because responsiveness is a whole other project that will work on in a future lesson, let's go ahead and create a variable called width, and assign it 400 as its value.

    [10:50 - 11:05] Now, we can say the range goes from 0 to 400. Let's go ahead and supply each of these raw grade values and put them into the X scale function.

    [11:06 - 11:17] Now, if we save, you'll see the chart does in fact spread outward and fill the available space, which means we're doing something right. Let's do the exact same thing for our Y scale.

    [11:18 - 11:38] Now, we're going to have the same scale linear, and we'll also say it has a height of 400. Now, we want the Y scale to be a scale linear with a domain of 0 to 100, really 0 to 60 will be good, but we can make this more robust in a second, and then ranging from 0 to height.

    [11:39 - 11:56] Now, it might be hard to tell once we supply the Y scale here, but this chart is actually upside down. And you could look at this if you wanted by taking a closer look at the actual chart that we're trying to create, but you might notice that the curves of these two are opposite.

    [11:57 - 12:14] So this point actually is matching map point, this point matches this point, etc. And this chart is upside down, and that's because, although we are used to generating charts from the 0, 0 position being at the bottom left, the SVG coordinate systems 0, 0 is at the top left.

    [12:15 - 12:35] So, what we actually want to do in every chart where we're scaling things vertically on the Y axis is switch, height and 0. And what this really practically means is that if somebody studied 0 hours, right, they would be at the very bottom of the chart, they would be 400 pixels down.

    [12:36 - 12:54] If they studied 60 hours, which would be the most possible, they would be at the top of the chart, right, the 0 position, because the coordinate system 0, 0 is up at the top left. So this is a bit of a tricky little gotcha that D3 has or the SVG has in its coordinate system, but you'll want to remember this specifically.

    [12:55 - 13:06] Now, because I inverted these, if I click save, you'll notice that they do in fact switch, and we now have properly scaled values. The only problem is we can't see them, right, and so this is the last step of this lesson.

    [13:07 - 13:19] So we have this SVG element and all these circles within, but some of them aren 't visible, like these two. And the reason for that is because SVG by default has a width of 300 and a height of 150.

    [13:20 - 13:33] But we supplied a width of 400, I forgot to add that there, and a height of 400 , which is obviously bigger than our SVG. Now, in order to assign these attributes to the SVG itself, we need to write this.

    [13:34 - 13:40] Width equals width and height equals height. Now, let's talk about what's happening here before I click save.

    [13:41 - 13:50] We're basically saying that width should be some value. We could have put 300 here in strings. We could have put 1000 here in strings.

    [13:51 - 14:04] But because these are values that are referenced within our script tag up here, we actually want to wrap them in these mustache curly braces. And we're basically saying that this has a width of 400 and a height of 400.

    [14:05 - 14:26] Now, if I save, you'll see our entire chart is in fact visible. Now, if you want a final life hack before we finish this lesson, because the width property name and the width value that we are assigning are the same, we can actually delete this equals sign and just provide the width inline like this, and the exact same thing with height for a little bit more readable code.

    [14:27 - 14:43] Now, if I hit save, you'll see nothing changes because the code is in fact identical to as it was before. So let's go ahead and format this code if you haven't already by doing the command palette with command shift P and typing format.

    [14:44 - 14:58] And now you'll see you have a Svelte file that looks nice, but more importantly , renders the initial starting point of a scatterplot. It has the same shape as our final scatterplot. It's just in these fixed 400, 400 dimensions.

    [14:59 - 15:07] It doesn't have axes yet. It doesn't have interactivity yet, which we'll get into all that and more in the future lessons. So I'm super excited and I'll see you there.