BNPieChart

This post introduces a new open-source iOS pie chart class, BNPieChart.  It’s designed to draw beautiful, scalable pie charts with a dead-simple interface.

To get the class, just click the Downloads button from the moriarty github page.

This chart:

is produced with this code:

BNPieChart *chart = [[[BNPieChart alloc] initWithFrame:frame] autorelease];
[chart addSlicePortion:0.1 withName:@"Orange"];
[chart addSlicePortion:0.2 withName:@"Fandango"];
[chart addSlicePortion:0.1 withName:@"Blue"];
[chart addSlicePortion:0.1 withName:@"Cerulean"];
[chart addSlicePortion:0.3 withName:@"Green"];
[chart addSlicePortion:0.1 withName:@"Yellow"];
[chart addSlicePortion:0.1 withName:@"Pink"];

BNPieChart is a UIView subclass, and you include it in your view hierarchy just like any other view. Note that the actual colors are chosen for you – in the example I’ve named the colors only for the sake of drawing labels. If you exclude labels, the chart knows to use the extra space and fills up most of its frame.

BNPieChart is also designed to display well at much smaller sizes. For example, the exact same code, within a frame size of 140×100, appears like this:

The chart is also drawn in a transparency-friendly way, so that you can display it above images or other views. For example:

If you want to avoid transparency, just set

myPieChart.backgroundColor = [UIColor whiteColor];

similar to any other UIView.

As with all code posted here and in the moriarty library, this class is free to use under the Apache 2 license, and I welcome contributions on the github repo.

(PS Fandango is the name of a dance, but also of a color in the fuchsia range, in case you were curious about that.)

