Chart Drawing Solution

Environment: Windows 95/98, Visual C++ 5.0 SP3

These are two classes I'm using to draw easy (absolutely not complex) graphs. I wrote it because I need a light (and cheap) control that could solve some problems about data showing.

What This Control Can Do

  • draw on the same chart few (up to 64, but you can change if you prefer) graphs with different styles
  • each graph can has up to 32k data (I never try this !)
  • draw NULL datas (undrawing them) so that you can show graphs with different X timebase
  • copy to clipboard
  • copy to file

What This Control Can Not Do

  • show data in 3d styles
  • print graph directly to printer
  • do a lot of things that I don't remember at this time...

How to use it

  1. First you must include the two classes in you project: add the files HMXChart.* and HMXDataset.* in your project
  2. include the HMXChart.h header in the CFormView that will show chart; the form must contain a static text control (modify its ID, e.g. IDC_CHART)
  3. create an object (in your formview object) derived from CHMXChart
  4. in formview initialization routine subclass the static text control
  5. set data and make-up

To set the data must be used following function

m_chart.SetData ( n, xxx );
where n represents the dataset, and xxx is the value (double). Every time this function is called a new value is added to the dataset. If you want modify a specific value, use this function:
m_chart.SetData ( n, idx, xxx );
where n is the dataset, idx is the idx-th element (zero based index), and xxx is the new value.

To create a new dataset its enought that a single value is added.

Following questions convinced me to design a new feature for this chart: NULL data.

What about if I have an hole in my data?

This is an example:

I have 2 datasets (Y1 and Y2):

X Y1 Y2
0 21 -12
1 17
2 33 10
3 10
4 23 15
5 22 18
6 12 16
7 13
8 45 17
How can I show these data in the same chart? To answer these questions I wrote this class so that it's possible to handle NULL data. Of course NULL value cannot be in the double range, because there could be a value that could be equal to that NULL. So I decided to define this NULL value as the upper limit of double range (see limits.h for details):
HMX_DATASET_VALUE_INVALID = 1.7976931348623158e+308
What about if a value is 1.7976931348623158e+308?
You can set it to 1.7976931348623158e+308 - 1, having a little error :)

In the example you can set to HMX_DATASET_VALUE_INVALID all the values that have no digits.

Even if the HMX_DATASET_VALUE_INVALID is a right concept for all dataset styles, in vertical bar style the value HMX_DATASET_VALUE_INVALID looks like 0.0, because all bars (positive and negative) starts from the zero line, thus the value 0.0 is represented with a 0 height bar.

There are three data formats: line, vertical bar and area; and the function to use to set the right format is:

m_chart.SetDatasetStyle( n, xxx );
where n is the dataset to modify and xxx can be:
If the style is line, it is possible to define a marker with the function
m_chart.SetDatasetMarker( n, xxx );
There are 4 different markers:
that correspond to a triangle (with vertex up), a square box, a shere and a diamond (45 degree rotated box). The marker size depends on the pen size. Please note that with small size box, sphere and diamond have the same look, reducing the readability.

To set the pen size use following function:

m_chart.SetDatasetPenSize( n, size );
If you're showing a line style graph, the pen size corresponds to the number of pixel used to draw the line; if the style is vertical bar, then the pen size corresponds to the width of the bar; in this case that number must be between 1 and 10; 1 is the smallest bar, 10 is the larger (occupies all the bar space). See the example and try to modify this value (an example is better than 1k words).

It's possible (of course) to set the X and Y labels; Y labels depend on the datasets and on the Y Ticks, X labels are added manually. They're strings, so it's possible to show numbers, text, date and so on.

Another interesting function allows the chart to have a good readability: rounding. It's possible to round the upper and lower chart limits to the multiple of each number, usually 2, 5, 10, 20, 500, and so on. This is its use:

m_chart.SetRoundY( n );
where n is the rounding value. Try to modify the example to see what it does mean.

There are al lot of self-explaining functions that improve chart readability.


Download demo project - 47 Kb