Coding

#22 Creating Charts | Build a Complete App with GraphQL, Node.js, MongoDB and React.js

  • 00:00:01 hi and welcome back to the serious now
  • 00:00:04 in this series we already added a lot of
  • 00:00:06 exciting things to this application
  • 00:00:08 one thing I promise you in which will
  • 00:00:10 now add is a chart so that we can see of
  • 00:00:14 the events that we booked how many cheap
  • 00:00:16 events we have how many normal events we
  • 00:00:19 have and how many expensive events we
  • 00:00:20 have so let's dive in and let's learn
  • 00:00:22 how we can add this functionality to
  • 00:00:25 this application
  • 00:00:29 so for this part here I cleared all
  • 00:00:32 existing events and I created three new
  • 00:00:35 ones here dinner in the dark forest
  • 00:00:37 hiking and an introduction to sailing
  • 00:00:40 and will be able to book these events
  • 00:00:43 with the right user account and then I
  • 00:00:45 want to see them in a chart off the user
  • 00:00:48 account with which I'm created them now
  • 00:00:50 test a test com is the account with
  • 00:00:52 which I did create these events so here
  • 00:00:55 they are and here when I click on
  • 00:00:57 bookings obviously see no bookings now
  • 00:01:00 my idea is that when I see the list of
  • 00:01:03 bookings here I also have like a second
  • 00:01:05 tab you could say where I switch to the
  • 00:01:07 chart view so let's start working on
  • 00:01:10 that now before we then implements the
  • 00:01:12 actual chart so I'm talking about that
  • 00:01:14 bookings jazz file in the pages folder
  • 00:01:16 there we have that booking list which is
  • 00:01:19 nice but I want to have that second part
  • 00:01:21 where I'm able to switch to a chart and
  • 00:01:24 therefore in here so in this Al's case
  • 00:01:28 of this ternary statement where I
  • 00:01:30 rendered a booking list it's now not
  • 00:01:32 just a booking list it's actually my my
  • 00:01:35 tabs which then render different parts
  • 00:01:37 now you can't implement such apps in all
  • 00:01:40 kinds of different ways and I'll
  • 00:01:43 implement a relative relatively simple
  • 00:01:46 kind of tabs here I just want to have
  • 00:01:48 two buttons and that render different
  • 00:01:50 contents depending on which one was
  • 00:01:52 picked surrendered booking list or
  • 00:01:54 render the outer part and therefore let
  • 00:01:57 me first of all refactor this a little
  • 00:01:59 bit in that render method here a little
  • 00:02:02 first of all check if this state is
  • 00:02:04 loading is true and I'll have my content
  • 00:02:09 property here and the content by default
  • 00:02:12 let's say is the spinner like this and
  • 00:02:15 now let's actually check for the
  • 00:02:17 opposite if we're not loading because if
  • 00:02:19 we're not loading then I'll overwrite
  • 00:02:20 the content and then this will be my
  • 00:02:22 tabs part and then down there where I
  • 00:02:25 had this ternary expression I'll simply
  • 00:02:28 output content like this because that is
  • 00:02:32 the content I wanna render now I'm doing
  • 00:02:34 it like that with this extra if check up
  • 00:02:36 here simply to make it a bit easier to
  • 00:02:38 read now inside here of the content all
  • 00:02:41 use react
  • 00:02:43 recommend as a wrapper because i'll now
  • 00:02:45 have two top levels sibling elements
  • 00:02:47 stored in here which would not be
  • 00:02:49 allowed otherwise and react react
  • 00:02:51 fragment is the necessary wrapper react
  • 00:02:54 expects without rendering anything to
  • 00:02:56 the Dom because I don't want to render
  • 00:02:57 anything to the Dom any wrapper element
  • 00:03:00 and then up there I want to have dis
  • 00:03:03 with two buttons so a button for list
  • 00:03:08 off bookings or just list and chart
  • 00:03:13 something like that can be as simple as
  • 00:03:15 that
  • 00:03:16 and below that I'll have let's say
  • 00:03:18 another death and in death this I then
  • 00:03:21 want to render my well the content that
  • 00:03:24 is selected up there so if I selected a
  • 00:03:26 list then I want to render a list of
  • 00:03:28 bookings so that booking list and if it
  • 00:03:30 is charts that I selected I want to
  • 00:03:32 render a chart down there so in the end
  • 00:03:35 the content I render here depends on
  • 00:03:36 that selection and therefore let's add
  • 00:03:40 onclicklistener
  • 00:03:41 and let's handle that selection in a new
  • 00:03:45 method which I add here and I will name
  • 00:03:47 this output type handler or change
  • 00:03:52 output type handler and you can name
  • 00:03:55 this however you want of course and I
  • 00:03:57 expect to get an argument here and the
  • 00:03:59 argument should be the output type let's
  • 00:04:02 say that simply is some text and I check
  • 00:04:05 if output type is equal to list and then
  • 00:04:10 I will change some state which I can
  • 00:04:12 then look for down here to render the
  • 00:04:14 list and otherwise I will set it to
  • 00:04:16 chart so up there in my state I'll set
  • 00:04:19 up some initial state output type and by
  • 00:04:23 default let's say that is list now let's
  • 00:04:25 go down here
  • 00:04:26 give that handler and in there handler
  • 00:04:29 here I will then call this set state and
  • 00:04:32 set my output type here to the list type
  • 00:04:37 now of course I could also set it equal
  • 00:04:39 to output type because I'm checking
  • 00:04:41 whether output type is list and since it
  • 00:04:44 is list down here I could just set it to
  • 00:04:46 output type instead of the hard-coded
  • 00:04:48 list I will do it like this though
  • 00:04:50 because in the Al's case I definitely
  • 00:04:52 want a hard-coded because I don't want
  • 00:04:54 to allow for arbitrary out
  • 00:04:56 types passed in as an argument I really
  • 00:04:59 only want to set output type here to
  • 00:05:01 list or to chart and they are for all
  • 00:05:03 hard-coded in both occasions so now I
  • 00:05:07 have this handler here this handler
  • 00:05:10 should be called on this click here so
  • 00:05:12 this change output type handler and here
  • 00:05:16 I'll bind this as a first argument
  • 00:05:19 because bind requires the this keyword
  • 00:05:21 to be bound as the first argument and
  • 00:05:23 then the second argument I pass to bind
  • 00:05:25 is the first argument received in here
  • 00:05:27 and that should be output type and for
  • 00:05:30 that first button that will be a list
  • 00:05:31 and then we can just copy and paste that
  • 00:05:35 code down there and set it to chart down
  • 00:05:39 there so now we have these two buttons
  • 00:05:42 that allow us to toggle our state or to
  • 00:05:44 switch our state between list and chart
  • 00:05:46 and obviously you could add more buttons
  • 00:05:49 and a more different output types here
  • 00:05:51 if you have more I only need a list and
  • 00:05:54 chart and then in this death here which
  • 00:05:56 conveniently gets refactored to have to
  • 00:06:00 be a single tactic which I don't want in
  • 00:06:02 this death here here I now want to
  • 00:06:05 output ever my chart or my booking list
  • 00:06:07 so here it can check for this state
  • 00:06:09 output type if it is equal to list and
  • 00:06:12 if it is equal to list then here I will
  • 00:06:15 output my booking list component so the
  • 00:06:18 booking list component we used before
  • 00:06:19 with that I'm of course talking about
  • 00:06:22 that booking list jeaious file here and
  • 00:06:24 in that file don't forget we need to
  • 00:06:27 pass in our bookings as props to work so
  • 00:06:30 on this component here all set
  • 00:06:32 bookings equal to this state bookings
  • 00:06:36 now that is one possible outcome but if
  • 00:06:40 I selected a chart so if this year is
  • 00:06:43 chart and not list then I don't want to
  • 00:06:47 render the booking list but then I want
  • 00:06:49 to render my chart and of course we
  • 00:06:51 don't have that yet so here in the
  • 00:06:53 bookings I'll add a new folder bookings
  • 00:06:55 chart and in there I'll have my bookings
  • 00:06:59 chart such as file and in here and that
  • 00:07:02 bookings chart or chess fall all import
  • 00:07:05 react from react as we always need to do
  • 00:07:07 it in a functional component or an
  • 00:07:10 react component and I'll have my
  • 00:07:12 bookings charge constant here which
  • 00:07:16 receives props and which then should
  • 00:07:19 output my chart in the end or my content
  • 00:07:22 and I'll export this as a default and up
  • 00:07:28 there for now I will just return a
  • 00:07:30 paragraph where I say that chart and
  • 00:07:33 obviously will add a real chart there
  • 00:07:35 whoops and that should be a semicolon
  • 00:07:38 down there so now I have that bookings
  • 00:07:40 chart component in the bookings page
  • 00:07:42 here I will now render that bookings
  • 00:07:45 chart component and obviously I want to
  • 00:07:49 pass in my bookings here as well we're
  • 00:07:51 not doing anything with that prop in the
  • 00:07:53 bookings chart component yet but we will
  • 00:07:54 do something with it soon so you're all
  • 00:07:56 will pass in this state bookings and now
  • 00:07:59 we just need to import that bookings
  • 00:08:01 chart components so that we can use it
  • 00:08:03 as a JSX element in that bookings page
  • 00:08:06 so up here I can duplicate that booking
  • 00:08:09 list import and replace booking list
  • 00:08:11 with bookings chart because that then is
  • 00:08:14 the correct path to that folder and file
  • 00:08:16 and I imported with the right name so
  • 00:08:19 with all that added if we scroll down
  • 00:08:22 that is now our output down here we'll
  • 00:08:24 recheck for the output type and if I
  • 00:08:26 save this and I now log in here with the
  • 00:08:30 user who created events but doesn't
  • 00:08:33 really matter at this point I have no
  • 00:08:35 bookings therefore I don't see anything
  • 00:08:37 when I'm in list mode but if I click on
  • 00:08:38 chart we see the chart and if I go back
  • 00:08:40 to list we see nothing because we have
  • 00:08:42 no bookings yet and if I were to add one
  • 00:08:45 by logging in with different user a user
  • 00:08:49 who can book events here if I book
  • 00:08:52 forest hiking and now with the event
  • 00:08:55 being booked if I go now go to bookings
  • 00:08:57 I get an error cannot read property
  • 00:09:02 bind-off undefined yeah because I'm not
  • 00:09:06 passing in on the leat of course I
  • 00:09:09 should do that in my bookings page so
  • 00:09:12 there on the booking list I of course
  • 00:09:14 have to pass in the on delete prop and
  • 00:09:16 bind this to this delete booking handler
  • 00:09:20 like that and now if we
  • 00:09:23 try this again lock back in with the
  • 00:09:27 user with whom we just booked an event
  • 00:09:29 and I now go to bookings here is our
  • 00:09:31 booking again so this works and if I go
  • 00:09:33 to chart we see the chart to go back to
  • 00:09:35 the list we see that obviously styling
  • 00:09:37 of the buttons can be improved but that
  • 00:09:39 generally works
  • 00:09:40 now let's improve the visuals for our
  • 00:09:43 buttons here therefore in the bookings
  • 00:09:46 page and a component here I want to
  • 00:09:49 style my buttons a bit differently and I
  • 00:09:52 will outsource them into a separate
  • 00:09:54 component for that again in the bookings
  • 00:09:57 folder I'll name that bookings controls
  • 00:10:00 and you can name this Harbury you want
  • 00:10:02 as always
  • 00:10:03 so bookings whoops bookings controls j/s
  • 00:10:09 is the file I'll create and then I'll
  • 00:10:11 have the bookings control stud CSS file
  • 00:10:14 and now let's grab these buttons or
  • 00:10:18 actually we can take the entire death
  • 00:10:20 here and place that in our bookings
  • 00:10:23 control javascript file by first of all
  • 00:10:26 importing react from react of course and
  • 00:10:30 then we'll have our constant here
  • 00:10:33 bookings control receives props and then
  • 00:10:38 we render our death here and we export
  • 00:10:43 that as our default the bookings control
  • 00:10:46 so that's the bookings control now we
  • 00:10:48 can style this by giving by assigning
  • 00:10:51 some class names so here I'll have my
  • 00:10:53 class name booking stash control let's
  • 00:10:56 say and then we can select the buttons
  • 00:10:59 with the help of that class so here in
  • 00:11:01 the CSS file let's add bookings control
  • 00:11:03 and first of all I want to make sure
  • 00:11:05 that the buttons are centered so I'll
  • 00:11:07 add text-align:center here and I'll also
  • 00:11:11 add a little bit of padding let's say
  • 00:11:14 dot five Ram in all directions and then
  • 00:11:18 let's also select bookings control and
  • 00:11:20 then the buttons in there before the
  • 00:11:22 buttons I want to inherit the font that
  • 00:11:26 I have I also want to generally remove
  • 00:11:32 the border and set the background to
  • 00:11:34 transparent I was at the color too
  • 00:11:37 black but I also want to highlight which
  • 00:11:40 button is selected for dad I'll first of
  • 00:11:43 all give every button a pairing let's
  • 00:11:45 say top and bottom off touch 2 5 Ram but
  • 00:11:48 one Ram left and right and then I'll
  • 00:11:51 have my bookings control button with the
  • 00:11:53 active class added which I will have to
  • 00:11:56 add some code to add this
  • 00:11:57 programmatically and there I want to
  • 00:12:00 have a border bottom and for that to
  • 00:12:02 look good I'll actually set up order
  • 00:12:04 bottom here on the default style as well
  • 00:12:07 border bottom which will be let's say 2
  • 00:12:10 pixels thick solid but transparent so
  • 00:12:13 that we don't see it here but down there
  • 00:12:15 I will set the border bottom color now
  • 00:12:19 to my main color for that we can take it
  • 00:12:22 from the main navigation I'm talking
  • 00:12:24 about that purplish color here dad
  • 00:12:27 should be assigned when that tab is
  • 00:12:29 active so to say and the text color
  • 00:12:31 should be that same color so now we just
  • 00:12:34 need a way of controlling which button
  • 00:12:36 is active and for this I will add a
  • 00:12:40 class name here to every button but dad
  • 00:12:43 will be set dynamically and I will check
  • 00:12:45 props and basically check for active
  • 00:12:50 button let's say that is a or active
  • 00:12:53 type active output type baby active
  • 00:12:56 output type that is a prop I expect to
  • 00:12:58 get and this year can be list and if it
  • 00:13:04 is list and I want to assign the active
  • 00:13:06 class to that first button because that
  • 00:13:08 is my list button and otherwise all set
  • 00:13:11 this to an empty string so I will not
  • 00:13:13 assign any class name in that case and
  • 00:13:16 on the second button all do the same
  • 00:13:18 here I will add a class name and I'll
  • 00:13:24 check for a chart and if this chart I'll
  • 00:13:26 set this button to active and therefore
  • 00:13:28 it should get the right styling and our
  • 00:13:30 wise it receives no class and therefore
  • 00:13:32 should have no special styling that is
  • 00:13:35 it that allows me to hopefully mark
  • 00:13:38 these buttons as active or inactive now
  • 00:13:40 of course I don't have my change output
  • 00:13:42 handler in here anymore instead I expect
  • 00:13:46 to get some props here props
  • 00:13:50 on change maybe you can name as however
  • 00:13:52 you want and you still want to bind
  • 00:13:54 lists and charts to pass this selection
  • 00:13:57 mode on to the parent component which
  • 00:13:59 will set on change to a function
  • 00:14:01 reference and now I do have my bookings
  • 00:14:04 control one thing of course I should
  • 00:14:07 import my bookings control CSS file to
  • 00:14:12 apply the cells now let's go back to the
  • 00:14:16 the page to the bookings page here it is
  • 00:14:20 and let's first of all import our
  • 00:14:22 bookings control for that I just
  • 00:14:25 replicated this import up there for the
  • 00:14:27 bookings chart and now I'll use bookings
  • 00:14:30 control because that is my folder name
  • 00:14:32 and my file name in the same bookings
  • 00:14:34 folder bookings control can they offer
  • 00:14:36 now be used in that file in the bookings
  • 00:14:39 page here if we now scroll to the bottom
  • 00:14:41 here we can add bookings control not
  • 00:14:45 charge control and of course we need to
  • 00:14:48 set two properties here the two
  • 00:14:50 properties we use in bookings control
  • 00:14:53 the ActiveX output type and unchanged so
  • 00:14:57 let's make sure we set active output
  • 00:14:59 type and we set this to this out at this
  • 00:15:02 state output type here and on change
  • 00:15:05 should be set to this change output type
  • 00:15:09 handler with that we have bookings
  • 00:15:11 control in place and I just seem to have
  • 00:15:14 an import error here booking stir maybe
  • 00:15:18 of a maybe I have a type of somewhere
  • 00:15:21 bookings controls okay so I named that
  • 00:15:25 of course bookings controls so I have to
  • 00:15:28 adjust that folder name and that file
  • 00:15:30 name here and of course I also rename
  • 00:15:32 the JSX element here to bookings
  • 00:15:34 controls they are for down there in my
  • 00:15:37 JSX code I want to use bookings controls
  • 00:15:39 as well now this compiles and now let's
  • 00:15:43 log in with the user with whom we
  • 00:15:45 created a booking and that looks way
  • 00:15:48 better now and we can now switch between
  • 00:15:51 the buttons I want to get rid of that
  • 00:15:53 outline though so let's quickly go to
  • 00:15:55 the bookings controls CSS file and here
  • 00:15:59 on the button when it is focused I will
  • 00:16:03 set out
  • 00:16:04 – nan and I also saw that we can
  • 00:16:07 definitely increase the padding here
  • 00:16:09 let's say – freer em and now this looks
  • 00:16:12 better one thing I also want to ensure
  • 00:16:14 is that we have to rise right courser
  • 00:16:17 being used so a little set cursor –
  • 00:16:19 pointer on that button now we have two
  • 00:16:22 nice cursor here great so now we can
  • 00:16:25 switch between that we can toggle
  • 00:16:27 between our two different tabs here now
  • 00:16:30 for the chart we do have our list of
  • 00:16:33 bookings here and remember these are the
  • 00:16:35 bookings we made it's not the bookings
  • 00:16:37 for events we created you could add such
  • 00:16:39 a functionality but we don't have that
  • 00:16:41 here instead this is a list of bookings
  • 00:16:43 we made with that user with whom we're
  • 00:16:45 locked in and therefore what could we
  • 00:16:47 output here on a chart well we could for
  • 00:16:50 example simply to show you how you could
  • 00:16:52 add charts we could think in categories
  • 00:16:55 of events and with that I don't mean
  • 00:16:58 categories like adventure or dinner or
  • 00:17:01 something like that because we're not
  • 00:17:02 saving that in the database but instead
  • 00:17:04 regarding the price we could have free
  • 00:17:07 buckets
  • 00:17:07 let's say events that are cheaper than
  • 00:17:11 let's see which events do we have let's
  • 00:17:13 say cheaper than 100 cheaper than 200
  • 00:17:18 and more expensive than 200 well so you
  • 00:17:21 can of course add any buckets you want
  • 00:17:23 these are just buckets that fit the
  • 00:17:25 events I created here so that we can see
  • 00:17:27 something in a chart so these are the
  • 00:17:30 buckets we could create and then we can
  • 00:17:31 play around with the buckets to see how
  • 00:17:33 the chart changes and therefore let's
  • 00:17:36 first of all create the buckets and
  • 00:17:37 output some text before we then add a
  • 00:17:40 chart so let's go to the bookings chart
  • 00:17:43 component here before I return and JSX
  • 00:17:47 code i wanna well fill my buckets i want
  • 00:17:50 to create the output for these buckets
  • 00:17:52 for that all first of all add a constant
  • 00:17:56 here bookings buckets and that will be a
  • 00:18:01 javascript object let's say and I will
  • 00:18:05 have labels here as key names let's say
  • 00:18:08 cheap and here the border the upper
  • 00:18:12 border should be 100 dollars normal
  • 00:18:16 could be let's say
  • 00:18:17 up to 200 and then we have expensive and
  • 00:18:22 expensive we'll go up to let's say that
  • 00:18:26 a very high number which will not exceed
  • 00:18:29 with our events here and of course there
  • 00:18:31 are thousands of different ways of
  • 00:18:32 calculating that and of setting this up
  • 00:18:34 this is just one relatively simple
  • 00:18:36 straightforward example now remember
  • 00:18:39 that on the bookings charge component in
  • 00:18:42 our props from the bookings page we'll
  • 00:18:44 receive our bookings here we forward
  • 00:18:47 that to the bookings chart component our
  • 00:18:49 bookings prop so we get the bookings in
  • 00:18:53 the bookings chart component and
  • 00:18:54 therefore here we can now basically
  • 00:18:57 generate some output that takes these
  • 00:18:59 buckets into account now how can we do
  • 00:19:02 that we could add a variable or a
  • 00:19:04 constant here output and that is an
  • 00:19:07 array which is empty initially and then
  • 00:19:09 with a for in loop we could go through
  • 00:19:12 our buckets and simply generate a new
  • 00:19:14 row in a table to begin with for every
  • 00:19:17 bucket so for bucket in booking buckets
  • 00:19:23 we have a look at our bookings and see
  • 00:19:26 if we got any um bookings in there that
  • 00:19:30 are cheaper than that and then that and
  • 00:19:32 then that for every iteration so here we
  • 00:19:35 could have our filtered bookings in
  • 00:19:38 there in every iteration and I go into
  • 00:19:40 my props bookings so the bookings were
  • 00:19:43 receiving from outside and I want to
  • 00:19:46 reduce them to a single number because I
  • 00:19:48 want to find the amount of bookings that
  • 00:19:50 fit into that bucket so we'll reduce
  • 00:19:52 them and the reduce function or method
  • 00:19:56 takes a function as a first argument and
  • 00:19:58 a starting value as a second argument
  • 00:20:00 starting value will be zero and that
  • 00:20:02 function that is the first argument gets
  • 00:20:05 two arguments itself the first one is
  • 00:20:08 the previous value and the second one is
  • 00:20:11 the current value and this will execute
  • 00:20:13 for every element in our bookings and it
  • 00:20:16 will start with our initial value as a
  • 00:20:18 previous value and then look at that
  • 00:20:21 current element we got here in that
  • 00:20:23 array we're looping through and give us
  • 00:20:25 that on the current element and then we
  • 00:20:27 have to return a new value which will be
  • 00:20:29 passed it as a previous view
  • 00:20:31 you in the next execution so for the
  • 00:20:32 next element in this array and so on and
  • 00:20:35 therefore we can basically reduce the
  • 00:20:37 complex booking objects which have a
  • 00:20:39 title and descriptions on to just a
  • 00:20:41 number and that number also changes from
  • 00:20:44 iteration to iteration which allows us
  • 00:20:46 to calculate a total sum so here I will
  • 00:20:49 return previous plus one but only of
  • 00:20:52 course if the current element we're
  • 00:20:56 looking at has a price that is lower
  • 00:20:58 than our current bucket border so I will
  • 00:21:01 check if current price remember current
  • 00:21:05 refers to a booking and that booking has
  • 00:21:08 a price property if that is smaller then
  • 00:21:12 bookings bucket for the bucket we're
  • 00:21:15 looking at and bucket here simply is our
  • 00:21:17 label so cheap normal inexpensive so now
  • 00:21:20 we're looking at this object and there
  • 00:21:22 at the label cheap for example so the
  • 00:21:24 value for cheap will be 100 we see if
  • 00:21:27 the current price is lower than 100 and
  • 00:21:29 if that is the case then we know we want
  • 00:21:31 to return previous plus 1 else we want
  • 00:21:34 to return Caribbeans because then we
  • 00:21:36 don't change the count because the
  • 00:21:38 current element we're looking at does
  • 00:21:39 not have a price that is inside of our
  • 00:21:42 boundary here then we can actually
  • 00:21:45 change output here to an object magic
  • 00:21:48 makes more sense because 10 here for
  • 00:21:51 this iteration so outside of the reduce
  • 00:21:54 function but ends of the for in loop
  • 00:21:56 here I want to set output and then add a
  • 00:22:00 new property with the square bracket
  • 00:22:02 notation and that property will be
  • 00:22:04 buckets or the name of the property so
  • 00:22:07 that will be cheap normal and expensive
  • 00:22:08 and so on and I will set this equal to
  • 00:22:12 filtered bookings and maybe I should
  • 00:22:15 also name this filtered bookings count
  • 00:22:17 to make it really clear that this is
  • 00:22:19 just a number
  • 00:22:19 so now we'll add something like cheap 1
  • 00:22:23 to this object to indicate that we have
  • 00:22:26 one cheap element let's console lock
  • 00:22:31 that to see if that works so let's
  • 00:22:33 console.log output here and let me open
  • 00:22:37 a console and see if we get output that
  • 00:22:41 makes sense if I log in here
  • 00:22:45 bookings they go to chart um I got chips
  • 00:22:50 your normal zero expensive serum so I
  • 00:22:53 guess good news is that we did
  • 00:22:55 successfully at keys to our output bad
  • 00:22:57 news is that they're all 0 and we booked
  • 00:23:00 forest hiking and forest hiking
  • 00:23:02 definitely is a normally priced event so
  • 00:23:06 normal should be one not zero
  • 00:23:08 let me quickly check what's wrong here
  • 00:23:11 and we can actually do that together
  • 00:23:13 by diving into our source code here in
  • 00:23:16 the developer tools and then let me set
  • 00:23:18 a breakpoint here and go back to chart
  • 00:23:20 and now it is pauses and first of all in
  • 00:23:23 props we do get our bookings yeah and
  • 00:23:27 obviously my problem is I access
  • 00:23:31 bookings price that's wrong it would be
  • 00:23:33 bookings for a booking it would be in
  • 00:23:35 the event but here I won't find the
  • 00:23:37 price because I'm not fetching it so
  • 00:23:40 let's remove the breakpoint and resume
  • 00:23:43 and let's fix that error here by going
  • 00:23:47 back and in the bookings page where we
  • 00:23:50 do fetch our content there for fetch
  • 00:23:54 bookings for an event
  • 00:23:55 I want to fetch the price so we need to
  • 00:23:57 add this here for the data we're
  • 00:23:59 fetching and in the bookings chart when
  • 00:24:02 I'm going through all the bookings and
  • 00:24:03 I'm looking at a booking
  • 00:24:05 I shouldn't check current price because
  • 00:24:07 that will be the booking object but it's
  • 00:24:09 the event object inside of a booking
  • 00:24:12 that has the price so that is what I
  • 00:24:14 want to check so now let's try this
  • 00:24:17 again let's log in again here go to
  • 00:24:20 bookings to the chart and now we have
  • 00:24:23 normal one and now is I booked this
  • 00:24:26 again and I also booked the first one so
  • 00:24:29 go back to poking to the chart now we
  • 00:24:31 have normal free cheap one which makes
  • 00:24:34 sense because I added two more bookings
  • 00:24:35 of the forest hiking and one cheap
  • 00:24:38 booking so now we can see that here we
  • 00:24:42 also see that expensive is added and
  • 00:24:45 that is a bug in our code of course
  • 00:24:48 expensive should be zero but for the
  • 00:24:50 code we wrote here it actually makes
  • 00:24:51 sense that I added expensive as well
  • 00:24:55 because when I go through that well
  • 00:24:58 the safe check checks only if the price
  • 00:25:00 is lower than the bucket border now of
  • 00:25:02 course a cheap event the price of that
  • 00:25:05 is lower than normal and expensive as
  • 00:25:07 well so we add a cheap event to all free
  • 00:25:10 buckets so we have to refine our check
  • 00:25:13 here a little bit and actually not just
  • 00:25:16 store a number in here but have a min of
  • 00:25:19 zero and a max of 100 let's say and add
  • 00:25:23 that for all three buckets here we have
  • 00:25:25 a min of 100 and a max of 200 and then
  • 00:25:29 for expensive we'll have a minimum of
  • 00:25:32 200 and a maximum of a really big number
  • 00:25:35 and now here we can adjust this and we
  • 00:25:38 can check if the current event price is
  • 00:25:42 greater than our bookings pocket and
  • 00:25:45 therefore the bucket we're looking at
  • 00:25:47 the minimum there and if it is lower
  • 00:25:50 than the maximum we can now access dot
  • 00:25:54 min and tot max because now the value in
  • 00:25:56 our booking bucket array object here is
  • 00:25:59 not just a single number but an object
  • 00:26:01 with a min and Max key that is just what
  • 00:26:03 I'm accessing down there so let me save
  • 00:26:07 that and let's now reload this and see
  • 00:26:09 if that now behaves as it should
  • 00:26:12 bookings chart cue cheap and one normal
  • 00:26:17 priced event dinner in the dark and
  • 00:26:20 first hiking yeah makes sense
  • 00:26:22 my explanation pretty what's wrong I did
  • 00:26:24 add two cheap ones and one expensive or
  • 00:26:27 a normal priced one now in the mean time
  • 00:26:30 I added a couple of bookings here and I
  • 00:26:32 noticed add we have a box somewhere in
  • 00:26:34 our bookings logic I'll fix that in the
  • 00:26:37 next video in this series for now let's
  • 00:26:40 just accept it so I booked events here
  • 00:26:43 and sometimes different events are
  • 00:26:46 actually booked or are actually
  • 00:26:48 retrieved we'll look into this now what
  • 00:26:51 matters here is that we do have
  • 00:26:53 bookings and I therefore get my chart
  • 00:26:55 data here now this is the chart data for
  • 00:27:00 the bookings I have I have two cheap
  • 00:27:02 ones these are the two dinner in the
  • 00:27:03 dark I have here I got a 5 sailing
  • 00:27:06 introductions which are the expensive
  • 00:27:08 ones and I got free forest hiking's
  • 00:27:10 which are the other ones
  • 00:27:11 now my goals to chart them before we fix
  • 00:27:14 that bug now if you google for react
  • 00:27:16 charts you'll find many results I will
  • 00:27:19 use react charts
  • 00:27:20 chassé which is a react wrapper around
  • 00:27:22 the chart chaser library which works
  • 00:27:24 with any framework or none at all
  • 00:27:26 now this supports line charts bar charts
  • 00:27:29 and zhan and you can dive into chart
  • 00:27:31 jazz documentation to learn all about it
  • 00:27:33 also into these examples now let's
  • 00:27:36 install it with this command and for
  • 00:27:38 this I quit my front-end development
  • 00:27:40 server to run install NPM install safe
  • 00:27:43 react chart j/s and as it also mentions
  • 00:27:47 here we need react to react Dom well we
  • 00:27:49 got that but we also need to install
  • 00:27:50 chart Chasse
  • 00:27:52 so the package which gets wrapped by
  • 00:27:54 react chart Chasse
  • 00:27:55 so let's add that as well and now with
  • 00:27:58 that installed and with the wrapper
  • 00:28:00 installed we are ready to use it so once
  • 00:28:04 this finishes we can restart the
  • 00:28:06 development server here with NPM start
  • 00:28:09 like that and now to build a chart we
  • 00:28:13 can actually follow the examples here
  • 00:28:15 and I want to build a bar chart so where
  • 00:28:19 I simply have a couple of bars for my
  • 00:28:21 different categories for this let me go
  • 00:28:24 to the bookings chart component excuse
  • 00:28:28 me this one here and let's import and
  • 00:28:33 now you can also see this new official
  • 00:28:34 box with different import syntax but
  • 00:28:36 we'll basically import bar chart from
  • 00:28:44 react charts chassé and that should give
  • 00:28:48 us access to this bar chart JSX element
  • 00:28:51 now how do we render that well in the
  • 00:28:55 place where currently up a paragraph I
  • 00:28:57 now render my bar chart and now that bar
  • 00:29:00 chart can take an options prop and all
  • 00:29:03 that data prop and that data prop should
  • 00:29:05 be data formatted as required by chart
  • 00:29:08 chess so you can check the official
  • 00:29:10 Doc's here to learn more about it for
  • 00:29:12 the bar chart in our case and you see
  • 00:29:15 that data should be an object with some
  • 00:29:17 labels so basically the labels at the
  • 00:29:19 bottom of our x-axis and then the data
  • 00:29:21 sets for the different data sets we want
  • 00:29:25 to render
  • 00:29:25 along our bars so let's copy that object
  • 00:29:29 here and then let's adjust it to our
  • 00:29:31 requirements of course I so down there I
  • 00:29:36 will prepare my charge data and that
  • 00:29:40 will be that object I just copied but of
  • 00:29:42 course we now need to adjust it
  • 00:29:44 instead of January February and so on
  • 00:29:46 the labels will be our bucket keys here
  • 00:29:51 right so it seeped normal and expensive
  • 00:29:53 and therefore we can loop through them
  • 00:29:56 now we can't reorder we don't really
  • 00:29:59 want a hard code our data in the chart
  • 00:30:01 data here though instead we want to
  • 00:30:04 generate this dynamically when we're
  • 00:30:05 going through all our chart buckets and
  • 00:30:07 this foreign loop here and when we're
  • 00:30:09 calculating how many items we have per
  • 00:30:12 bucket so therefore I will actually set
  • 00:30:15 chart data I will treat it up here
  • 00:30:18 or I will actually use output and rename
  • 00:30:21 this to chart data and we'll start with
  • 00:30:22 an empty object and we'll generate this
  • 00:30:24 charted object dynamically whilst we're
  • 00:30:26 going through our foreign loop so here
  • 00:30:29 instead of setting output bucket all set
  • 00:30:32 chart data labels that will be an array
  • 00:30:35 and therefore up here I will actually
  • 00:30:39 initialize this to have that labels
  • 00:30:40 array which is an empty array up there
  • 00:30:42 before we go through all our elements
  • 00:30:44 and then we'll have our data sets array
  • 00:30:51 in here which also will be an empty
  • 00:30:52 array initially and will populate this
  • 00:30:54 in the foreign loop now so labels there
  • 00:30:57 I will push bucket as a new label so the
  • 00:31:00 bucket we're currently looking at and
  • 00:31:02 remember bucket is the key name here in
  • 00:31:04 this foreign loop so this will be
  • 00:31:05 something like cheap normal or expensive
  • 00:31:07 and then I also want to push something
  • 00:31:11 into my data set so I want to push a new
  • 00:31:13 object in there and that object should
  • 00:31:16 look like that here so here I will add
  • 00:31:20 my label I don't really need that fill
  • 00:31:24 color and so on I will use the default
  • 00:31:26 one here for all my buckets for now and
  • 00:31:28 then data will only have one data point
  • 00:31:31 here now in theory data's build such
  • 00:31:34 that you can have one data set as the
  • 00:31:36 name it here and this can hold
  • 00:31:38 data points which go into different
  • 00:31:41 parts of the so in different columns you
  • 00:31:44 render in the end so you might have like
  • 00:31:46 seven columns and you want to render
  • 00:31:48 your data points into all seven here and
  • 00:31:51 then they would have the same color
  • 00:31:53 across all columns now for the bar chart
  • 00:31:56 I'm creating here will only have one
  • 00:31:58 column per label so per section on the
  • 00:32:03 x-axis basically and therefore each
  • 00:32:06 column will be a will only hold one data
  • 00:32:09 point here so here our data point will
  • 00:32:14 only be one data point as I just
  • 00:32:15 mentioned and that will be of course our
  • 00:32:17 filter bookings count so I will add that
  • 00:32:21 here as data and now we're generating
  • 00:32:25 chart data and the data sets into labels
  • 00:32:27 dynamically so we can get rid of it down
  • 00:32:30 here and now simply pass our dynamically
  • 00:32:35 generated chart data as the data to bar
  • 00:32:38 chart let's see what that gives us if
  • 00:32:40 that works if we go back here and we log
  • 00:32:43 in with our user we submit this and go
  • 00:32:46 to bookings a chart this crashes yeah my
  • 00:32:51 bad
  • 00:32:52 here we ran import bar bar chart
  • 00:32:56 it's just named bar actually not bar
  • 00:32:58 chart but I can import this as a bar
  • 00:33:00 chart so I can give it an alias to use
  • 00:33:03 it under a different name
  • 00:33:04 so let's import bar as bar chart from
  • 00:33:07 react chart chess and then let's have a
  • 00:33:12 look at this again under bookings chart
  • 00:33:15 and that looks some okay but they're all
  • 00:33:19 rendered in the same area now so we have
  • 00:33:23 cheap normal and expensive which looks
  • 00:33:25 good but everything gets rendered and
  • 00:33:26 cheap the general values here are the
  • 00:33:29 right ones though but what can we do
  • 00:33:31 about that well the problem is here my
  • 00:33:36 foreign loop I push new objects in there
  • 00:33:39 but the default behavior is that here
  • 00:33:42 data every element in here belongs to
  • 00:33:45 one of the columns our rendering now
  • 00:33:47 since I have free labels because I have
  • 00:33:49 three buckets which I push into the
  • 00:33:51 labels array
  • 00:33:52 we'll have three areas in the chart
  • 00:33:54 which you can see here cheap normal and
  • 00:33:55 expensive this is how the labels work
  • 00:33:57 they generate these areas in the chart
  • 00:33:59 into which we can render it and then
  • 00:34:01 every data point we have down there
  • 00:34:03 belongs into one area now since for
  • 00:34:05 every bucket were looping through we're
  • 00:34:08 only adding one data point this all goes
  • 00:34:11 into the first area we created the idea
  • 00:34:14 of course is that for the first element
  • 00:34:16 so cheap we want to have just one data
  • 00:34:20 point here in the first element but for
  • 00:34:22 the second one normal we want to have
  • 00:34:25 zero and then our filter bookings count
  • 00:34:28 and for the third one expands if you
  • 00:34:30 want to have zero zero and the filter
  • 00:34:32 bookings count so how can we get there
  • 00:34:35 well we just need to generate data in a
  • 00:34:38 bit of a more elaborate way we can
  • 00:34:40 create a new constant values which is an
  • 00:34:43 empty array initially here and when
  • 00:34:48 we're going through all our buckets here
  • 00:34:50 and we're calculating the value for
  • 00:34:52 every bucket I will set values or I will
  • 00:34:57 access values and Porsche my filter
  • 00:35:00 bookings count onto it so initially it's
  • 00:35:03 empty after a first round it has the
  • 00:35:05 value for the first bucket and so on and
  • 00:35:07 then I use that down there as my array
  • 00:35:09 so my values but after I assigned this
  • 00:35:13 here all set values equal to a copy of
  • 00:35:18 values and therefore of course that
  • 00:35:22 should not be a constant but I have let
  • 00:35:24 as a keyword so to copy it so that
  • 00:35:27 whatever I do now with it doesn't change
  • 00:35:29 the values array I assigned here because
  • 00:35:31 it's a reference type by default so I
  • 00:35:32 copy all my values here and then for the
  • 00:35:36 copied values I'll access the last
  • 00:35:38 element which I get with values length
  • 00:35:40 minus one so the element that just added
  • 00:35:43 basically and I'll set this to zero so
  • 00:35:45 that after the first iteration values
  • 00:35:48 will basically look like this before I
  • 00:35:51 do that values will look like this
  • 00:35:53 holding the amount of items I have for
  • 00:35:56 this bucket then I reset this to zero so
  • 00:36:00 for the next iteration we start with
  • 00:36:02 values having one element which is zero
  • 00:36:04 we then portion ul
  • 00:36:06 so for the second iteration values will
  • 00:36:08 look something like this and then after
  • 00:36:11 storing that I will reset it so for the
  • 00:36:16 third iteration we start with two zeros
  • 00:36:17 and so on so for that let's see if that
  • 00:36:21 works as it should if we now save that
  • 00:36:24 and I try logging in here I go to my
  • 00:36:28 bookings and there to the chart this now
  • 00:36:31 looks better and now I have my three
  • 00:36:34 different areas here or my three
  • 00:36:36 different columns being rendered in the
  • 00:36:38 different chart areas and that of course
  • 00:36:41 is just the output type I want to use
  • 00:36:43 here you can of course style this
  • 00:36:46 differently look into the chart is
  • 00:36:47 documentation to output this in a
  • 00:36:50 different way in a different chart
  • 00:36:51 whatever you want now reminding thing
  • 00:36:54 I'll do is I want to Center that chart
  • 00:36:57 and that is really easy to do in my
  • 00:37:01 bookings chart j/s component I can
  • 00:37:05 simply wrap my chart here in a death
  • 00:37:09 like that and then simply Center that
  • 00:37:13 and I'll do this quick and dirty here
  • 00:37:15 with inline Styles by setting text align
  • 00:37:21 to Center of course you can do this with
  • 00:37:24 a CSS file as well and now if I log in
  • 00:37:27 here and I submit this and I go to
  • 00:37:31 bookings that is my Center chart now as
  • 00:37:34 I mentioned there is an an error there
  • 00:37:36 is a bug in our application when it
  • 00:37:38 comes to booking events somehow wrong
  • 00:37:40 events are booked and I'll have a look
  • 00:37:41 at this in the next video which should
  • 00:37:45 then be the last video of this project
  • 00:37:47 series because obviously there is way
  • 00:37:49 more you could add way more you can
  • 00:37:51 configure style and build but this is
  • 00:37:53 already quite a long serious and we
  • 00:37:55 added a bunch of different things but I
  • 00:37:58 will round it up in the next with you
  • 00:38:00 I hope you enjoyed this one where we
  • 00:38:01 added this nice chart