Click here to Skip to main content
15,867,453 members
Articles / Desktop Programming / MFC

2D Animated Charts

Rate me:
Please Sign up or sign in to vote.
3.73/5 (35 votes)
24 Jan 2005CPOL6 min read 235.2K   9.5K   114   52
An article on creating 2D animated charts using Windows GDI.

2DAnimatedCharts/preview1.jpg 2DAnimatedCharts/preview2.jpg 2DAnimatedCharts/preview3.jpg

Introduction

This article demonstrates the use of Windows GDI in the creation and animation of different types of 2D charts (bars, lines and pies). With this article is also included a demo-project and a source with all needed classes to implement charting in Win32 applications.

Background

A background of this can be found in various flash-chart projects and commercial software available on the Internet. My goal is to try to come as much closer as possible to existing Flash solutions in 2D charting using just Windows GDI (and no OpenGL rendering). That is why this solution is suitable for applications that would like to present graphical data in a dynamic way with the possibility of real-time data rendering. This solution is also built to run fast and reliable using minimum CPU time.

Using the Code

To use the presented code, you will need to download just Source.zip file and extract the source files to your project application. Then, include headers and you can start creating and editing charts. You can also download a demo-project to see in one place all the available chart types and animations.

Creating 2D Animated Charts

First, I will explain the structure of presented solution. The base class is CGraphObject providing functionality for creating different chart types and animations, and also for changing some default chart object properties. This class is derived from CWnd and it is actually the window of the chart object. So, you will need to provide an ID for this object. Follow the example in creating this object:

C++
// First call the constructor
m_pGraphObject1 = new CGraphObject();

// Then initialize m_pGraphObject1 object
// (or however you name it, in your project)
m_pGraphObject1->Create( NULL, NULL, NULL, 
   CRect(40,20,240,220), this, ID_OBJECT_GRAPH_1, NULL );

I have limited the minimum size of the chart window because I don't see the reason in creating a chart window smaller than 200x200 pixels if you like to see or read something at all, but you are free to change this in the constructor of the CGraphObject class.

Then, you will need to decide what chart type you need and when you do, create the chart of the specified type, like this:

C++
// Create chart of the specified type
m_pGraphObject1->CreateGraph( GT_2DPIE );

Possible chart types are: 2D pie chart (GT_2DPIE), 2D bar chart (GT_2DBAR) and 2D line chart (GT_2DLINE).

The next step depends on the chart type you have chosen to work with. In this article, I will presume you will work with the 2D pie chart graph object. So, next you will need to add segments to the pie chart. You don't need to worry about the segments percent. You can add segments as long as you like but when you reach to 100%, all segments you try to add will not be added (unless you change this, I wouldn't). To add segments to the pie chart, do the following:

C++
// Add 2D pie chart segment
m_pGraphObject1->Add2DPieGraphSegment( 40, RGB(255,0,0), "Seg_1" );
m_pGraphObject1->Add2DPieGraphSegment( 25, RGB(0,255,0), "Seg_2" );
m_pGraphObject1->Add2DPieGraphSegment( 15, RGB(0,0,255), "Seg_3" );

The first argument is the percent segment we will have in the resulting pie on the screen. The second is the color of the segment, and the third is the segment text that will be shown in the pie chart's legend.

After you finish adding pie chart segments, you should decide if you would like the chart to be animated on the screen or not. Follow the code:

C++
// Set 2D pie chart animation
m_pGraphObject1->SetGraphAnimation( TRUE, AT_PIE_DRAW );

First argument says if it will be animated or it not. If chart is not animated, then the second argument is not important, but if the chart is going to be animated on the screen, then this argument can also have values that depend on the chart type you have chosen to work with. Since I am explaining here work with 2D pie chart, this argument can have the following values: 2D pie chart draw animation (AT_PIE_DRAW) and 2D pie chart blend animation (AT_PIE_BLEND).

That is it! Your chart is now fully functional.

When you finish working with CGraphObject object, you must destroy it in the following manner:

C++
//Destroy graph object
m_pGraphObject1->DestroyWindow();

Changing Default Chart Properties

Now, when you see your chart on the screen, you can think it isn't so much. It isn't much with default chart settings because these settings are there just to enable the chart's main function which is data representation and, maybe, animation. There are many chart properties you can modify, like:

  • chart title text
  • chart subtitle text
  • chart title text color
  • chart subtitle text color
  • chart title text shadow (show or hide)
  • chart subtitle text shadow (show or hide)
  • chart background style (solid or gradient)
  • chart background color
  • chart background gradient style (vertical or horizontal)
  • chart label text color
  • chart legend (show or hide)
  • chart legend background color
  • chart legend text color
  • chart size
  • chart position
  • chart animation type

Altering these properties, you can get results (I hope even better) shown in preview pictures.

Chart Design Considerations

Here, I will just explain some possible chart design considerations that can help your charts look better.

