Simple Graph Control

at Definitive Solutions, Inc.


Click here to enlarge image

Environment: Windows NT4 SP5, Visual C++ 5

This is a very simple (but easily enhanced) CStatic-derived class to do bar, line, and pie graphs. Why create one of these instead of just using the Microsoft-supplied control? Mostly because I want better control over the appearance.

The class has the following features:

  • Supports any number of series and groups.
  • Tooltips to tell you what the values are.
  • The colors are picked automatically.
  • The font sizes scale to the size of the control.
  • Trivia: const correct, Hungarian, no leaks, lots of ASSERTS and VERIFYs, commented!
To use the class, take the following really easy steps:
  1. Insert the MyGraph.cpp and MyGraph.h files into your project.
  2. Create a "static" control called IDC_STATIC_MYGRAPH (for example) in a dialog box. Give it a border so it looks nice, and make sure to check the "Notify" checkbox (or you won't get the tooltips).
  3. Use ClassWizard to add a member variable called "m_graph" of category "Control" and variable type "CStatic" for your "static" control.
  4. Edit the dialog's header file to the header file:
  5. #include "MyGraph.h"
    
  6. Edit the dialog's header file to change your static control's class from "CStatic" to "MyGraph".
    // Dialog Data
    //{{AFX_DATA(CMyGraphDemoDlg)
    enum { IDD = IDD_MYGRAPHDEMO_DIALOG };
    /* CStatic */ MyGraph	m_graph;
    //}}AFX_DATA
    
  7. Edit the dialog's header file to include member variables for each series you want to graph:
    // MyGraph data.
    private:
     MyGraphSeries	m_gsBoys;
     MyGraphSeries	m_gsGirls;
    
  8. In your dialog's OnInitDialog(), add code to initialize the graph; for example:
  9. // Create the series.
    m_gsBoys.SetLabel("Males");
    m_gsGirls.SetLabel("Females");
    
    // Add series to graph.
    m_graph.AddSeries(m_gsBoys);
    m_graph.AddSeries(m_gsGirls);
    
    // Set up the graph.
    m_graph.SetGraphType(MyGraph::Pie);
    m_graph.SetYAxisLabel("Births");
    m_graph.SetXAxisLabel("Day of Week");
    m_graph.SetGraphTitle("Babies Born by Gender, Day of Week");
    
    // Add some data for each weekday.
    int nGroup(-1);
    
    nGroup = m_graph.AppendGroup("Sunday");
    m_gsBoys.SetData(nGroup, 25);
    m_gsGirls.SetData(nGroup, 35);
    
    nGroup = m_graph.AppendGroup("Monday");
    m_gsBoys.SetData(nGroup, 15);
    m_gsGirls.SetData(nGroup, 12);
    
    nGroup = m_graph.AppendGroup("Tuesday");
    m_gsBoys.SetData(nGroup, 5);
    m_gsGirls.SetData(nGroup, 21);
    
    nGroup = m_graph.AppendGroup("Wednesday");
    m_gsBoys.SetData(nGroup, 17);
    m_gsGirls.SetData(nGroup, 6);
    
    nGroup = m_graph.AppendGroup("Thursday");
    m_gsBoys.SetData(nGroup, 20);
    m_gsGirls.SetData(nGroup, 18);
    
    nGroup = m_graph.AppendGroup("Friday");
    m_gsBoys.SetData(nGroup, 12);
    m_gsGirls.SetData(nGroup, 16);
    
    nGroup = m_graph.AppendGroup("Saturday");
    m_gsBoys.SetData(nGroup, 8);
    m_gsGirls.SetData(nGroup, 13);
    
    // Paint the graph now that we're through.
    m_graph.Invalidate();
    

The code is as clean as I can make it, but is by no means complete or bulletproof; it should give you a good starting point, though. There are several assumptions and shortcuts made, so beware. Of course, no warranty is implied, so use at you own risk. This is code is based on un-copyrighted code posted here by Brian Convery at CGraph - Graph Class for Plotting Groups of Data. I pretty much rewrote the entire thing, but much of the basic design is his. I pass it along enhanced and still un-copyrighted. As far as I'm concerned, you can use it for any purpose whatsoever.

Downloads

Download demo project - 32 Kb
Download source - 11 Kb