Build Your own Pie Chart with Jetpack Compose in Android - Android Studio Tutorial | Canvas

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
what's up guys and welcome to another video about Japan composer and canvas in this video I'm gonna show you how you can build such a beautiful pie chart which displays different list items with different values and when you click on this pie chart for example on this segment then you can see you get the corresponding value the total value and also the description and then you can click on it again and invoke another one like this and another possibility is to click in the middle of the pie chart and then all the items get displayed and you can also set some kind of text in the middle of the pie chart which describes your pie chart all right okay I'm in an empty chapter compost project the only thing I did was to add these colors but you can find them in my github's repository or simply choose your own ones for the pie chart for the different segments and in here in our main activity we are going to remove this default stuff and the first thing we want to do is to create a data class which represents our pie chart elements so pie chart input one input will have for color and a value of type ins a description of type string and a value if the pie chart is currently tapped and this is set for false by defaults then we can start defining our pie chart composable which we will simply call a pie chart this takes the modifier and a radius of type loads which is set to 500 by default so how big our pie chart will be but you can pass another value of course into this composable to choose another the size then we have an inner radius which is the inner circle of the pie chart the white one and this is also uptime float and sets to 250 by default I've experienced it that it looks kind of good if this is half the value of our radius then we have a transparent width so the the little transparent Circle between our actual pie chart and the Inner Circle and this is of type float and 70 by default then we have the input of our trip pie chart which is a list of pie chart inputs and we have a center text so a text inside our pie chart in the middle which is set to nothing by default so you it's up to you if you pass some text or if you leave this empty I will also quickly copy and paste some default compose stuff here to invoke our pie chart so that we can run our previews sometimes and always see what's currently going on otherwise it wouldn't be that easy to follow and I think this should help when watching the video I will go quickly over this and you can find this code in my GitHub repository and can also just copy and paste it we have a column as the root composable which sets some our alignment and Arrangement stuff fills the max size then we have the text composable inside this column which tells us what's the screen about it's about preferred programming languages in my case and then we have a box which also fits the max size and in here our pie chart gets invoked and the pi shots radius will be 500f I think we should don't need to set it here because this is the default value anyway and then we have a modifier which also set to 500 DP and our input list here with different pie chart elements like python Swift JavaScript Java and so on just some pie chart elements here and then also the sender text where we display that 150 persons were asked about their preferred programming language okay all right now we can start in our pie chart compostable we both need to declare some mutable State variables so on the one hand we have the Circle Center if I remember which is set to mutable state of and offset.0 by default and then we also have the input list by remember and this is by remember because we need to change the input list inside our pygel composable because of the is tapped property if the pie chart element is tapped or not or if all pie chart elements are tapped or not and this is why we make this mutable State Bar and this will be set to our input list by default then we have this Center tapped property so this is a general property if the user actually Taps the center and then we can display all the different pie chart elements properties this is also by remember and set to false by default then we will have a box which takes our past modifier the content alignment will be alignment.center and in this box we can then start with our canvas this canvas also takes a modifier which fills the max size and also takes a pointer input modifier for our tap detection later but we will just draw the pie chart and care about tab tab gestures and tabs of the user later any of we will now have different values which interact with each other and this will be a lot of values so if this may be too complicated and I can't explain everything in detail then leave a comment Down Below in the video or write me a message or something and yeah otherwise the video would be too long we have the first value which is our width which we can get from our canvas then we also need the height and then we have the Circle Center which we can get from our width and iron so this will be an offset the x value will be our width divided by 2f and the Y value will be our Heights divided by 2f then we will also have a total value of our input array so each item of our array has a different value and all of the values sent up is our total value so we say input sum off and for the value we just take our it dot value so it sums up all the whole values of all inputs list elements then we need the angel pair value which we can get from 360 divided by our total value because a circle has 360 degrees and our total value are all elements summed up or all values summed up so we can get the angel per value which makes drawing easier later then we also need a variable current start Angel which is of course zero degrees at the beginning then we go over our input lists we can say input list for each and then we get the pie chart inputs in our for each block here in here we first have a look at the is tapped property of our pie chart input and depending on that we will set a different scale because if the user Taps on a pie chart element then it scales out so we can say if pie chart inputs dot is tapped and we set this scale value to 1.1 F and else to 1.0 f after that we also need the angel to draw and we can get this from our pie chart input dot value multiplied with the angel per value and then we know our foreign pie chart input element and then we can scale this with our scale value and if the scale value is just 1.0 F then nothing happens and if the element is tapped then it scales out a little bit now we can draw the arc power element and for the color we pass our pie chart inputs.color or the start Angel we say current start Angel The Sweep angel will be the angel to draw and then we also use the center the size will be a bit radius multiplied with 2L and the heights will be radius multiplied with 2f as well and then we also need to set the top left property which will be our width minus radius multiplied with 2f divided by 2f and for the height and the same thing for the heights minus radius multiplied with 2x divided by 2f and then the last thing we need to do is to update our current start Angel and say current start Angela is equal to current start Angel plus our Angel to draw so that we go a step further to the next item now we can already have a look at how it looks on our emulator and yeah okay this looks fine so far and we draw each item with the corresponding space and yeah now things will get even more interesting below our for each Loop we can then draw our Inner Circle and the little circle which is transparent around the Inner Circle we can say draw context.canvas dot native canvas dot apply because we want to add a little Shadow here and this is easier on the native canvas and not on the compose one so you can say draw a circle and we will pass the circle center.x circle Center dot Y and for the size our inner radius and then we also pass a paint here and say paints.apply for the color we say whites dot copy because we want to make sure that a little bit of the background is shown so we set the alpha to 0.6 F and then to RGB and for the set Shadow layer we pass 10f 0 f 0 f and the color gray to RG RGB like this and then we can also draw the little transparent circle around our Inner Circle and then we can launch it again draw a circle and for the color we say white Dodge copy and for the alpha zero point two F so that it is really transparent and we only see a little bit of it and then for the radius we will pass our inner radius plus a transparent width divided by 2f so it is around our inner radius and starts to draw around our Inner Circle and let me quickly think about let's also add the text in the center then this is also done we can say texts and for the text we say the center text so this is about the text inside our Inner Circle which tells the user some additional information about the pie chart this text will take a modifier and this modifier Swift is on DP our inners inner radius so it's dependent on our inner radius how big this radius is divided by 1.5 F and it also has a little padding of 25 DP and then we have a fontbase Bond rates dot semi Vault the font size will be 70 SP and the text the line will be text the line.center and of course you can also use your own values and heading and all that stuff this is just an example here and yeah okay as you can see this looks quite good so far our Inner Circle and the transparent circle around it and also the text in the middle and yeah okay now things will get a little bit more complicated because we need to rotate the text we need to rotate the percentage values and all that stuff and also make this whole thing clickable so yeah okay now the easy part is done and it will get complicated now up here inside our for each loop after the updated the screw and start Angel we now need to take care of the rotation logic first we say VAR rotates rotate answer is equal to current start Angel and let me quickly close this during start Angel minus Angel to draw divided by 2f minus 90 90 F and again sorry I can't explain all the different values we have here um I try to explain as much as possible but if I would explain every value every variable then this video would last an hour and um yeah you just need to know that this is about the rotation now because we want to display the different percentage texts and we also need to rotate them otherwise they would all be shown horizontally and so that depending on where the text is shown it rotates a little bit then we have an factor and this factor is for um the texts at the top and the bottom because if the angel is too high then the text gets uh stands by the head so we also need to turn it around and in some cases and then we can say if rotate Angel is bigger than 90f this is the case where the text is in the wrong direction then we say rotate Angel is equal to rotate Angel plus 180 modulo 360f and this just Maps the angel to the angel we need and then we can say factor is equal to minus 0.92 F this is also because the text is inverted then and we don't want to make this one F minus one F because then we had a different distance between the pie chart and the text then we have well percentage and we get a percentage value of each pie chart input element of the value divided by the total value to float and multiply this with 100 and then we just convert this to an integer and then we have the percent touch if you want to have commas separated comma percentage which is more precise then feel free to do this I'm I'm happy with the integer percentage and then we can say draw contexts.canvas.native canvas.apply again and because we need to draw a text and as far as I know there's no solution in compose canvas so we use the native canvas again if our percentage value is greater than three because if this would be smaller than 3 then I think the user couldn't reach the percentage value anymore so we only show the percentage value If the percentage is actually over 3 or greater than three then we say rotate and re-rotate this with our rotation engine and then we draw a text here and this text will be our percentage and we also apply a percentage sign here then circle center.x circle Center dot Y and for the Y we need to add additional values because um we wanna set or we wanna draw this percentage value where the user actually can see it in our in our pie charts where their colors are not in the Inner Circle so we need to add additional value we say radius minus radius minus inner radius and this divided by 2f multiplied with our vector and last but not least I paint for the paint dot apply we say text size is equal to 13 sp.2 pixel the text align will be paints.alion Dot Center and the color will be whites dots to RGB and then we can actually start this and you can see how it looks now and yeah this looks fine as you can see and the percentage values are drawn nicely all right okay this is it for the drawing at least the pie chart drawing not the elements description which comes when the user Taps on an item but for the pie chart itself it is it now and yeah now we will come to the tapping logic which will be the most complicated one and down here below our um well we are now below the draw context in our for Loop and we can then say if pie chart input dot is tapped in here we then need the tab rotation because if the user Taps on an item then it gets scaled out and we also want to show on the left and on the right the lines which sep kind of separate the elements so that the user can really see it currently popping out and for that we can say current start Angel minus Angel to draw minus 90 F and then we say rotates and rotates this with our tap rotation then we draw around the directs and the top left for this rounded rack will be our Circle Center the size will be of type size and the width will be 12 F and the height will be our radius multiplied with 1.2 F the color will be Gray and the corner radius will be Corner radius and for the X and the Y value we pass a 15 f and then we need the next line This is the line on the left or on the right depending on where you look at it or which element it means um we can say this is the line for one side and then we also need the other side which we will get from our rotate our tab rotation multiplied with the angel to draw then we are at the end of our segment and can draw the next line then we again we can just copy and paste this here and yeah like this and the last thing is our description text which means in our case the different programming languages like Java kotlin Swift and oleds have different programming language that they get also displayed if the user Taps on a segment and also we need to rotate this because we don't want to show it horizontally and this is why we need this rotate function one one more time this time we again use the rotate Angel and not the tab rotational because the rotate angel means the rotation in the center of the segment and this two rotation functions here wherefore the start and the ending of our segment and then we say well draw context dot canvas dot native canvas dot apply because we again draw a text and then we say draw texts for the text we pass our pie charts inputs dots description and then double colon our pie chart inputs.value then we set our Circle center.x and circle center.y for the positioning and for the Y we need to add the radius multiplied with 1.3 f multiplied with our Vector again because we want to display the text outside of the pie chart and not in the middle or in the color section we want to multiply this radius with 1.3 F because then the text gets drawn outside and this fact factor is again because some kind as in some cases the text is inverted and then we just need to turn it around and then we pass also a paint again say paints.apply the text size will be 22 sp.2 pixel the text align will be again paints.align.center the color will be yds.2rgb and we also say set is fake all text to true alright this is it for all the canvas drawing stuff now things will get wild when we detect the tabs and process the tabs of the user to make this an interactive pie chart up here in our modifier pointer inputs here we will start with detect tab gestures and in here we Define the ontap method and this unhapp method provides us an offset where the user actually tapped in this untapped method we now need the angel in degrees where the user actually tapped because when we have a circle then it's easier to calculate with degrees rather than with such an offset and I will quickly copy and paste the formula here which I already explained in my circular progress slider video where we do the track logic and yeah this is why I will go quickly over this you can just copy and paste this as well or you can also if you're interested in the detailed have a look at the circular progress trackable slider and this formula will provide us the tab angel in degrees and now we also need to check if the user actually tapped inside the Inner Circle so we will expand all the different items or if the user just Taps on the Outer Circle and we only really show this specific item he tapped on and there are four different possibilities where you can click and where we need to consider the offset differentially and this is also a little bit confusing and it would take like 10 minutes here I think to explain this I will also just copy in this and paste this sorry for that but um yeah this is uh the calculation which detects if the center so the inner circle is actually clicked or if the click was outside and not in the Inner Circle now we can check on this Center clicked value which should be true if the user actually tapped inside the Inner Circle we can say if Center clicked and in here we can then set all the input lists elements so all our pie chart elements property is tapped to true or to false depending on if they are already true we can say input list is equal to input lists.nap and now you can see why we made this input list a mutable State because we need to update it in case the user Clicks in the middle or on a specific item we can here say it dot copy and then we set is tabs is equal to not equal is Center tapped so if it's currently is the center Notch tabs at the moment then this is tapped will set will be set to true and in case there is send adapt is true then they are all gonna set to false this was the easy part and I think we can already launch the app and check on the center clicks the last thing we need in this if statement is we need to set this is Center tabs of course to is not Center Tab and then we can start it and as you can see this works perfectly fine but it'd be a tip I don't know if you see my mouse no I don't think so but I'm clicking on the outsides on the single items and there nothing happens only the sender logic works so far in our else case which means that the user tabs on the pie chart but not in the middle of it we first need the angel per value and we can get the answer per value by 360f so 360 Degrees divided by inputs dot sum of it's dots value so 360 F 360 Degrees divided by the total values of all items in our list then we also need the current Angel which is equal to zero f and then we go over our input lists we say input list dot for each and here we get the pie chart inputs we need to do this because we want to detect we want want to calculate on which specific item the user actually clicked so that we can only show this specific item first of all we update the current angel with our pie charts inputs.value multiplied with the angel pair value so to this current Angel the additional angel of our pie chart input gets added and then we can say if tap angel in degrees this is the Angel where the user actually clicked is less than our current angel then we know that the user tapped on this specific item because if the tab engine decrease is below the current Angel and the current answer is the highest Angel the end angel of our um Tron color of our elements then we know that he actually tapped on this specific item then we need the description of this pie chart input element so well description is equal to pie chart inputs dot description and then we can say input lists is equal to input list.map and check if the description is equal to its.descriptioner so the element of this input list and if this is the case then we detected our clicked element and can update it it's dot copy and for the is tabs we simply say not it's dot is tapped and else we just say it.copy is apt is equal to false and if we are in this case we don't want to go further in this for each Loop and we can just say return and add the text gestures so this breaks the for Loop all right I think we can start and try it out and I enabled my mouse so that you can see where I am actually clicking when I click in the middle oh then everything looks almost fine we have two lines which shouldn't be there and let me quickly try the single clicks yeah the single clicks also working fine but uh the separator lines are not drawn where they actually should I need to look into this but yeah most of the functionality is working fine I think okay one minute later I already found it out here in our rotates functioner um I multiply the tab rotational with the angel to draw and this of course needs to be a plus sign here we need to add the angel to draw to our tab rotation let's try it again yeah now everything works um the separator lines are looking very good and yeah also the single item clicks here and oh there's another separator line missing here and another buck and I think this just happens on this first item here okay this um is because the separator line gets overdrawn and this only happens when the first item is drawn because then the last item over draws the first item and the other separated lines in the middle items are not affected by this because they they get drawn on the on the elements color we can fix this by drawing this single separator line in case the first item is selected above or on top of the match one last item and therefore we need to leave the for Loop and we go over this straw con canvas here where actually the circle before the center gets drawn we can here say if input list DOT first is tapped if the first item is tapped then we can rotate this with 90f and draw our rounded rects I think we can just copy it from above and paste it down below and start this again and then this should work when we yeah when we tap on the first item now then everything works regarding the separator lines and also of course the text display and all that stuff all right okay this was it for this video and for the pie chart in chapter composed with canvas sorry about not going into the deep details all the time I think the video would be just too long and if you have any questions about different calculations and regarding this code then I would be really happy to help you and if not we will see us in the next video
Info
Channel: K Apps
Views: 4,243
Rating: undefined out of 5
Keywords: Android, Android Jetpack Compose, Jetpack Compose, Kotlin, Compose, JetpackCompose, PieChart, Android Pie Chart, Android Charts, Android PieChart, Jetpack Compose PieChart, Jetpack Compose Piechart, Jetpack Compose Pie Chart, Jetpack Compose BarChart, Android Bar Chart, Jetpack Compose Charts, Jetpack Compose LineChart, LineChart Android, Compose LineChart, Jetpack Compose User Experiences, Android User Experience, Jetpack Compose Canvas, Android Canvas, Kotlin Canvas, Canvas
Id: CGevyQxp8uw
Channel Id: undefined
Length: 29min 38sec (1778 seconds)
Published: Sun Oct 30 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.