FlutterFlow Custom Widgets: COMPLETE TUTORIAL (2023) | FlutterFlow Basics

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we're going to be talking about what I think is one of the most powerful features of flutter flow and that is custom widgets so we are going to be covering everything that you need to know when it comes to custom widgets and by the end of the video You're Gonna realize why first of all custom widgets are super powerful and they help you build incredible customizable and unique apps but also you will know exactly how to do all of the above not only will you know how to build simple custom widgets to customize a little things about your app but you will also know how to build more complicated custom widgets and also how to use the power of chat the GPT to help you build even more powerful custom widgets now before we get started as always all the videos that I publish on this channel you can view and or clone them from my patreon page so that's something you might be interested in check out our patreon community at the link just below the video now first let's talk about what exactly are custom widgets what is their purpose why do you need to know them and how can they help you well in order to understand that the first thing that you need to realize that everything that you see in a flutter Flow app is a widget so for instance here we are on flutter flow's home page and you see this animation here where they're showing you how you can build your apps and really what kind of apps that you can build and so this is a perfect example as any because everything that you see in the app builder as well as in the final version of the app are widgets right so this page is a widget this whole page is a widget and all the little elements are widget right this is a text widget this is a car this is you know another text widget another text widget this is a chart which uh we have another text widget we have another like an arrow which is a type of widget so you have kind of these bigger widgets right so if you think about this whole page this whole screen the canvas that is a widget and then you have smaller widgets that are children of these bigger widgets right so you have this kind of you know parent to Children relationship right that is the most fundamental thing that you need to understand when it comes to building flutter flow apps because everything after that is going to be a lot easier and a lot simpler to grasp once you understand how everything is built okay so everything right all the images the video as well as if you go into flutter flow itself right if you click on it here right so we have our Builder let's say I want to add a new widget right all of these are widgets right but the big difference is that these are built-in widgets so these are essentially widgets that flutter flow has built for you that you don't need to build yourself so here I have a page and you know let's say you know the name of the page is page one this is our first page and I want to you know maybe have an image right well it's very very easy I can just add a child and just search for image add an image I can you know change the width I can make it bigger I can Center it you know using the parent Widget the column you know is the parent widget I can Center it um vertically but this is a widget that has been provided to us by flutter flow and remember uh I talked about parent child relationship right so we have this image that we just created but the parent is the column and then the page is the columns pair which is kind of like the grand parent if you will of this image okay so here what you're essentially doing when you're building apps is you're essentially using built-in functionality that was that has been graciously provided it to you by Florida phone that is why we use a lot of floor but there are some situations in fact there are many situations I can think of where you know the built-in functionality the built-in widgets that flutterflow provides you are not enough right maybe you want to customize them something that already exists or maybe you want to create something new all together in these cases um you need to go out and create custom widgets okay so I'm gonna be giving you several examples from simple to more complicated and you're gonna see exactly how you can go out and build your own custom widgets depending on what kind of custom widgets uh you're looking to create basically what kind of functionality you're after Okay so let's get started with a very very simple example so I have this page one and so I'm going to delete this image and this is my kind of scaffolding right I have the page ready I have page one I have a column and before or I can actually you know place this custom widget on my page I need to go on create it so I'm going to go to custom code which is on this left hand panel here and what I'm going to do is I'm going to add the new widgets I already have some widgets created that I'm going to be showing you a little bit later in the video but first I want to show you how to create one yourself so we're gonna come here we're gonna pick widget and now we have a widget I'm just going to call it widget one you can call it whatever you want now an important thing that I have to say here at this stage is that when you're building custom widgets you are kind of going into an area where the rubber meets the road okay so when we're talking about you know no code or low code and all of these tools well depending on the tool you know you may never need to write code but flutter flow is more of a it's a no code tool but it also has low code functionality and also has you know coding functionality and so when you're creating a custom widget you're actually look talking at the code that's being generated because when you're creating an app right this app here uh you may not you may never see the code that's being generated right but there is code that's being generated underneath but unless you're actually you know creating custom widgets and other you know functionality you may never actually see the code that's being generated and that's fine right that's kind of why we're here uh we want to build apps without seeing the code but in this example we have no choice but to actually see the code because when we write custom widgets we have to code something and depending on the type of functionality that we want to implement you know we may need to code just a little bit or we may need to code a lot and so but it's important for you guys to follow the steps here uh exactly because if you don't you're gonna have some issue so after you you give it a name the next thing you want to do is you want to click here right and when you click here you are essentially given the screen and there's some code here and and you can kind of ignore this code what's important is that you have this boilerplate widget code and you can just copy to editor right now we have a scaffolding a boilerplate of custom widgets and this is enough right this is enough we have a custom widget right now we didn't write any code we didn't write you know a single line of code all we did was uh give it a name and then we clicked here and then we just said copy to editor and that's it and now we have a custom widget okay so what does this custom widget do well let's go see I'm gonna say say and you can kind of ignore this right now right you can kind of ignore this message you can just press uh press yes and now we've created a custom widget so what I'm going to do is I'm gonna go back to the UI right I'm gonna go back to the part that you're typically interfacing with interacting with and so what I'm gonna do is I'm gonna press here instead of picking a built-in widget I'm gonna go in here and I'm gonna pick the widget that we just created so I already have a bunch of other widgets but if you're just creating this widget here you're just gonna have this widget one so I'm going to click widget one and this right here Place folder for visual one please try compiling okay that's fine the next thing that you want to do is you want to give this widget a width and a height so I'm just going to do 300 and I'm going to do a 300 and 300 pixel height and now we have the second also Center how do I do that well depending on how I have it set up right now this is a child of column and what this means is that I can Center it vertically right columns uh they align elements vertically and this is already centered vertically because if I click on column and I come in here we have this main axis alignment which is vertically uh and it's already centered I can also have it you know aligned um to the top I can align at bottom or I can center now if I want to center it horizontally I have to wrap this inside of a row so what I'm going to do is I'm going to right click I'm going to say wrap widget and I'm going to say row and now we have this row here and now I can click on this row and I can Center this I can do it like this right like this doesn't really matter we only have one widget and now this widget is centered both horizontally and vertically okay now there are two problems right now the first one is that I'm not seeing the widget and that is because I haven't compiled it right remember we are doing a little bit of coding here even though we haven't written any code just yet there is code behind this custom wood is this telling us please try compiling and previewing again it again so what I'm going to do is I'm going to click on this red you see I have a project issue and I'm going to click here and that's gonna compile it so it's already compiling it and this is and because this is a standard kind of code that we were given you we're not going to have any error messages here we haven't written any codes so we haven't had a chance to um to have errors yeah okay so we're gonna wait a few moments for it to compile right here it's compile it now all right so it finished compiling and as you can see it says no errors okay if there was an error this would be red and there you know it would tell you what kind of error you have and where's the error but right now this custom widget that we pasted uh there's no error so we can go back to the UI this is the page and now this is our widget and it's not displaying the that those instructions that it had before that we need to compile and except we're not seeing anything here we're not seeing it even if we were to run this app and I can do that right now so I can actually run this app for you guys just so that you can you can see for yourself what's happening right now so let's go ahead and create our test environment here all right so we finished compiling this is our app running exactly how our users would typically see and as you can see we're not seeing anything there's nothing on the screen it's as though we haven't really done anything when in fact we do have a custom widget here and the reason we're not seeing anything is because this custom widget is actually not doing anything so if we go back right we go back to our custom widget we go here what the switching is doing is you should be looking in this area right here you see this build this is a build method a build function whose job it is whose aim it is is to actually build the widget and to display it on the screen to return something that will be displayed eventually by the app and what it's doing is it's returning a container and the container is just another widget that can contain something and so what you need to do is you need to make sure that this container actually has a child and the child actually displays something so let's create a child element that will display some text so we can begin by typing child and then we're gonna say text okay and now we can actually display something that you know will be text based that you're gonna see on the screen so now it says you know we have a container it has a child remember I talked about the child parent relationship where some widgets can have one child some witches can have multiple children and some witches cannot have children at all right in this case a container can have one child the role can have multiple children a column can have multiple children and then a text really doesn't have any children right it's just a text okay and so right now if we preview it we should see armor custom widget and what I'm gonna do is hit save right here okay we should also compile it again and you need to do this every time you change your code because flutter flow needs to make sure that you haven't made any mistake it needs to make sure and you know it's a good idea for it to tell you sooner than later so it's better for it to tell you now than later when you're running your app or you know when you've given your app to your users okay so we're gonna wait for it to finish compiling all right so it finished compiling there are no errors and now we can go back to the main page and we should see some text as you can see it says I'm a custom widget if we go back to our test uh test environment here and we reload it we should see the same thing okay so now instead of having you know being kind of a blank screen we are seeing I'm a custom widget okay and so what's happening now is that a lot of flow build this whole app for us but it also built a custom widget that we built ourselves okay obviously you know for this for something simple like this we can obviously use flutter flow right because you can come in here and you know you have this custom widget but you can also add a text to it right so now you have a text widget you know you can arrange it however you want which would do exactly the same thing as what we've just done and so in these kinds of situations you obviously are not going to build a custom widget that just prints does something simple but I wanted to show you guys so that you guys understand how it starts right you still need to know the basics before you can advance uh to the more complex things okay so I'm gonna delete that so that was our custom widget that does something very very simple and now let me show you some examples where we can do more complicated things and you can go as far as you want and I'm going to give you kind of the blueprint for you guys to go and build you know uh custom widgets that are as complicated as uh your app needs them to be okay so here I have another page and here I have a button that does something very very interesting so if we go back to our app and let's say we reload it again just for good measure okay so this is our main page here with the simple which is let's go to the second page and now we have about but it's more than just a button if I click on it we have some text displayed and what's gonna happen is going to toggle it right so I can toggle it click on it toggle it click on the toggle it so let's take a look how this was built if we go back here we go um to the second page we're displaying the second widget we're gonna go to our widgets coming here and we have a widget that's slightly more complicated okay and what exactly is this what you're doing well when you want to see what is doing you need to find this build method you're going to start at the state right here you see the state you have two classes typically you're gonna have to class you're going to have your widget class and you're gonna have the stateful class the state class and the the purpose of that class is to build the widget in response to a change of state and what is the state well something change in your app something change in that widget we're going to be rebuilding the widget that would that's what makes uh flutter and flutter Flow by extension uh very much in demand is that they're reactive right we have state that changes the user does something and that rebuilds the widget and so if you take a look at this right here we have the state we have a build and we have children and then what we are using is we're using an elevated button which is just a type of button and then that button has a method called unpressed and so when you click on that button this function here this this code you know this code inside of this function here gets executed and in this case we just have very very simple State just keeping it very very simple simple and we have just one variable called the Boolean and if you've used flutter flow you know you can create app State you can create page State same thing this is exactly the same thing and in this case we have a Boolean show text by default is false and that is why when you start it you're not seeing any text because it's false and so by default this false but when you click on it it reverses the value it flips the value so if it's false it becomes true if it's true it becomes false this is what this line does and then we have this extra text right we have this extra text and so we have a statement here if show text and this means if show text is true right so if it's true display this and if it's not true this is not going to get X okay and so in the result we're seeing this right it starts off like this and if we click on it this becomes true remember we executed this it flips the value toggles the value so it starts off at full as false uh when we click on it it becomes true and then this bottom text is this play this text just below the widget is displayed so a very very simple example just you know but a little bit more complicated than the previous example and you know you can you can take it as far as you want right you can make it as complicated as you want okay so let me let me keep going let me show you some more exam now in this next example I am using the so-called third-party packages okay so flutter and flutter flow has built-in packages especially flutter they have a lot of built-in widgets that you can use built-in buttons built-in Tech but you know people can also create their own components right and so if you head over to a site called pub.dev you have access to a ton of other third-party packages that do a ton of amazing things like all kinds of packages that do all kinds of different things that you can Implement and integrate in into your own flutter Flow app okay so if you come over here you can search for specific packages if you want but if you scroll down you can take a look at what kind of packages they have right so they have a lot of favorites most popular packages and you know some of these packages are just gonna be just kind of under the hood things meaning that you're not gonna see them right so maybe it's something about connection or you know handling requests or something like that you're not gonna you're never gonna see them right but a lot of them are also going to be widgets that you see that you can interact with right so as an example if you come over here you have top flutter packages right you have a rating bar a simple yet fully customizable rating bar for flutter which also includes a rating bar indicator right so this is a widget this is not a widget right this is a composable multi-platform API for HTTP request this is more for coding right this is not something that you should be concerned right now so if you scroll down you're gonna see all these different packages all of these different things and one package that I wanted to kind of use was a package that displays a video right a custom widget that displays a video and also lets you play a video as well and so if you search for video or like video player you're gonna see it so let's say I type video player here you're gonna see well we have a video player here right and that's obviously a widget because it's it's viewable right it's it's presentable you you're gonna be interacting with it it's not some library that you know is going to be doing something under under the hood right this is going to be something you're going to be interacting with right and so I opened this one up and this is the page that we have right now once you've located the kind of package you want to be using as a custom widget uh you want to pay attention to kind of you know more information about it right because you know this is a open platform right they're gonna be you know custom widgets that do amazing things that are very very popular that are frequently you know maintained updated things like that right but they're also going to be other widgets that are really not used by people they may have bugs or people haven't updated them or you know maybe other issues as well right just like with anything else and so so the next thing you want to take a look at is these things here right the amount of likes uh the number of Pop points and the popularity right and this is like you know the more people are using it right the more people are using the these specific widgets in their own apps the better it is going to be for you right so for instance this has a lot of likes this is relatively it's a high number right so anything more than like a thousand two thousand that's a lot on this platform and it also has 140 pop points but the most important thing is it has a hundred percent popularity all right so what this means is that this is kind of the default uh the standard right the standard I would say like or one of the standard video players on pop.dev and so what this means is that um it's it's a highly maintained plugin uh people are working on it it's it's been updated for all the the new flutter versions etc etc and and you know in in in in simple terms when you use something like this that has a lot of these high high numbers and you know this pop its popular high popularity ratings you're gonna be you know there's going to be less hassle uh to to implement that right and so the next thing you want to scroll down kind of get an idea what the specific widget is doing and this is a video player right now flutter flow has their own built-in video player but if they didn't this is what you would be doing right you would you know be looking for a third party video player right so you can kind of scroll down you can get an idea what's happening and now let's say you want to implement this specific plugin in your app how would you do that well let me show you exactly how you would do that the first thing you're gonna do is you're going to go back to your app and you're gonna say add you're gonna do custom widget you're gonna give it a name so let's say we call it video player which next you're gonna click on this button and it's actually telling you boilerplate code using the button on the right actually telling you copy to editor and now you have your empty canvas so to speak you have your beginning you have your starting point okay now what do you need to do next next you're gonna go to the widget that you pick and you may go to like a little example right so if you go to read me that they typically have examples on the bottom and when you see this code the quick and fast rule is that you want to copy everything below the state so we're going to ignore all this because we already have that but if you copy all of this here all the way to the bottom you copy this and you come in here you go back to your app here and then you select all of this inside uh just below this line that has State and you paste it now once you've pasted this code there's two more things that you need to do okay the first is that you need to get this dependency right remember this is a piece of code that somebody has built and you don't have it right so you need to solve Florida flow that we are using this code it's one thing to kind of copy the code but you also need to uh point it so that it gets the actual library that it's using it right so what you want to do is you want to come in here and you can just hop hover over this and you can just click on it that copies the dependency you're going to go back to your app and you're going to say add dependency you're going to paste it here there's one more thing that you need to do and that is if you scroll back to the example you see it says here um import package flutter material do not worry about this first line whenever you see import package and what typically is going to happen you're it's going to be the same package so like video player forward slash video player.dart or you know music player forward slash music player.dart it's kind of a quick and fast rule you can copy this right here and just this line right here copy that Ctrl C go back and you want to paste and you want to paste it right here now once you've done that you're gonna have a widget that looks something like this so I already did this and this is the widget that you're gonna have and what's cool about it is that you can actually preview it right now so all you have to do is click here and you can preview this widget you can make it with it's a little bit bigger height a little bit bigger and you have the preview now this is not functioning you still need to compile it but at least you kind of see what the widget looks like in its kind of initial State nothing is going to work it's not going to play anything nothing nothing is clickable because we haven't compiled the code we're just kind of viewing the initial State and so in this case what you want to do is you want to go back to your widget right we're going to go to this editing screen we're going to hit save next you're gonna hit compile code you're gonna wait a little bit when it's done you're gonna see no errors and everything should compile perfectly if you follow the direction and now you can go back to your app here to the UI this page and include this widget so I already have it included but if I had to do it from the beginning I need to pick a place I'm going to pick a place where I want to insert it so let's say here I'm going to come here and I'm gonna pick this is widget three and this is the widget so I can make it a little bit bigger make it a little bit bigger okay and so now if we refresh our app or create a new session when a session expires we should have a custom video player that we can use in our apps all right so here's our app let's go ahead and take a look at that custom widget and this is the custom widget that we've just created using the help of a third-party Library so we can actually play right so we can do that you see it's actually playing this video and you might be wondering uh what video is it playing well it's actually very very simple if you go back to our custom widget here and we go back to the code it's actually loading up a sample video file okay it's loading up the sample video file now it that's not going to be very much useful for us to play like a random video file like to to you know to play a video file of a b that's kind of um buzzing around right well thankfully we can also include our own custom arguments we can pass them into a custom widget so we can pass all kinds of you know interesting arguments that we might need for the custom widget to have so how do we do that well that is actually really also very very simple and the way you do it is you go back to the custom wizard that you you want to add custom arguments to and you want to click on here add a parameter so we're going to say add a parameter and we're going to say well we want to pass like a custom URL to play or something like that and you want to say string and you're going to say uh custom URL this is what we want to call it now we're not done here yet okay you want to click on this thing here on the boilerplate button here and you want to see how this is actually done so you see right now we have this key width height and width and height but when we add this here if you click here you're also going to see custom URL that we've just added add it to the code so what you need to do guys is because we already have the code we can just paste this boilerplate over our custom widget that's just going to override it and that that's not going to do us any good what we need to do is we need to take a look and see how it's done here okay so you see how it's after height and this is also After High so now I can go back and I can just type it in myself this custom and same thing here final string custom Europe now after you've added those parameters we're not done just yet we need to link the parameter to the actual video that's being displayed you see this is the video that's being displayed this is that video of the B buzzing around but this is our parameter here so what we need to do here is it says Network what we're going to do we're gonna say widget dot custom URL okay that's all you need to do and now we can delete this thing here and now instead of just displaying a random um you know buzzing B video whatever that was hard coded there it's gonna display the URL that we specified uh dynamically right and so what this means is that we can essentially send a unique value from our app to be displayed by the custom widget that's exactly what you need to do right there's no need to display like a random hard-coded you know URL well over you know video would be buzzing around you want something that you're gonna be supplying as part of your app if we go back to our UI we go back here we come back here and let's say we want to add this widget here so I already have it added but let's say I was adding it uh from scratch I would just click a plus click here and select widget three in this case okay and now we have this widget I'm going to give make it a little bit bigger like a width of 300 height of 300 and now in addition to these two properties here right that we're passing this height and width we also have this custom URL that we can pass as well and so if you have a video or something uh you can pass you know a link to a video that will be playing something so here we are on pixels.com we can find a a video that we may want to show as part of our our custom widget and so we can just click here copy video address double check and we have a video here okay so if I come in here and I take this URL of this nice video video we can paste it in here we can run our app reload our test environment go back to the page that has the widget and now if you reload the app we can see that we are now viewing the video that we supplied and we can actually even play the video and as you can see the video is playing and this is by creating a custom argument we are we are passing a custom URL of the video that we want to play to our custom widget pretty cool I would say now in this last example that I want to show you you can use amazing tools such as chat GPT to help you build your own unique custom widgets so let me show you exactly how you can do that well the first thing is that you're essentially going to go in here you're gonna say uh widget you're gonna click here you're gonna give it a name maybe chat GPT widget as an example you're going to click here copy to editor and you have this the next thing you want to do is you want to go to chat gpta and you can type a prompt such as this one one generate a flutter widget that rotates a box as an animation just generate the widget code without scaffold or app okay so you can use a prompt such as this one you can just replace this part here with whatever you are looking for and if you do that you're gonna get a custom widget that looks something like this now this next step is very very important you want to come back to your app and what you want to do is you want to only copy a certain part of it okay so in this case as you can see we have this line with State and so what you want to do is you want to copy everything below right here you want to paste that into your app come back to the app and you want to paste it just below the state right here paste that there now there's a couple of things that you need to do if you come back to your uh generated widget you see this state it also has in this example it's giving us something else so we're going to copy this go back to the widget and we're gonna paste it in here now when you finish doing everything you're gonna have a widget that looks something like this and now you need to compile this widget right so we're going to say compile code we're going to wait a few moments okay so it finished compiling we can go ahead and we can refresh our test environment our app that is running okay so we're gonna go back and now we're gonna click through and find the the new widget and this is the result this is the widget that we have and this is exactly what we told chat the GPT to do we said that rotates box as an animation and it decided to create a red box that essentially rotates at this specific speed now all of these things you can change now in this specific widget in addition to width and height we're also passing the size of the box and the color as well and I just created them as parameters uh in the same way that I talked about in the previous couple of examples so if we go back to the UI go to this widget we have the size and we have the color so I can change the color to let's say dark bluish something like that we see a little preview here but if we go back to the app and we reload it we should be seeing a blue rotating okay we come in here and now we're seeing a blue rotating box we can also change the size and kind of mess around with it all of these things are absolutely customizable now before you go crazy and you start using Chad GPC for all of your custom widgets there's a very very important thing that you need to understand and this is something that one of my students in my mastering flutter flow course training uh mention now what he was trying to do was he was trying to get Chad gbt to generate a custom widget for him uh the problem was was that he wasn't building like a regular custom widget like I was doing here he was building a custom widget that was taking advantage of the data that he was working with inside of the app so in your app you can be you know using firestore DB data you can be using App State data and the problem arises when you're trying to kind of mix and match different things and get them working together so as an example if you are doing you know if you're you know building your app in flutter flow and you have your data and flutter flow uh you have to be very very careful of how you actually pass that data and how you make that data available inside you know your custom widget or your custom function because flutter flow has their own way of uh managing the data that you're accessing inside of your app so if you're using firestore they have their own way of you know accessing that data and so if you're going to be using chat GPT to help you generate a custom widget and you're also going to be telling it that you're using you know Firebase firestore chances are it's going to generate a widget that's simply not going to work because the way it generates you know database custom widgets with firestore etc etc is different from the way flutter flow does it so if you when you're dealing with things like data you're dealing with with these types of things uh you need to be very very careful because chances are charging she's not gonna know you're using flutter flow and so it's going to make some mistakes of doing it but for simple custom widgets that are doing some animation some buttons some text things like that you can easily use a tool such as chat GPT to help you generate the widgets and then use them inside of your flutter Flow app now if you watch this video and you're still not 100 sure on some of the things that I talked about some of the things are not exactly clear you're you know you have maybe a couple of dials here and there when I was building you know maybe a simple custom widget or maybe a more complex custom widget well the best thing for you guys to do right now apart from rewinding this video and double checking things that I talked about would be to view and or clone this exact app like I have it right now because when you are viewing it you can see exactly what I built here when you clone it you can leverage the functionality right inside of your ass because you can typically take this app you can clone that you can remove the things that you don't and you can easily View and or clone the specific app by joining our amazing patreon Community because when you join our incredible patreon Community not only will you get access to all the flutter flow apps that are built on this channel but you'll get access to extra content such as q and A's live streams behind the scenes content as well as my patreon exclusive Master Class Series where I do a deep dive on a specific topic that the community is perhaps having trouble with and so the community votes on a specific topic and then they create an extensive video where I hopefully get you to a new level of understanding of that specific topic a lot of people have said that a lot of these videos really help them to kind of understand this at a deeper level and so if you're serious about building no code apps you really want to build that one app that you been thinking about for a while or you want to build a ton of apps and different niches then joining our amazing patreon Community is going to be the right move for you and you can join our amazing patreon Community by clicking on the link in the description below this video now if you guys enjoyed this video and you're looking for more content that will help you build amazing apps with flutter flow then you should definitely check out my amazing training called mastering flutter flow in that training I broke in the process of building apps on flutter flow into easily digestible modules where you have access to our community and you can ask any question that you have plus you can also join our private Discord Community where Community as well as myself will help you with any issues that you have so that you end up building the app of your dreams and you can get more information about my training in the description just below the video
Info
Channel: James NoCode
Views: 13,608
Rating: undefined out of 5
Keywords: flutterflow, flutterflow 2023, flutterflow full custom widgets training
Id: 0jp2-Rge9IE
Channel Id: undefined
Length: 36min 17sec (2177 seconds)
Published: Wed May 03 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.