The first thing is that everything depends on the quantity of data and the type of the data you would like to show in your chart. If you are working with data you would like to see in comparison with some other data on the same chart, then you must use either 2D bar or 2D line chart types (since pie chart doesn't have a possibility to work with data in series).

If you find that your number of series is equal or smaller then the number of segments, then I suggest you use charts that have width and height the same. This will improve the chart's appearance, no matter what the chart's size is.

If you want to speed-up the chart's animation, you will need to change the ANIMATION_TIME identifier that can be found in the header file of the CGraphObject class. Be careful decreasing this value since it is a Windows timer resource that is created each time you create an animated chart object. This could possibly be a threat if you have too many charts in your application. This demo works fine with all 12 charts and default animation timings. Speeding-up charts animation costs more CPU time but looks better.

You may find it useful to change default CGraphObject class Create() method. If you would like to move your chart windows on the screen, then alter parameters passed in this function to CWnd Create() method. Your charts can have the windows attributes all windows have.

Watch the text length you pass to the chart title or subtitle, labels or legend text. This solution contains no text-wrapping methods, so too long text strings can look ugly. Anyway, text on charts is used to mark data specific attributes (quantity, kind or something else).

All positioning and sizing inside the chart is done according to relative calculations, based on the chart's size and position. So, if you find you can improve your chart's appearance by changing these values, please do so.

At the end, you are free to modify everything you find in these solutions and accommodate them to your needs. It might be easy to combine different types of animation and get totally new ones, but it is a thing to experiment.

Points of Interest

I am interested in continuing the work on these charts but next time in 3D space, I hope. That will require using fast 3D rendering device and one possible solution might be employing OpenGL.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Elektromehanika d.o.o. Nis
Serbia Serbia
He has a master degree in Computer Science at Faculty of Electronics in Nis (Serbia), and works as a C++/C# application developer for Windows platforms since 2001. He likes traveling, reading and meeting new people and cultures.

Comments and Discussions

 
QuestionSimple minimal example? Pin
DrMN29-Jan-24 0:51
DrMN29-Jan-24 0:51 
QuestionQuestion Pin
_Flaviu3-Dec-15 22:19
_Flaviu3-Dec-15 22:19 
AnswerRe: Question Pin
darkoman17-Dec-15 21:08
darkoman17-Dec-15 21:08 
GeneralRe: Question Pin
_Flaviu21-Dec-15 1:30
_Flaviu21-Dec-15 1:30 
Bugnice project Pin
Member 114046137-Jun-15 6:00
Member 114046137-Jun-15 6:00 
Questiondamn the Chinese network... Pin
Cheng Chuankai25-Nov-12 10:07
Cheng Chuankai25-Nov-12 10:07 
GeneralMy vote of 5 Pin
NUPTboyZHB5-Apr-12 2:26
NUPTboyZHB5-Apr-12 2:26 
QuestionI find the code useful but it seems that you require the max value to be first in a series. Pin
csystemsaz26-Aug-11 10:49
csystemsaz26-Aug-11 10:49 
QuestionGreat article, but... Pin
brightak19-Jul-11 6:06
brightak19-Jul-11 6:06 
Questioncan i use this code for dialog based? Pin
kip_chuko26-Sep-10 20:43
kip_chuko26-Sep-10 20:43 
GeneralMy vote of 1 Pin
moher_gryzie17-Apr-10 7:23
moher_gryzie17-Apr-10 7:23 
Generalthanks Pin
callmejt19-Jan-10 19:10
callmejt19-Jan-10 19:10 
GeneralThank you! Pin
isnis2-Sep-09 16:50
isnis2-Sep-09 16:50 
QuestionQuestion... Pin
Kimmiseon12-Jun-09 16:16
Kimmiseon12-Jun-09 16:16 
GeneralAbout memory leak... Pin
Han JaeJoong26-Jul-07 5:07
Han JaeJoong26-Jul-07 5:07 
GeneralRe: About memory leak... Pin
Diode28-Dec-07 21:36
Diode28-Dec-07 21:36 
Generallmd charts Pin
kurnikov11-Apr-07 6:33
kurnikov11-Apr-07 6:33 
GeneralRe: lmd charts Pin
darkoman11-Apr-07 19:14
darkoman11-Apr-07 19:14 
GeneralBitBlt or GardientFill which is faster Pin
Sarath C21-May-06 5:22
Sarath C21-May-06 5:22 
GeneralRe: BitBlt or GardientFill which is faster Pin
darkoman21-May-06 11:20
darkoman21-May-06 11:20 
Generalplease fix this small bug Pin
Jane041010-May-06 23:28
Jane041010-May-06 23:28 
thank you for your source code.It save me a lot of time. I found a little memory leak still in your source code.
you should call "ClearGraph()" in C2DPieGraph::~C2DPieGraph().
thanks again.wish you a good day.

Smile | :)
GeneralClear Area Pin
vtwsvani16-Feb-06 14:20
vtwsvani16-Feb-06 14:20 
GeneralRe: Clear Area Pin
darkoman16-Feb-06 19:08
darkoman16-Feb-06 19:08 
GeneralRe: Clear Area Pin
vtwsvani16-Feb-06 21:21
vtwsvani16-Feb-06 21:21 
GeneralRe: Clear Area Pin
darkoman16-Feb-06 21:48
darkoman16-Feb-06 21:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.