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 Kb
Download source - 129 Kb


Comments

  • Distance between Bar Charts & Tooltip Text

    Posted by Aravind_Ponnur on 08/04/2005 06:45am

    Hi, 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

    Reply
  • Does anybody implement scrolling support?

    Posted by Legacy on 01/21/2004 12:00am

    Originally posted by: Oleg

    I tried to do this with overriding CChartView with CScrollView, but not implementing yet. May be someone find out another way?

    Reply
  • How can i draw a logarithmic axis of coordinates?

    Posted by Legacy on 01/04/2004 12:00am

    Originally posted by: qhzeng

    The chart Library is perfect. but in my application, sometimes logarithmic axis of coordinates are needed.
    How can i change the axis into logarithmic axis?

    Reply
  • Scrolling support

    Posted by Legacy on 12/30/2003 12:00am

    Originally posted by: Lak

    Good job. I want to add scrolling to XY- Chart. How should I proceed.
    Thanks,
    Lak

    Reply
  • ExportBmpToFile() has memory leakage

    Posted by Legacy on 10/11/2003 12:00am

    Originally 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.
    Please correct this problem.

    Reply
  • pie chart with one datapoint

    Posted by Legacy on 09/29/2003 12:00am

    Originally 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:00am

    Originally 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.

    Reply
  • Assertion fault after implementation in a dialog-based project

    Posted by Legacy on 07/21/2003 12:00am

    Originally 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

    Reply
  • Fantastic chart source

    Posted by Legacy on 07/03/2003 12:00am

    Originally 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


    Reply
  • can't use from another dll

    Posted by Legacy on 06/20/2003 12:00am

    Originally 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 ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • In support of their business continuity and disaster recovery plans, many midsized companies endeavor to avoid putting all their eggs in one basket. Understanding the critical role of last-mile connectivity and always available Internet access for their enterprises, savvy firms utilize redundant connections from multiple service providers. Despite the good intentions, their Internet connectivity risk may still be in a single basket. That is because internet service providers (ISPs) and competitive local …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds