Adding Charts With the "Easy-to-Use" Control: CChartCtrl

Click here for a larger image.
Environment: VC6 SP5
About a year ago, there were not as many chart implementations on CodeGuru.com as there are now. This is why I decided to write one of my own. I am happy to see more implementations now and to be among those who attempt to author such a useful control. I set out to design a simple charting control that fit my needs as they are today and to build on them as future needs arise. I believe that this is laid out in an easy manner that you can take advantage of for your customized needs also.
The CChartCtrl is based on a CWnd and can be placed anywhere a CWnd can be placed. The sample application places it into a CChartView (based on CView) as a data member, as well as on a dialog that shows some of the styles that can be set. I believe this to be an easy peice of code to take advantage of because it is so straightforward, as shown in the following code snippit from the dialog's OnInitDialog():
m_wndChart.Create(NULL,
NULL,
WS_CHILD|WS_VISIBLE,
CRect(0, 0, 0, 0),
this,
1);
m_wndChart.SetChartType(TYPE_LINE);
m_wndChart.SetAxisStyleX(AUTO_SCALE|m_wndChart.GetAxisStyleX());
m_wndChart.SetAxisStyleY(AUTO_SCALE|m_wndChart.GetAxisStyleY());
m_wndChart.SetAxisFormatString(X_AXIS, CString("%.2f"));
m_wndChart.SetAxisFormatString(Y_AXIS, CString("%.2f"));
/****clear all data and create the data sets****/
m_wndChart.Purge();
m_wndChart.AddDataSeries("RED", RGB(255, 0, 0));
m_wndChart.AddDataSeries("GREEN", RGB(0, 255, 0));
m_wndChart.AddDataSeries("BLUE", RGB(0, 0, 255));
/****clear all data and create the data sets****/
CDataPoint DataPoint;
double dDivisor((rand()%20)+2+2*DBL_EPSILON); //mimimum == 2
/****invent some data****/
for (int i(0);i<10;i++) {
DataPoint.m_dX = i;
DataPoint.m_dY = (rand()%50)/dDivisor;
DataPoint.m_sCaption.Format("DataPoint %d", i);
m_wndChart.AddDataPoint(&DataPoint);
DataPoint.m_dY = (rand()%50)/dDivisor;
DataPoint.m_sCaption.Format("DataPoint %d", i);
m_wndChart.AddDataPoint(&DataPoint, 1);
DataPoint.m_dY = (rand()%50)/dDivisor;
DataPoint.m_sCaption.Format("DataPoint %d", i);
m_wndChart.AddDataPoint(&DataPoint, 2);
}
/****invent some data****/
m_wndChart.ShowHeader(FALSE);
m_wndChart.ShowFooter(FALSE);
m_wndChart.ShowLegend(TRUE);
m_wndChart.ShowSeriesLegend();
m_wndChart.Invalidate();
m_wndChart.UpdateWindow();
That's pretty much it. Using this in a CView-based object is not much different; you need to create it as above in your overridden OnCreate() function and handle the sizing in your overridden OnSize() function. Check out CChartView to see how this is done; they're both one-liners.
You can periodically add data points through a timer or other timed event; this is what the StripChart does. Cleanup is handled on its own.
Things to note:
The strip chart does work but can eat a lot of processor resources if the style is any of the filled strip charts greater than 60 data points. The bottle neck here is the CDC::Polygon() function. To overcome this, the strip chart skips every other data point and compresses what is already there. Compressing any more than every other data point results in a lousy image, at best. After the maximum number of data points is reached (automatically set, based on the strip chart type), the chart begins to scroll from right to left, tossing out the oldest point. Here, the image is shifted toward the right and only a new data segment is added. At this point, CPU usage is barely perciveable. I was hoping to improve this CPU hog considerably, but I am out of ideas. I welcome any suggestions you may have. The non-filled strip chart is not a problem and is graphically superior because it redraws completely every time.
Currently the data sets are limited to positive numbers because those are my needs for the time being.
Included in the demo project is a CChartCtrl interface guide called ChartHelp.htm.
Downloads
Download demo project - 60 KbDownload source - 129 Kb

