DASHBOARD OR BAR-PIE CHARTS

Maybe instead of a full white rectangle, the .png can contain an AA already. So for example using a 45° line (with proper AA), instead of the 0° or 90° ones. That way we could skip the AA process (or lack of).
Not sure I’ll have time to improve on the code, but should be pretty performant to leave room for messing around a bit (it creates a single object for each slice).

Ah, that is an interesting concept.  It feels a bit strange to prepare hard baked lines in all sorts of angle instead of just supplying a single image of a line to be programmatically rotated, but if that’s what it takes, I suppose that’s what needs to be done.

Naomi

I think I’d have to scrap this idea.  I’d need to create 180 pieces of line images to accommodate this.  Otherwise, I won’t be able to capture every angle I’d need.  But then, this feels like a giant waste of texture memory…  Is this really what it takes to create a good looking pie chart with Corona?

Naomi

Actually, I meant to use a single png with a 45° line (top point in the top left corner of the canvas, bottom one in the bottom right corner), set the anchor points to 0, 0 (top left), and then after having positioned it at 0, 0 of the circle, rotate it.
This way it should still keep it’s AA a bit (or at least it’s worth a try), and still load only one image.
Another way I thought again to achieve this using images is

-Get a white circle on a transparent background
-Get a mask that is half black, half white, with the central line antialiased
-Create two circles for each slice you need, and colorize them
-Apply the mask to each circle, rotate it so that from the first circle it takes out the desired portion (would be currAngle in my code)
-If the % is higher than 50%, take the second circle, apply the mask, and rotate it so that it reaches the second angle (newAngle in my code)
-If the % is lower than 50%, do a display save of the current circle, delete it, load the new texture, and again apply the mask and rotate it so that it removes everything after the second angle (always newAngle in my code)
-Repeat for all slices needed

This would 99% remove all issues of AA, using just 2 file (the circle and the mask), and the end result would use a texture for each slice (which is not too bad). Also it should be able to do that quite fast, unless there aren’t 100 slices needed. Consider also that business apps rarely need particular care for performance (apart in slide views or if they have intense animations).
 

Hey, @hachisoft, thanks for sharing your thoughts.

You know, I fooled around with the 360 lines that make up the pie chart, and I decided I’d go with it.  My pie chart will sometimes need a single piece, other times, two or three… up to six pieces.  I kind of feel I can use the line version with the flexibility I want without worrying too much about dynamically adjusting the pie chart based on how many pieces there are or how big /small each piece is going to be. 

And… when I set the barWidth to 1, the chart kind of look funky, and perhaps it can pass as intentionally stylized design – and the jaggedness from the dividers doesn’t feel so strikingly horrid when placed along with the pattern the chart creates.

So long as the device build doesn’t have any performance issue with the pie chart, I think I’ll stick with it.  (And if Corona fixes the anti-alias issue, I can simply widen the barWidth back to 2 and return the pie chart to look more normal.)

Naomi

Final note:  I decided not to use display.newLine to create lines but instead use display.newImageRect, showing a PNG image of a white strip.  I then apply color via setFillColor for each pie pieces and add divider of white using the same PNG file.  This also makes circle mask unnecessary for the pie chart.  Overall, this seems to give me the most flexibility I like.  Cheers.

