Learn How to Build SVG Line Charts in React JavaScript

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
thank thanks for joining us tonight this is my first talk for react.js Green Bay but it's also my first talk so I'm really excited to try this so looking forward to learn learning that while I teach you this so this is a chart that we're making basically it's this line chart we're gonna have data that we plot these different points we join them by a line but then we also have some additional features like you can customize label percision you can customize dimensions and you can add a grid and you know you might wonder why are we gonna build this from scratch because you know there are literally thousands of charting libraries in NPM a lot of them have a great functionality and really neat features but I feel like there's three main reasons to do this one maybe you have customization that you want to do that you don't feel like it's supported by any of these existing libraries maybe you don't want to add an additional dependency but even more important I think it's great to learn how to build these that way when you need to customize a chart from a library you have the underlying know-how in terms of laying out SVG's positioning things where you want them and actually I'm gonna extent go a little bit beyond what my original blog posted and at the end of this I'm gonna take a reach arts chart which is a really popular library I'm gonna use what we learned here to extend that and have like some customization so primarily the way that you get started is you just draw out what you want to build and I found in building this line chart which was the line chart that I used in an actual client project I found it was really important for me to keep track of what I'm actually trying to plot I happen to use a diagramming software called lucid chart which you can see pictured here and you can see how to do a lot of different diagrams to keep everything straight but you can really use anything even just a pencil and paper okay so let's just dive into it the first thing that you have to understand when you're laying things out with SVG is your origin is this top left corner so you can see I've added the arrows that point to the left and point down and there's the zero zero we're keeping that in mind because as we lay these the lines out and as we lay our guides out we are going to have to flip things vertically otherwise our chart will start up here in the corner so the first thing we're going to do is we're going to lay out our y-axis and our x-axis and basically you start with three main variables you're gonna do your desired height and width as well as your font size which eventually feeds into this padding which is green so throughout this whole walkthrough I'm gonna be referencing here's our chart area this is where we're actually having lines and points outside of the blue and the green that's where we'll have some labels on both for the X and the y-axis and then a title eventually so the way I did it was I based my padding off of the font size and also the number of digits that we're going to need to display here in this padding I have a little code sample here I'll show it more in context but basically what I did was I took the maximum of than why from my data so if you think about all the data points that you have and you think of all the Y values for those what's the maximum you earlier I mentioned you want to perhaps allow you know custom precision like you and have decimal points or not you keep that and you keep that in mind by using two fixed and then how long is that number you know so if your maximum is a hundred and you have you want two decimal points that's what six characters and then I just add in one for space so what I thought looked good was the desired font TSA's font size that I had those numbers of digits and then multiplied it by three so basically the there's not like a exact formula for this it's just what you think looks good based on what font you're using and based on the data set so if you think you'll what range you might be in so let me show you the code and I'm just gonna be hopping from different tags which at the end of this I'll share a repository that has all of these branches and tags so you can go and see exactly where I was when I was walking through this but in this case I mean that the axis X YZ and you can see here I'm just doing exactly what I just described I'm finding the maximum Y from my data and my data actually looks like this so this data is imagining you have a data point for each day of the week so Sunday Monday Tuesday Wednesday and then our X values are just the position of that day of the week and then Y values these are just kind of random just values that I came up with as an example and so the maximum from that which I think was like 500 I'm converting that to a string that I'm getting a float and I'm finding the getting the fixed precision so in this case I want two decimal places adding some getting what the length was of that so I think that would be six and then I'm adding one so seven using that formula that I came up with that I thought looked good and then I have my I've go back to my diagram and this is kind of where plotting this out is really helpful because if you think about okay so I want to have this much padding then my y-axis is going to start at a XY coordinate of padding and padding and so that was like ended up being 50 pixels or something it would be 5050 and then it would be whatever my desired height was so then X stays the same and then I just have the total desired height so that's the height of the chart plus the padding minus one of these padding so it only goes to at this point doesn't go through all the way to the end same with going the other direction start with our x padding and that's height minus padding to place us here same thing here height minus padding and then with - padding and then what we end up with is and this is kind of faint but there's an X and y-axis here so now that we have our canvas we can start plotting out our points so a common theme that's just going to keep coming up as we plot all these things out now that we have our container is ratio and it makes sense because you are laying things out in relation to all of the other points that are on your chart or all of the other guides that are on the chart and the points are great starting a place to be considering this because you can kind of think of it as if we have any particular point that we want to lay out and we think about okay so I have this x value and let's say this was 1 or something you would divide it by whatever your max was so that's 1 maybe this is 8 or something so that's 1/8 of the way across you multiply it by your width so that you know where to lay it out on the SVG canvas itself and then because we have this padding around here we also want to offset it so we push it into the actual chart area and leave our padding unoccupied until we need to place labels and things that actually belong in that gutter and then plotting lines with SVG it's really simple you just give it a string that's made up of a number of points and then you give it a stroke a width there are other attributes that you can use but these are the basic ones and so to get into the nitty-gritty of how do we get from our data our data set to a string that the polyline can use is we map over our data points which just to remind you our data looks like this so we map over our data points and for each point we say and in this case I'm calling the point an element we say for the x value of that element I want to know what is the ratio of that to the maximum x value from our data multiply it by the chart width and then add the padding so that I can push it out of the gutter same with the Y value I'm taking the Y value from that data point finding the ratio of that value to the maximum Y from the data multiplying it by the chart height and then adding the padding but because the origin of the SVG so the origin that SVG is opposite from the origin of what a typical chart would have we need to flip it and so that's why we do chart height minus all of those things so it just inverts it and then the format that the polyline is expecting are these X Y comma separated pairs with spaces in between I can show you what that looks like in our code so that's here it's exactly what I just walk through and then we just take the points and we pass it into the polyline and it ends up looking like this so in my opinion that's really pretty simple for you know going from nothing to having a chart that maps out our polylines so I find personally it gets kind of addicting like once you know how to start laying things out you you want to do it a lot and like roll your own so be careful of that because a lot of times the charts out there will be really the libraries out there will be the best option but it's fun to build your own - that's what code pen is for right okay so then like I said ratios are gonna come up a lot and so when we're doing our Cartesian grid I'm gonna show you a horizontal and vertical quickly we have to start again with a ratio so we think about how many guides do we want and by the guides I'm thinking of are these guides that go across you say how many guides do I want and then for each guide that you want to layout you say okay what's what's the ratio of that to the number of guides I want so that I can lay them out evenly along the different axes and we start with you know a zero based index plus one because since you already have your X and y axis if you you can put a guide there but it's just going to overlap with the axis you already have in place so with the horizontal guide our X will always be the same because they're just going to line up with these edges of our chart so the start will be the same value as our padding because we just push it over that much and then our end will be the total width of our SVG - the padding on this side for the Y value you'll do the height the height of our chart so the height of our chart here is this total height minus padding here and padding here so padding times two and then we subtract that from the height chart again to invert it and then we add our padding so push it down that way vertical guides are similar the math is just a little bit different we use the exact same ratio in this case our Y value is always going to be the same so we'll start with padding because we're pushing it down from the top and then our end will be the height minus the padding so imagine like a line going all the way down to here but then we subtract that padding and then our x value we use that ratio that we calculated and then multiply it by the width of the total SVG element and then we just subtract the padding on each side so then we would lay out so that lays out our line and then we just push it into the chart so we add this padding on the left and that ends up looking like so then we have our Cartesian grid and the way that I set this up in the code is I have horizontal guides and vertical guides and I have for my line chart component you can just pass in the number of guides that you want horizontal and vertical guides and the code looks just like what I described for the example of a horizontal guide you have the start of your x value the end of your x value it's gonna be the same for each guide that you set up and then the way that you come up with a number of guides basically out of nothing because they're kind of arbitrary is you create an array and you say how many guides that you want to have you fill it with zero so this is how you can initialize an array of however many objects then we map over it and we take the index of each of the guides in our array we calculate that ratio that keeps coming up and then in this case we need to figure out what our y-coordinate is and so we say it's the chart height minus chart height times ratio plus padding and we just use another polyline and the format of the points that it takes is exactly the same it's the pairs of coordinates separated by a space and then we can just drop those into our chart like that so you do have one question that came in okay or was it answered I don't know if Nico if you saw that oh never mind yep yeah yep I just answered you could the do question was from Zach he mentioned Kelsey that since we're dividing each elements y-value by the maximum which ever wants to highest Y value will always be at the very top of the chart so that's that's correct yeah hey Kyle so just real quick do you mind talking a little bit more about SVG in general I know that you're using polyline and SVG here but for those that haven't really done much SVG maybe just a quick run-through of you know what is that SVG tag and how what what's going on sure so I have a link here as well that I'll just put up in the background is um so SVG's are scalable vector graphics and I find them really helpful in that they have a similar syntax to HTML the markdown is and so basically like I was describing a minute ago you have the you have this origin here up at the top where you're starting with zero and you give it a you give your SVG of view box and so that's where our width and height are laid our are utilized in our actual code and when you lay things out you're doing it within the you're you're laying them out within this pair my guess would be how I would describe it so you're saying that our view box is going to be like let's say a hundred by a hundred and so whenever you're laying out your points or your x-axis or your y-axis you're saying where within those hundred units left to right or those hundred units top to bottom am i placing these elements and there's a lot of different elements and I only use a handful of them here so I use polyline and then I also use later on I'll use text and T span and circle but there's a lot of different elements that you can use and they're all going to use things like X or Y or some variant of them in order to be positioned within your SVG element but you can really take it a lot of places cool and that's why I had mentioned earlier like code pen you can find people making really neat things in code pen using SVG and the Indian went Docs that I pulled up as well have a lot of really great examples especially you know figuring out how to use particular elements it's really helpful to to just look them up and see exactly what the different attributes that they accept are and what they'll do based on what value you pass them awesome for for myself most of my experience with SVG has been mostly around like icons and logos and SVG allows you to pass in essentially pass in some JavaScript into the actual icon code so for example being able to set a color you you essentially have the icons kind of metadata and then at runtime you can fill in the code sorry you can fill in the color the size and all these other things with with JavaScript it's pretty cool yeah and I think and maybe I kind of glossed over this but the idea of it being scalable you don't it like you know when you you you use like a PNG or a JPEG if you scale it up too large you you you lose fidelity or it starts to look blurry and so with SVG's because you're laying them out with relational points they are scalable so as you make it bigger it stays just as crisp and that's why we can do things like pass in different heights and widths and it just adjusts to what arguments we pass in okay so just one more one more component that we have to add to our charter it was there something else see ya real quick we have one more question about SVG's from from shy the question is the numbers in the view box and in the PAS line do those represent pixels they represent the / what am i proportion I'm forgetting the word um because you can give it a hundred by a hundred but then you can have it fill like those are your units and then you can have it fill a containing div that you say is 800 pixels so it's really more proportional and that's why it's so great that it's scalable because you know if you if your view box is 100 by 100 and you place a circle at fifty fifty right there in the center and you scale your rectangle or square larger or smaller the circle stays right in the center so it's adaptable so you can see how that would be helpful on different size screens especially like mobile development if you can have something that will just fit to whatever you know if you're using a phone or if it's a desktop you could say I wanted to scale up to a maximum of 500 pixels or something along those lines okay cool so so if they say that you were making this chart be 100 by a hundred if if you were to make a ten by ten it would still fill up the space mm-hmm cool yeah that's a great question mm-hmm yeah that's why we think that yeah that's a really good question another thing too is you know you can position things in the SVG there outside of the outside of the view box if you think about it's kind of like a window and so then you can have things animate in and out of view so that can be a neat thing that you do okay so the last thing that you have to do within your SVG is add labels similar thing again like for x axis labels in this example you figure out your ratio here so that's the index here of this element divided by the max of your X values you multiply it by the width here in it and then you will add padding to push it away from this gutter and into the right position and then in my case I'm also positioning it then back half of a half of the value of my font size because I happen to know in this case and this is kind of a limited case so this is a caveat when you're doing setting these up is I know that my data labels are all one or two characters because they represent the days of the week so in for Monday T for Tuesday and so on and so I know that I can position it Center the text under the tick mark by just moving it back half of a like character width and that's that's in this case if you thought that that would be more variable you would need to adjust accordingly and have a little bit more of a nuanced approach this just worked for this use case and then for my Y value so how far up and down I want to position my labels here finally we're actually using this green gutter and so we take the total height of our chart or SVG and then we subtract padding so that brings us here to the x-axis and then we add font size times two so that basically just pushes it down to lines and so that we have some space between our x-axis and our labels and I'll show you that in the code so yeah so here I'm figuring out what the Y value will be tight - padding and then we just add some space between our x axis and our label text and I'm iterating over the data that way I can look at the x value because that's what I really want to label because as you remember from the data set each day of the week has their own x value and it's just the index here and I so I get that ratio here and then I multiply it by the chart width and then add the padding to push it away from the edge and so here's another SVG element this one is text and you can give it these different style attributes in the same way that you would CSS one of the differences though is it uses fill instead of color but I can still use things like font family and then I just pass it this element label so that will be where like the end for Monday or T for Tuesday come from and y-axis is similar the in this case what I do is I keep in mind like if there is a number of and horizontal guides that I want to show I want to have a label for each of those guides and so that it that's how I come up with how many labels to come to render versus here I'm just doing one for each data element with my y axis labels I do one for each guide yeah and the here's also where the precision comes into play so whatever precision you pass in you can have it this way and that ends up looking like that so it's basically all that we do within the SVG to create our chart something that you might remember from math class is that you have to also put labels so under the X to the side of the Y and then also give a title to your chart so you know what your charting and I just decided in this case to do that outside of the SVG you so for the title for example I just made a different react component and I just render that above my line chart and I've said the text is gonna be movements per day of the week and then I use CSS grid to just lay the different components out so this is this chart title is actually outside of the SVG so I won't go super into detail on that but if you want to see the code it's gonna be in the repo and in the blog post and so that just lays that out there and I like having it outside to the SVG because you may want to treat it like a header in the same way that you would treat any of the other headers on your page axis label same thing so I made these label components I pass in the text and then for this y-axis label it has a rotate attribute so that it will rotate it to the left so how you would expect to see a label on a y-axis okay so like I said I built this originally for a client project so it was something that actually got used or something similar not exactly like this but same concept but probably where you're gonna find it most useful in your day-to-day to know how to use these concepts is in things like extending reach arts so in a different client project we had a case where we wanted to add a label kind of like this so it's a rectangle it has some text inside it has some brand colors that they use I'm going to have this line that connected it and I knew that based on the position of this point I could lay all of these different components out appropriately so it would look it would have the look and feel that I wanted and then also taking into account these kind of tricky cases where if I had just done the same layout as I did for this dot for this dot up here that's really close to the edge of my chart it would have pushed my rectangle and labeled just completely out of the view and when you push things out of your viewport like I said earlier it just cuts it off and so you may have these cases where you need to understand how do all these numbers working together impact the view and how can I conditionally display things so in this example I'm flipping it over and showing it under the dot because that's where I have room and the code for that kind of almost ends up looking more confusing than the other code but just because it's more of a complex look so using reach arts I just imported their components so line chart x-axis line and y-axis and it does make it really really fast I mean you saw the code that we had to write to do it manually but here we just use their their line chart and then pass it the x-axis and y-axis and then have a line here and we say what our data key is going to be I won't go super into how to use reach arts but just to give you a high level of review one of the options though that reach arts gives us is we can use a custom dot component and in my case I only want to show one of them so I use this target prop and I write a custom dot component I use the props that get passed in by reach arts and then I can do math like this where I say if I have a rectangle that's 50 by 125 and I want to push it up 60 unit or 60 yeah 60 units from my dot I can do math here to say well if I have a Y value that's from my dot which is C Y here because they're wanting to they're anticipating you placing a circle and so a circle has a see Y and I see X and that's where the origin is placed on your SVG I say my C Y minus the height of my rectangle that I want to draw minus the Y offset that I want to use if that's less than 0 then I know I've pushed it off of the screen or out of the viewport and so in that case I can just invert it and so I in that case I say ok so wherever I place my rectangle top to bottom and where I place that connecting line top to bottom is going to be dependent on this invert calculation so this is going to be true or false so if it's true I can use this formula if it's false I can use this formula then similarly I lay out my connecting line my rectangle this is the this is another component that you can use with SVG's another element and just using some math similar to what I walked you through in detail I can lay these elements out text is another or I guess I showed you text earlier but T span is an element that you can use with text to show your text on separate lines and just do some more nuanced layout with your text within your SVG and so that one ends up looking like planets sorry switching back and forth between all these commits I want my not node modules mr. got mixed up yeah this has happened to me so you just got a you got a uh NPM I again yep doing it here anyway and ends up looking like this where it either displays it here where you have enough room or it displays it here if you don't have enough room above it hey cuz we we have a question about the the y-axis tix I believe it's so the question is that because the Y and the X Y coordinates are go from from the top left the text is not aligned with the y-axis and you can see that in these in the bottom the bottom label there the zero point zero two zero so they're all left aligned instead of being aligned with the with the with the axis so the question is would there be an easy way to align it to the right who will line that text do you see what I'm saying yeah and I should you saw their line I'm sorry in the in the bottom example you do have the zero aligned I think that's what they mean yes yeah I see what they mean yeah and I should have said alignment when I'm thinking of alignment I'm thinking like top and bottom so like this is this line if it can't if it continued over it would go through the middle middle of the 100 but I see what they mean like this zero being lined up with the zero I think I think they got my line chart just off the top of my head that maybe something like text anchor right or something along those lines see if that made any difference no you would have to play with it and that's why that's we're going to indium MD in Docs that I showed earlier which I have in the presentation link very first that's where that would be really helpful to think about where am I what part of my element am I looking at when I'm aligning it on the within the canvas and so a lot of times it's just gonna be the top-left corner but you can use different attributes like and I did it in the reach arts example funny enough you can use things like text anchor an alignment baseline to say okay I'm actually not interested in aligning it based on that top left corner I'd rather be looking at the exact center because that a lot of times is an easier way to position something and that's more consistent versus you know different words can be of different lengths or even number values and so yeah I would recommend going to that those docks and looking up these different attributes awesome thanks and here's just the example of adjusting so that you can fit your label yep and so besides just pointing you all to some other great resources in it and then also a text detailed walkthrough of the steps that we just took and the repo that's all I got for y'all awesome yeah this this was awesome I like you went a little bit farther than you went in the in the blog post which was really cool to see see that being implemented in recharge so yeah thanks Kelsey really glad that you came on and and I think this was super informative for myself and I'm sure for for a lot of other people so yeah I'm not sure Jacob what the how we can open this up for questions maybe is that something that we've been doing to the QA or yep okay yeah so if anybody has any questions about beyond what it was answered whether it's even maybe it's just about SVG's maybe it's about just other ways that this can be done or any questions for Kelsey or Nico now is the time so either in the chat or the Q&A is easier for us to manage questions but if you have any questions feel free to throw them in there all right we got we got a comment not a question Justin says he struggled with the victory for days which had this back on information before starting there yeah we just i we were we used victory and a project i was recently working on and we positioned some labels I'm actually not even sure the extent of what kind of charts you can make with victory but what we were making was a radial chart that would say tracking progress and saying you're 60% so it fill radial chart 60% and yeah positioning things in the middle of that like if you wanted to put the percent and maybe a label X knowing the XY coordinates and how to lay things out like that is really helpful yeah I mean we can we can talk a little bit about some I think it makes sense to discuss some more favorite graphing libraries Jacob you can start me you know as a person that does a lot of marketing I love all of them they're all good I'm not sure I know for some of your projects Kelsey you probably use a couple of other things but we we've been using for the part that I'm on we started using nivo which is a if I don't think is as as popular some of like something like reach arts or d3 but it's surprisingly simple it's like very high level so you don't really get to customize too much and it was great we we had a lot of success with it for some some some of the requirements that we got we had I think we had to dip into recharge for like a few I think we had some overlap like a line chart that also had a bar chart behind it with different data we had to do a little bit of but overall I knew it was really a great choice and I've been really tempted to like fork it and just call it Nikko and then I said they're their domain is Nebo dot rocks and Nico dot rocks is available so I'm saying I could I could steal some traffic from them very easily how much rocks you better not be letting on live stream somebody's gonna praise you we can we can scratch that later right chicken from the well just take that up no it's too late we do have a question though from shy it's uh she asks if it's not too difficult can you show or explain an example for implements in animation maybe on on hover with the table yeah they took a question do do SVG elements have the same do they respond to some of the same event handlers that normal HTML elements do you can apply classes to SVG elements in the same way that you can other HTML elements and like other HTML elements there are limitations I will I don't think I could quickly LiveCode an example right here because I am not sure how to inline do like transformations and hover and hover things like that those specific selectors but another thing is a lot of these libraries like reach arts have that stuff built in for you as well but basically if I was to describe the steps that I would take for shy I would have a hover selector for a class apply that class to the element and then have on hover like transform translate however many you know units I need to move it left or right or up or down you can do the same thing with changing fill and all that it's definitely possible I don't think I could demo it right now though yeah it seems just from from from reading some CSS tricks about SVG's it seems like you would have to attach a class and then do some transformations on it a lot of jQuery on this page not a big not not very happy with it I do have an example if I have time to show animating I think I have it of animating SVG um somebody put a bunch of practice projects on my Mac though and now I can't find it who definitely wasn't me we have a good comment from Andrew I says super cool presentation where the client projects you built these four intended to be static charts or were you taking in a feat of data that would update periodically so the idea is that the data would update continuously so you would be getting the in this case it was movements or you know whatever your tracking day-to-day it was supposed to be showing you here's your average movements for a Tuesday here's your average movements for our Wednesday so that would be continuously updating and the in my example where I showed a really simple just object with some or I should say it was an array with different objects in there in a real world example or in our crowd client project example that was coming from an API you I wanted to show my I don't know Miko if you remembered the animation learn something that I showed one Monday but there is a really good YouTube video out there that I'll ask Jacob to include but I learned initially how to animate SVG's using our I learned from this YouTube video where just somebody did kind of like what I did here he walks through how to do it so send that to Jacob so he can include it in the post talk resources yeah that'd be great my project that I mean ya know where is what we for everybody listening will send out all the resources and you know the code sandbox links and all that stuff we'll put it in a nice little package for everybody and now we'll include that to Kelsey so yeah I mean one more time just thanks for putting this together this was really awesome and I'm looking forward to more blog posts from you thanks guys yeah
Info
Channel: Headway
Views: 5,348
Rating: undefined out of 5
Keywords: javascript, react, reactjs, webdeveloper, softwaredevelopment, svg, java, coding, coder, webdesigner, webdesign, webdev, css, html, svg tutorial, svg react js, react svg tutorial, react line chart, react charts, react charts example, react chart tutorial, react js line graph, line chart in react js, javascript charts tutorial, creating charts in javascript, svg line chart, coding for beginners, javascript for beginners, react svg, svg react, svg javascript, react chart, javascript svg
Id: PV2kFiVi5Ns
Channel Id: undefined
Length: 48min 45sec (2925 seconds)
Published: Tue May 19 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.