Comments
Distance between Bar Charts & Tooltip Text
Posted by Aravind_Ponnur on 08/04/2005 06:45amHi, Thanks for the code. I would like to increase spaces between two bar charts. Please tell me how to do that. I have added OnGetPopupText() function to dialog box which shows this Graph and modifed the Message variable. But still I am not able to see my own tooltip. Looking forward to hear from you. Thanks & Regartds, AZG
ReplyDoes anybody implement scrolling support?
Posted by Legacy on 01/21/2004 12:00amOriginally posted by: Oleg
I tried to do this with overriding CChartView with CScrollView, but not implementing yet. May be someone find out another way?
ReplyHow can i draw a logarithmic axis of coordinates?
Posted by Legacy on 01/04/2004 12:00amOriginally posted by: qhzeng
The chart Library is perfect. but in my application, sometimes logarithmic axis of coordinates are needed.
ReplyHow can i change the axis into logarithmic axis?
Scrolling support
Posted by Legacy on 12/30/2003 12:00amOriginally posted by: Lak
Good job. I want to add scrolling to XY- Chart. How should I proceed.
ReplyThanks,
Lak
ExportBmpToFile() has memory leakage
Posted by Legacy on 10/11/2003 12:00amOriginally posted by: Edward Jang
In printing, your chart control shows the different image with window chart image.
So, I make the chart image to bmp file.
And i add the bmp file to print the some form.
But I found the your ExportBMPtoFile() has memory leakage.
ReplyPlease correct this problem.
pie chart with one datapoint
Posted by Legacy on 09/29/2003 12:00amOriginally posted by: Fred
When a pie chart has only one datapoint, the draw is incorrect. There is two small pies, one above another.
Normaly, it should have only one pie which should be a circle with one line : this is the default behavior of GDI fonction Pie chen the two point are identical.
I don't know how to resolve this problem ?
Is there something to do in the _DrawPieChart function of DataSeries class ?
Thanks for help.
Fred
(France -> english not very good)
Reply
Printing Problem(Y axis label and Printing image)
Posted by Legacy on 09/28/2003 12:00amOriginally posted by: Edward Jang
Your Chart Control is very excellent.
But, in printing, it doesn't show "Y-Axis label".
and printing result is different with window chart image.
If you correct theses, everyone like that.
ReplyAssertion fault after implementation in a dialog-based project
Posted by Legacy on 07/21/2003 12:00amOriginally posted by: Harry
Hi folks,
I'm working on two independent projects and both of them
are using this Chart.dll.
The first project of the type MDI is running quite perfect
with the chart.dll and the second, a dialog-based project,
shows the following fault if I change from the debug-
configuration to the release-configuration:
I can compile the code without errors and warnings but if
I'm starting the application I get the following error
message:
_AFXWIN_INLINE HINSTANCE AFXAPI AfxGetInstanceHandle()
{ ASSERT(afxCurrentInstanceHandle != NULL);
This assertion (located in AFXWIN1, line 19) fails at the
moment when I'm trying to create the window for the chart and I have NO idea why.
Is there somebody who can help me ??
Every hint would be appreciated.....thanks !
Regards
Harry
ReplyFantastic chart source
Posted by Legacy on 07/03/2003 12:00amOriginally posted by: Harry
Hi folks,
I've implemented Scott's Chart.dll in my project and I'am
very impressed by his work. The possibilities of the
interface and the reliability are great.
Just a few words to explain my situation: I'am a Microwave
engineer and last year I started to gain experiences in
programming VC.
I dont know how long it takes to program such a complicated
dll but I'am very glad that there are programmers like
Scott who shares their work (with beginners ;-) ).
Thank you !!
Sincerely
Harry
Replycan't use from another dll
Posted by Legacy on 06/20/2003 12:00amOriginally posted by: Fred
I can't use CChartCtrl from another dll. If I only declare a
variable of CCHartCtrl class (whitout instancing it), then I can compile, but when a executable try to load my DLL, it fail (it blocks).
How must I do ? I try to modify DllMain and "new CDynLinkLibrary(ChartDllDLL);", but without success ?
Thanks for help.
Fred
(France)
Reply
Loading, Please Wait ...