Click here to Skip to main content
Click here to Skip to main content

2D Animated Charts

, 24 Jan 2005
Rate this:
Please Sign up or sign in to vote.
An article on creating 2D animated charts using Windows GDI.

Preview1.jpg Preview2.jpg 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:

// 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:

// 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:

// 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:

// 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:

//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 possible 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)

About the Author

darkoman
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

 
Questiondamn the Chinese network... PinmemberCheng Chuankai25-Nov-12 10:07 
GeneralMy vote of 5 PinmemberNUPTboyZHB5-Apr-12 2:26 
QuestionI find the code useful but it seems that you require the max value to be first in a series. Pinmembervalenfour26-Aug-11 10:49 
QuestionGreat article, but... Pinmemberbrightak19-Jul-11 6:06 
Questioncan i use this code for dialog based? Pinmemberkip_chuko26-Sep-10 20:43 
GeneralMy vote of 1 Pinmembermoher_gryzie17-Apr-10 7:23 
Generalthanks Pinmembercallmejt19-Jan-10 19:10 
GeneralThank you! Pinmemberisnis2-Sep-09 16:50 
QuestionQuestion... PinmemberKimmiseon12-Jun-09 16:16 
GeneralAbout memory leak... PinmemberHan JaeJoong26-Jul-07 5:07 
GeneralRe: About memory leak... PinmemberDiode28-Dec-07 21:36 
Generallmd charts Pinmemberkurnikov11-Apr-07 6:33 
GeneralRe: lmd charts Pinmemberdarkoman11-Apr-07 19:14 
GeneralBitBlt or GardientFill which is faster PinmemberSaRath 21-May-06 5:22 
GeneralRe: BitBlt or GardientFill which is faster Pinmemberdarkoman21-May-06 11:20 
Hello,
 
well you can draw different gradients using memory bitmap (usualy more complex and better) then using just simple GradientFill() method called for rectangle structures (or triangles, even if the triangles can give you some advantage when drawing gradients).
 
Gradient functions are generaly slower functions.
BitBlt() is extremly fast, but creating memory bitmap will take you time (depending on the size of the bitmap, that is your control's background).
 
I would use the first method and save me a time for coding something else, if I need just some simple horizontal or vertical gradient. GradientFill() would here be enough.
 
The second method, a memory bitmap, would come when I need something like radial or diagonal gradient (or something else).
 

PS.
Anyway, I would have to use double buffering technique in both cases to avoid flickering of the control. That would be again a memory bitmap.
 

Regards...
Generalplease fix this small bug PinmemberJane041010-May-06 23:28 
GeneralClear Area Pinmembervtwsvani16-Feb-06 14:20 
GeneralRe: Clear Area Pinmemberdarkoman16-Feb-06 19:08 
GeneralRe: Clear Area Pinmembervtwsvani16-Feb-06 21:21 
GeneralRe: Clear Area Pinmemberdarkoman16-Feb-06 21:48 
GeneralRe: Clear Area Pinmembervtwsvani16-Feb-06 22:23 
GeneralRe: Clear Area Pinmemberdarkoman17-Feb-06 0:44 
GeneralRe: Clear Area Pinmembervtwsvani18-Feb-06 4:10 
GeneralY-axis scaling issue Pinmembervtwsvani15-Feb-06 20:21 
GeneralRe: Y-axis scaling issue Pinmembervtwsvani16-Feb-06 21:53 
GeneralRe:I have solved it PinmemberJane041014-May-06 20:59 
GeneralProblem Linking Pinmembersitner29-Sep-05 2:33 
GeneralRe: Problem Linking Pinmemberdarkoman29-Sep-05 2:51 
QuestionRight Y axis? PinmemberJRLU12-Sep-05 14:37 
AnswerRe: Right Y axis? Pinmemberdarkoman12-Sep-05 19:06 
AnswerRe: Right Y axis? Pinmemberdarkoman12-Sep-05 19:09 
GeneralPrinting PinmemberVidar Gunstvedt9-Jun-05 1:03 
GeneralRe: Printing Pinmemberdarkoman10-Jun-05 4:15 
GeneralCan't build MFC OLE projects using static MFC libraries Pinsusswhoopi21-Feb-05 12:04 
GeneralRe: Can't build MFC OLE projects using static MFC libraries Pinmemberdarkoman21-Feb-05 21:31 
GeneralRe: Can't build MFC OLE projects using static MFC libraries Pinmemberabimbolacole22-Feb-05 2:56 
GeneralRe: Can't build MFC OLE projects using static MFC libraries Pinmemberdarkoman23-Feb-05 21:24 
GeneralI found memory leaks that did not fix Pinmemberflywingangel2-Feb-05 19:52 
GeneralRe: I found memory leaks that did not fix Pinmemberdarkoman3-Feb-05 2:56 
QuestionMemory leaks fixed yet? PinmemberViolaCase25-Jan-05 0:07 
AnswerRe: Memory leaks fixed yet? PinsussAnounimus28-Jan-05 6:43 
Generalusing just Windows GDI Pinmember.:floyd:.22-Jan-05 13:51 
GeneralRe: using just Windows GDI Pinmemberdarkoman22-Jan-05 21:48 
GeneralTerrible C++ Pinmemberdarkoman20-Jan-05 6:01 
GeneralExcellent! Pinmemberdido2k20-Jan-05 2:48 
GeneralTerrible C++ PinmemberHelmut Muelner20-Jan-05 1:24 
GeneralRe: Terrible C++ Pinmemberdarkoman20-Jan-05 6:02 

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

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

| Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 25 Jan 2005
Article Copyright 2005 by darkoman
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid