Introduction
A Chart needed to be implemented in my earlier project for displaying the real-time ethernet data packets transfer status in a graphical view. I tried to find interesting materials and sample applications for chart display. I found
some charts looked like graphs already - even those that were intended for displaying complete
data records. I could not find a good article which displayed dynamic data on
runtime. After that, I planned to create an independent chart control with more features,
to be flexible and useful wherever possible.
Overview
Actually I am a beginner in ATL components. This is my first ATL application which I developed to
learn about ATL components and while achieving independent chart control. I tried to find
some guidance, which could help me to learn about ATL and how to create an ATL component but could
not find any clear document on how to create ATL controls. Then, I started to create one using MSDN.
Features
These ATL Chart controls have some of the main and important features like:
- Automatic Scaling.
- Customizing display dynamically (colors, styles, refresh speed, etc.).
- Animated Chart view. (Built-in timer for synchronize the display).
- Overlaying chart bars (Single or double chart bars)
Code Description
ATLChart Control initialize
Linking the Chart Control with your application is pretty easy. Simply register
the dll file (ChartATL.dll) either by typing
regsvr32 chartATL.dll
in the command prompt or
use "ActiveX control test container" tool from Visual Studio's start menu and compile your
project. Now choose the "chart atl" control from the Toolbox and drag it into your dialogs
or on any controls. You can edit all of the control's properties in the designer's Properties panel.
Property Methods
These property methods are used to customize the chart display
dynamically at runtime. The user is then required to do some
modifications. This can be achieved by creating a member variable
for the ATLChart control which is placed on the dialog. And by using
the dot (.) operator followed
with the member variable, it will list all the methods and variables of
that object (ATLChart). You
can call any of the corresponding methods with valid parameter values
to update the chart at
runtime. Based on the modification, the chart will get updated and
displayed dynamically
(colors, styles, refresh speed etc.).
STDMETHOD(get_BackColor)(OLE_COLOR* pVal);
STDMETHOD(put_BackColor)(OLE_COLOR newVal);
STDMETHOD(get_VerticalLineStyle)(PenStyle* pVal);
STDMETHOD(put_VerticalLineStyle)(PenStyle newVal);
STDMETHOD(get_HorizontalLineStyle)(PenStyle* pVal);
STDMETHOD(put_HorizontalLineStyle)(PenStyle newVal);
STDMETHOD(get_VerticalLineColor)(OLE_COLOR* pVal);
STDMETHOD(put_VerticalLineColor)(OLE_COLOR newVal);
STDMETHOD(get_HorizontalLineColor)(OLE_COLOR* pVal);
STDMETHOD(put_HorizontalLineColor)(OLE_COLOR newVal);
STDMETHOD(get_ChartColor_1)(OLE_COLOR* pVal);
STDMETHOD(put_ChartColor_1)(OLE_COLOR newVal);
STDMETHOD(get_ChartColor_2)(OLE_COLOR* pVal);
STDMETHOD(put_ChartColor_2)(OLE_COLOR newVal);
STDMETHOD(get_ChartFillStyle_1)(BrushStyle* pVal);
STDMETHOD(put_ChartFillStyle_1)(BrushStyle newVal);
STDMETHOD(get_ChartFillStyle_2)(BrushStyle* pVal);
STDMETHOD(put_ChartFillStyle_2)(BrushStyle newVal);
STDMETHOD(put_RefreshSpeed)(USHORT newVal);
STDMETHOD(get_RefreshSpeed)(USHORT* pVal);
Dynamic Chart Value Updating
There is only one public method available for updating the chart values: UpdateChart
. At any
point in time if you obtain a value from anywhere (released by an event obtained from recurring
routines, etc), add it to the ATLChart control using the UpdateChart
method. No need to
worry about data preparation or display synchronization. This method consists of two parameters:
UpdateChart(USHORT ChartValue1, USHORT ChartValue2);
USHORT ChartValue1 - Specifies the value to be modified the first bar
of the chart.
USHORT ChartValue2 - Specifies the value to be modified the second bar
of the chart.
Global typedef definitions
Global typedef definition is used to specify the styles of the line and fill color property.
PenStyle
: typedef describes the styles of vertical and horizontal lines in the background of the chart.
BrushStyle
: typedef describes the bar fill color style for the two different colored bars.
typedef enum
{
L_SOLID = 0,
L_DASH = 1,
L_DOT = 2,
L_DASHDOT = 3,
L_DASHDOTDOT = 4,
L_EMPTY = 5,
L_INSIDEFRAME= 6,
L_USERSTYLE = 7,
}PenStyle;
typedef enum
{
B_SOLID = 0,
B_EMPTY = 1,
B_HOLLOW = 2,
B_HATCHED = 3,
B_PATTERN = 4,
B_INDEXED = 5,
B_DIBPATTERN = 6,
B_DIBPATTERNPT = 7,
B_PATTERN8X8 = 8,
B_DIBPATTERN8X8 = 9,
B_MONOPATTERN = 10
}BrushStyle;
Chart Drawing Methods
Drawing the chart is one of the easiest parts of this project. Here I will simply get the
boundaries of the control on the dialog and divide them into equal parts, horizontally
and vertically.
Actually there are two methods used to draw the chart. The DrawChartBackground
method will draw the background of the chart, and give the background an animated form by
moving the vertical line from right to left. The RedrawChart
method will do the automatic scaling by
checking the maximum value passed and draw the two-chart bar.
VOID CChartDlg::RedrawChart(HDC hdc, RECT Rect)
VOID CChartDlg::DrawChartBackground(HDC hdc, RECT Rect)
Demo Application Execution procedure
Download the source from the above following links and save it into a folder. Now register ChartATL.dll
either through the command prompt "regsvr32 ChartATL.dll" or register using "ActiveX control test container"
tools option from start menu in Visual Studio.
Further Improvements
We can still improve this component.
- Adding more properties to the chart. (like width of the lines and size of the grid).
- Number of underlying bars at runtime (User can change the number of bars to be drawn on chart at runtime)
- Display negative values. Currently works only with positive values
- ... and still more features.
Conclusion
This ATL Chart control has many benefits: a better understanding of
creating a basic user
control custom drawing using ATL, and an improvement in learning the
basic coding style of ATL components. However,
this component is incomplete. There are several ways of improving the
aspects of this component, but what we have satisfies the user's basic
needs.