@Naomi, I solved the antialiasing issue with no performance loss (actually I think it’s faster :smiley: ) and made a blog post about it (; 
It kinda bugged me and fortunately I didn’t had to rewrite basically anything of the previous code (;

Hey, @hachisoft, this is awesome!  I’m so glad you made it work so beautifully.

Thank you!!

Naomi

Oh, by the way, @hachisoft, I’m assuming you’re okay with me adding your ragdogLib.lua along with your brush.png in my commercial product.  Please confirm.

Thanks again!

Naomi

@Naomi, glad you like it! (; And of course you can use any of our libs in free/commercial products, and even in open source projects (in this last case as long as credit is given and it’s not one of our templates (; )

Thank you, @hachisoft!

Now, here’s a problem with the pie chart, though.  It doesn’t quite work when I change the data to the following:

[lua]

local data = {

  radius = 90,

  values = {

    {percentage = 18, color = {0, 0, 1}},

    {percentage = 12, color = {.5, 0, 0}},

    {percentage = 67, color = {0, 1, 0}},

    {percentage = 3, color = {1, 1, 0}},

  },

  name = “myFirstPieChart.png”

};

[/lua]

Or something like:

[lua]

local data = {

  radius = 50,

  values = {

    {percentage = 10, color = {0, 0, 1}},

    {percentage = 12, color = {.5, 0, 0}},

    {percentage = 75, color = {0, 1, 0}},

    {percentage = 3, color = {1, 1, 0}},

  },

  name = “myFirstPieChart.png”

};

[/lua]

Or something like:

[lua]

local data = {

  radius = 50,

  values = {

    {percentage = 99, color = {0, 0, 1}},

    {percentage = 1, color = {.5, 0, 0}},

  },

  name = “myFirstPieChart.png”

};

[/lua]

Any ideas how to deal with cases like these?

Naomi

@Naomi, Whoops! Didn’t took into account that 4 points aren’t enough to properly draw angles bigger than 180° (: Fixed that, and updated the link in the blog post (;

Another thing, if you need to do a pie of one big 100% slice, make the percentage 99.9 (:

My bad, uploaded another version d: The last one still had a couple issues in a few scenarios.
This time I made sure to test it throughly, putting into a timer going from 99 to 1 percentage, and all seems well (:

OMG, @hachisoft, this is awesomeness.  Thank you for the update.

I’m now wondering if you can allow something like this:

[lua]

local data = {

  radius = 80,

  values = {

    {percentage = 100, color = {0, 0, 1}},

    {percentage = 0, color = {.5, 0, 0}},

    {percentage = 0, color = {0, 1, 0}},

    {percentage = 0, color = {1, 1, 0}},

    {percentage = 0, color = {1, 0, 1}},

    {percentage = 0, color = {0, 1, 1}},

  },

  name = “myFirstPieChart.png”

};

[/lua]

Meaning, sometimes, only one out of six may have value.

By the way, it seems like I can do something like the following:

[lua]

local data = {

  radius = 80,

  values = {

    {percentage = 0, color = {0, 0, 1}},

    {percentage = 90, color = {.5, 0, 0}},

    {percentage = 0, color = {0, 1, 0}},

    {percentage = 0, color = {1, 1, 0}},

    {percentage = 10, color = {1, 0, 1}},

    {percentage = 0, color = {0, 1, 1}},

  },

  name = “myFirstPieChart.png”

};

[/lua]

The two pieces of pies work, but I do see a tiny gap.  I wonder if you could perfect these two cases too.  Would be super nice.

Naomi

@Naomi, updated the blog post  version to take those cases into account (:
Now if a percentage is 0, the slice will be skipped completely, and if it’s 100, it will be made as 99.9 so it draws it correctly (;

@hachisoft, it’s beautiful!  This is great.  Thank you so much for updating it.

Cheers,

Naomi

Hey, @hachisoft, there’s just one more thing to perfect your pie chart code.  I think you’ve inadvertently made “slice” a global variable.  It’s on line 122 of your library:  strokesSlices[#strokesSlices+1] = slice ;

You might want to fix it?

Thanks again for putting the pie chart code together.  This is really an awesome library.

Naomi

P.S.  Commenting out the line 122 doesn’t seem to cause any issue (and I don’t find any mention of “slice” anywhere else in the library) – so I assume this line is a left over from previous iteration and no longer necessary?

@Naomi, update it in the blog post. Yup, it’s a bit of leftover from playing around with various solution :smiley: I polished the code now a bit too (: I’m glad you like the library! (;

Great!

Naomi

Hey, @RagdogStudios, I came across a situation where the pie chart isn’t displaying the size I tell it to.  This only happens when I want to display two different pie charts by toggling small to big (or big to small.)  I made a simple test project, and I’m wondering if you can tell me what might be causing this to happen and how I may fix it.

The test folder has main.lua, config.lua, build.settings, ragdogLib.lua and png files.  Here’s the copy of main.lua (and if you’d like me to email you the complete test project with png files, please let me know.)

[lua]

display.setStatusBar( display.HiddenStatusBar )

local ragdogLib = require( “ragdogLib” )

local widget = require( “widget” )

local showSmall

local showBig

local smallGroup

local bigGroup

local sheetOption = {

    width = 180, 

    height = 52,

    numFrames = 2,

    sheetContentWidth = 180,

    sheetContentHeight = 104

    };

sheet = graphics.newImageSheet( “PNG/btn180x52.png”, sheetOption )

showSmall = function()

    display.remove( bigGroup ); bigGroup = nil;

    smallGroup = display.newGroup()

    local data = {

      radius = 50,

      values = {

        {percentage = 18, color = {0, 0, 1}},

        {percentage = 12, color = {.5, 0, 0}},

        {percentage = 25, color = {0, 1, 0}},

        {percentage = 3, color = {1, 1, 0}},

        {percentage = 42, color = {1, 0, 1}},

      }

    };

    local pie = ragdogLib.createPieChart(data);

    pie.x, pie.y = display.contentCenterX+100, display.contentCenterY;

    smallGroup:insert(pie)

    

    local switch = widget.newButton

    {

        sheet = sheet,

        defaultFrame = 1,

        overFrame = 2,

        width = 180,

        height = 52,

        label = “Show Big”,

        labelColor = { default={1.0}, over={1.0} },

        fontSize = 18,

        font = native.systemFontBold,

        onRelease = showBig

    }

    switch.x = 100;

    switch.y = display.contentCenterY;

    smallGroup:insert(switch)

end    

showBig = function()

    display.remove( smallGroup ); smallGroup = nil;

    bigGroup = display.newGroup()

    local data = {

      radius = 100,

      values = {

        {percentage = 10, color = {0, 0, 1}},

        {percentage = 42, color = {.5, 0, 0}},

        {percentage = 25, color = {0, 1, 0}},

        {percentage = 3, color = {1, 1, 0}},

        {percentage = 20, color = {1, 0, 1}},

      }

    };

    local pie = ragdogLib.createPieChart(data);

    pie.x, pie.y = display.contentCenterX+100, display.contentCenterY;

    bigGroup:insert(pie)

    local switch = widget.newButton

    {

        sheet = sheet,

        defaultFrame = 1,

        overFrame = 2,

        width = 180,

        height = 52,

        label = “Show Small”,

        labelColor = { default={1.0}, over={1.0} },

        fontSize = 18,

        font = native.systemFontBold,

        onRelease = showSmall

    }

    switch.x = 100;

    switch.y = display.contentCenterY;

    bigGroup:insert(switch)

end

showSmall()

[/lua]

Naomi

Ah, I fixed the problem by adding 1 millisecond delay for piechart creation.

Cheers,

Naomi