22 Comments

  1. Jules
    Posted January 25, 2011 at 8:39 am | Permalink

    Good job 🙂 Great pie chart, hate to grumble, but there’s some `Build Analyzer` warnings, any chance of an update to fix them ?

  2. Posted January 26, 2011 at 2:07 pm | Permalink

    I’ll take a look at these, Jules.

  3. Posted January 26, 2011 at 5:43 pm | Permalink

    Ok, just pushed an update to github.

    Turns out the code was functioning correctly, just that my naming convention was based on the old Core Foundation “create” instead of “new.” I changed the name of one method, and it builds without any analyzer warnings now.

  4. Posted February 13, 2011 at 5:59 pm | Permalink

    Thank you! Your code saved me!

  5. Posted April 1, 2011 at 6:58 am | Permalink

    Great lib Tyler, the best I have seen so far without question (very polished).

    Looking though you code I see that you are specifying the colours for each of the segments in the function getRGBForIndex (assumption here as I am quite new to IOS dev), is there a way to fix the colours for each segment other than this method – the idea is that I start with the an orange colour (already in place) and then move to green, yellow ect

    Thanks again for a great library, David

  6. Posted April 5, 2011 at 2:05 am | Permalink

    Hi @david, I just added user colors to BNPieChart. Download the latest version from the github page to see it (https://github.com/tylerneylon/moriarty). You set them with BNColor, which accepts rgb values either as a hex string (like @”00FF00″ for green) or as floats, similar to UIColor. I used BNColor because it’s easier for me to directly access the red/green/blue values later on, when I need to tweak them for the gradients involved.

  7. Posted April 5, 2011 at 2:29 pm | Permalink

    Also! This stuff is open source, so anyone is free to add features directly. I’m happy to add anything useful and well-written in the official library. To contribute, follow standard github procedure, which is basically: (1) get a github account, (2) fork the repository (i.e. make a personal copy of the codebase), then (3) make whatever changes you like in your version, (4) send me a pull request on github.

  8. arturo
    Posted April 13, 2011 at 2:26 pm | Permalink

    It has been very useful for me.

    I got some troubles when sending a BNPieChart view the message setFrame:(CGRect)frame;

    but I fixed it implementing the setFrame method by copy and pasting the code in the
    initializer:

    -(void) setFrame:(CGRect)frame{
    [super setFrame:frame];
    fontSize = frame.size.width / 20;
    if (fontSize < 9) fontSize = 9;

    // Compute the center & radius of the circle.
    centerX = frame.size.width / 2.0;
    centerY = frame.size.height / 2.0;
    radius = centerX < centerY ? centerX : centerY;
    radius *= kRadiusPortion;
    }

  9. Posted April 14, 2011 at 1:08 pm | Permalink

    Hi @arturo, thanks! Good idea. I added this change to the code (on github).

  10. Alan Taylor
    Posted April 16, 2011 at 7:23 pm | Permalink

    Hi, could you give some more specific instructions? I added the .h and .m, including the ones for BNColor and NSObject+Be, and I have no warnings when I compile but never see the chart. I figure I must be missing a simple step, but I can’t for the life of me work out what.

    Thanks so much for sharing your work with everyone, and I appreciate any help you can give me!

  11. Alan Taylor
    Posted April 17, 2011 at 1:16 pm | Permalink

    Ah! I got it! It was something simple >.<
    [self.view addSubview:chart];

  12. jorge johnson
    Posted April 18, 2011 at 1:00 pm | Permalink

    very nice pie chart!
    please use part of your spare time on think about a pie slide reacting to a touch. It would be great if, for example at first, I make a summary of data with a pie chart, and before that, I use a touch or gesture in a slide portion on order of the pie to query for detailed data (in a UITableView, for example).
    thank you a lot.
    nice job.

  13. Posted April 20, 2011 at 12:15 am | Permalink

    Hi @jorge, good idea. It would be nice if an app could respond to taps on a pie chart slice, such as showing details about that slice of the pie. I don’t have much free time lately, so no promises. Also, this is open source, so anyone can add this functionality. If the code is good, I’ll pull it into the master branch on github (the official library). If someone were to implement this, I would recommend using an optional (ie allowed-to-be-nil) delegate object for callbacks from BNPieChart about touch information.

  14. Alan Taylor
    Posted May 30, 2011 at 10:02 am | Permalink

    Could you give a bit more information on changing the colours for the different segments? I was hoping I could make the colours match the colour-scheme of my app more…

    Thank you!

  15. Posted June 8, 2011 at 2:41 am | Permalink

    @Alan, you can set the colors to anything you want by setting up an NSArray of BNColor elements, and then setting the “colors” property of your pie chart to that array. Something like this:
    BNPieChart *pieChart = [[BNPieChart alloc] init];
    BNColor *myColor1 = [self setupColor1];
    BNColor *myColor2 = [self setupColor2];
    pieChart.colors = [NSArray arrayWithObjects:myColor1, myColor2, nil];

    Now everything will be based on the colors you provided. The first pie slice is colors with the first color you provide, and so on. If there are more slices than colors, then the colors repeat, so it’s best to provide enough colors to cover all your cases.

  16. Colm
    Posted June 9, 2011 at 8:35 am | Permalink

    Thank you so much for this – really lovely looking chart and just the right mix of simplicity/customisability.

  17. Posted June 16, 2011 at 2:12 pm | Permalink

    Thank you, @Colm! What an insightful comment, I am impressed.

  18. Mikkel Bjerg
    Posted July 11, 2011 at 2:40 am | Permalink

    Looks very good, however I seem to have a problem when showing the chart in Landscape mode, the texts are not properly placed, and I havent been able to find out why, please help me

  19. Mikkel Bjerg
    Posted July 11, 2011 at 3:30 am | Permalink

    The problem only occurs when I try to build the PieChart in my viewDidLoad. If I make the chart in the init-method it works perfectly

  20. Posted July 12, 2011 at 4:33 pm | Permalink

    Hi @Mikkel, if I can reproduce the error, I’ll fix it. It would be easiest for me if you could post somewhere a zip file of a small Xcode project that shows the problem. Could you do that?

  21. Posted July 18, 2011 at 1:59 pm | Permalink

    How do you “reset” the data cleanly so you can update the pie chart? I can reset the portions array, but the labels appear to still get written multiple times….

    [_pieChart.slicePortions removeAllObjects];
    [_pieChart addSlicePortion:0.25 withName:@”Fat”];
    [_pieChart addSlicePortion:0.50 withName:@”Carbs”];
    [_pieChart addSlicePortion:0.25 withName:@”Protein”];

  22. Posted July 20, 2011 at 6:08 am | Permalink

    Hi @Duane, I noticed your pull request on github for this. I’ll take a look at that code later today. Thanks!

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*