Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

S.I.V.: A Simple Pie Chart with Legend

0.00/5 (No votes)
3 Aug 2004 1  
Simplicity Is Virtue : how do draw a simple pie chart almost anywhere

Introduction

Welcome to another S.I.V. article. For explanation of S.I.V., check out that beautiful link "Articles by this author". This one is (again) from a n00b, for the n00bs :-) I was reading a book (can't commercialize here..), and I saw a piece of code for going around in a circle. Following the good old "When in trouble or in doubt, run in circles, scream and shout.", I wrote this article just for practice. Actually, this is kinda my GDI primer, since I never did ANY drawing.

Anyways, since this is a primer, there are probably tons of big NO-NOs, bugs and other stuff. Feel free to find them and correct them and/or inform me to correct 'em.

Background

The reason why I wrote this as two independent classes instead of subclassing something like CStatic, is because this way, you can use it nearly anywhere: dialog, control, SDI/MDI document, or whatever. As long as that something has a DC, you can draw a chart on it.

Another thing that would be important to mention is that these classes work only with PERCENTAGES. That means you can't give them data like: "Sales revenues in 1994", and then: 2025098 USD, 1252366 USD, etc. Only stuff like: "IT professionals by gender", and then: 64% men, 36% women (this is real data from Croatia).

Using the Code

Well, actually this is quite simple: include the PieChart.h and PieChart.cpp in your project and you are ready to go. The most simple way to use them is by using the AutoDelete feature. Since CPieChart holds an array of CPieSlices, it would be nice to delete them automatically when our CPieChart object is deleted. If for some reason, you don't want this (for example, you want to reuse your 'slices' somewhere else), you should turn off the AutoDelete feature OR remove all slices explicitly by using CPieChart::RemoveSlice() function which doesn't delete anything, just removes it from the pie.

If you check out the sample, you'll see that the key parts of this whole article are CPieChart::Draw2D(...) and CPieChart::DrawLegend(...). I've named my drawing function Draw2D because I might decide to create another one, for (surprise, surprise) 3D apple pie, i.e., Draw3D.

So, a bit on Draw2D:

void CPieChart::Draw2D(
        CPaintDC* pDC,
        CPoint ptCenter,
        int nRadius,
        BOOL bShowTitle,
        int nLegend,
        BOOL bFillExtra)
  • pDC - the target DC
  • ptCenter - center point of our pie, in logical units. Everything else is relative to this point.
  • nRadius - radius of our pie, also in logical units
  • bShowTitle - to display title, or not to display title. To be, or not to be. Default: TRUE
  • nLegend - should we display the legend? and where? Default: PIELEGEND_NONE
  • bFillExtra - should we ignore if the percentage data isn't quite right? Default: FALSE

More on bFillExtra: if for example, you set the data so in total sum of all slices, you don't get a full circle (i.e., you don't get 100%) bFillExtra takes the last slice and extends it to fill the rest of the cheese pie. In the demo app, click on the View->Dialog Sample menu, and observe carefully: the "Content" slice has percentage set to zero. However, when Draw2D was called, it looked like this:

// inside CChartDlg::OnPaint()
m_chart.Draw2D( &dc, center, 70, TRUE, PIELEGEND_RIGHT, TRUE );

If you mess around with the values inside OnInitDialog(), and change for example the "Spam" slice percentage from 57 to 33, you will see that the "Content" value has also dynamically changed (in this case to 25%). Recompile and run the example and you'll see what I mean. Next:

void CPieChart::DrawLegend(
        CPaintDC* pDC,
        CPoint ptLocation,
        BOOL bFillExtra )

Everything is pretty much the same as in Draw2D, except for ptLocation. In this case, it is the UPPER LEFT corner of our legend. The reason why this code lies in a separate function is because you might want to draw the legend some place else, not near the pie itself. The only thing you need to take care in that case is the ptLocation. Also remember to use the same bFillExtra value which you used with Draw2D.

Points of Interest

I think it's pretty neat for my first drawing class(es). You might like the fact that both classes are inherited from CObject and are ready to use within Doc/View architecture (i.e., built in Serialization). I hope that they are straightforward to use, and if not, oh well, I did my best. (-: The sample is a Unicode build (I hope), so I guess that means it's Unicode "compatible".

Issues & Bugs

Stuff to (un)do:

  • Perhaps use a MemDC someday so it doesn't flicker at all
  • Make it capable of using "real" data so you don't have to calculate the percentages yourself
  • Create a Draw3D function which would somehow draw a 3D pie
  • Find a girlfriend and get married someday (but only if she knows how to make a pie)
  • Probably much more stuff than I can think of right now..

Copyleft

Nothing new: Copyleft © T1TAN 2004 - 3827. You can use this code in any way, print it and burn it, spit on it, read it backwards and even use it in a commercial app (right..). The only thing you can't do is sell the code and/or claim it yours. M'kay?

NOTE: If you're going to rate this article bad (Or good. Or at least terrible.), please post the reason so I can improve my future writings. No comment is the only bad comment! Thank you! (-:

History

  • 28.7.2004 - Initial release

License

This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.

A list of licenses authors might use can be found here.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here