In past programming experiences, I've often had a desire to display and monitor the rate or performance of some operation on a graph. Whether it be the rate of write operations or the number of content results extracted each second, I always thought a graph similar to the graphs found in Windows XP’s Task Manager (CTRL-Alt-Delete) performance and networking tabs would do the trick well. After a quick search on Google for the graph control clone yielded no relevant results, I decided cloning it myself would be an interesting and beneficial experience.
As time progressed and cloning the control proved itself easy, I decided to add more features and make it completely customizable in nearly every aspect. In the end, as the smoke cleared, I was left face to face with the control this article revolves around. It looked and behaved astonishingly beautiful for being developed with such haste. But who cares about its pastime, let's move on and see how easy it is to implement...
Using the code
If any of you read my last article (CGoogle), you’ll be informed of the fact I’m approaching my articles with a new style. Instead of rambling on and on about a certain feature, I'll attempt to hand you the vital information in a much quicker fashion.
Adding the Control to your Dialog
There are two ways to add the control to your dialog, one being the politically correct way of doing it, and the other being the easy way.
If you're looking for the easy way, first add a static control to your dialog (I typically use the picture control for a frame). Then, give the newly created control the desirable styles and a unique ID. You should then proceed to position and stretch the control to where you want the graph. Now, add a new variable to your dialog class using
C2DPushGraph as the type. Finally, call
OnInitDialog and pass the control ID as the first parameter, and the parent window as the second (you may use the '
this' pointer if you’re calling
CreateFromStatic from the parent dialog class).
The politically correct way involves using the Custom Control item in the resource editor and specifying
C2DPushGraph as the class name. From there, you proceed just as you would with any custom control.
Setting the Graph Range
Before continuing, you should set the range of your graph. The range being the minimum and maximum possible magnitudes (for example, a CPU usage graph might have a minimum of 0 and a maximum of 100). To set the range, you can use one or more of the following:
Adding a New Line
The two most important parts of
C2DPushGraph are obviously being able to add a new line, and updating that line with new data. So we'll start off with adding a line. To add a new line, you call
AddLine, which has the following prototype:
AddLine( UINT uiLineID, COLORREF crColor ). The first parameter is the unique ID of the line, this is what you'll use later to indicate you're changing a specific line. The second parameter is the color of the line. I strongly suggest using a preprocessor definition or named constant for your line ID, it makes things much easier.
Pushing a New Point to a Line
Unlike a typical graph, to add a new point to a line, you only need to provide the point's magnitude or Y coordinate. Each magnitude should be a number within your graph’s range, though it will be adjusted to the nearest valid number if it is greater or less than the current maximum and minimum range values. To push a new point to a line, you call
Push, which has the following prototype:
Push( int nMagnitude, UINT uiLineID ).
You'll notice that after pushing a new magnitude to a line, the graph will remain unchanged. This is because you must first push the desired magnitudes to however many lines you wish, then call
Customizing the Graph’s Visual Appearance
Before listing the functions available for setting and retrieving your graph's visual appearance, here is a quick pictorial showing the most basic attributes of the graph control:
Functions Available for Setting Attributes
void SetBGColor( COLORREF crColor )
crColor: The new background color.
void SetGridColor( COLORREF crColor )
crColor: The new grid color.
void SetGridSize( unsigned short usWidthAndHeight )
usWidthAndHeight: The width/height of each grid unit in pixels.
void SetInterval( unsigned short usInterval )
usInterval: The distance in pixels between each magnitude point.
void SetLabelForMax( LPCTSTR lpszLabel )
lpszLabel: The C-string used to label the graph's maximum magnitude.
void SetLabelForMin( LPCTSTR lpszLabel )
lpszLabel: The C-string used to label the graph's minimum magnitude.
bool SetLineColor( COLORREF crColor, UINT uiLineID )
crColor: The line's new color.
uiLineID: The line's ID.
void SetTextColor( COLORREF crColor )
crColor: The new color for the minimum and maximum labels.
bool ShowAsBar( UINT uiLineID, bool bAsBar )
UiLineID: The line’s ID.
bAsBar: true if you want the line displayed in bar graph format, false if not.
void ShowGrid( bool bShow = true)
bShow: true if the grid is to be shown, false if not.
void ShowLabels( bool bShow = true)
bShow: true to show the minimum and maximum labels, false to hide them.
Functions Available for Retrieving Attributes
COLORREF GetBGColor() const
COLORREF GetGridColor() const
int GetGridSize() const
unsigned short GetInterval() const
LPCTSTR GetLabelForMax() const
LPCTSTR GetLabelForMin() const
COLORREF GetLineColor( UINT uiLineID )
int GetMaxPeek() const
int GetMinPeek() const
COLORREF GetTextColor() const
Contacting the Author
Stuart Konen E-mail address: firstname.lastname@example.org
Quick shout out: I'm currently looking for employment and am open to contracts.
- April 14, 2005 - Began work on
- April 20, 2005 - Submitted
C2DPushGraph to The Code Project.