Loading...
Print Send a link

A simple C library for graph plotting

Introduction


Download demo - GraphicalDisplayDemo_12022009.zip (32.98 KB)
Download source code - GraphDisplaySrc_12022009.zip (97.09 KB)

In our application, we had to display the output of a multichannel ECG (Electro Cardiograph) device. I had a look at some commercial libraries, but none of them met by demands. So, I decided to design a simple solution by myself.

This is my attempt to design a flexible, easy to use library for drawing graphs.

The library is capable of displaying multiple graphs in different layouts. Right now, five modes of display are possible:

* Normal: means that all data sources are displayed in one graph window, with separate ordinates.
* Stacked: means that all data sources are displayed in one graph window, stacked vertically, with shared ordinate and shared abscissa.
* Vertical aligned: means that the graph windows are displayed vertically aligned, with separate ordinates and shared abscissa.
* Tiled horizontal: means that the data sources are displayed in tiled windows (preferred alignment direction is horizontal).
* Tiled vertical: means that the data sources are displayed in tiled windows (preferred alignment direction is vertical).

Graphs can be displayed unscaled or auto-scaled. In the auto-scale mode, the visible graph is automatically fit to the visible area.

The following images show examples for the different display modes:
Normal:



Stacked:



Tiled horizontal:



Tiled vertical:



Vertical aligned:



Autoscaled X-Axis?



The following images show a sample of an ECG application, where eight data sources are displayed vertically tiled and auto-scaled.



Using the Code


The control is very simple to use. Just have a look at the sample application. The following code shows how the graphs in the sample application are generated:

Color[] cols = { Color.Red, 
    Color.Orange,
    Color.Yellow, 
    Color.LightGreen, 
    Color.Blue ,
    Color.DarkSalmon, 
    Color.LightPink };

display.DataSources.Clear();
display.SetDisplayRangeX(0, 400);

for (int j = 0; j < count; j++)
{ 

    display.DataSources.Add(new DataSource());
    display.DataSources[j].Name = "Graph " + (j+1);
    display.DataSources[j].GraphColor = cols[j];
    display.DataSources[j].Length = 5800;
    display.DataSources[j].SetDisplayRangeY(-300, 600);
    display.DataSources[j].SetGridDistanceY(100);
    display.DataSources[j].AutoScaleGraph = true;
    display.DataSources[j].OnRenderXAxisLabel += RenderXLabel;

    for (int i = 0; i < display.DataSources[j].Length; i++)
    { 
        display.DataSources[j].Samples[i].x = i; 
        display.DataSources[j].Samples[i].y = (float)(((float)20 * 
        Math.Sin(40 * (j + 1) * (i + 1) * 3.141592 / display.DataSources[j].Length)) * 
        Math.Sin(160 * (j + 1) * (i + 1) * 3.141592 / display.DataSources[j].Length)) +
        (float)(((float)200 *
        Math.Sin(4 * (j + 1) * (i + 1) * 3.141592 / display.DataSources[j].Length)));
        display.DataSources[j].OnRenderYAxisLabel = RenderYLabel; 
    }
}


The functions RenderYLabel and RenderXLabel are used to render the X and Y legends of the graph.

private String RenderXLabel(DataSource s, int idx)
{
    int Value = (int)(s.Samples[idx].x/200);
    String Label = "" + Value + "\"";
    return Label;
}

private String RenderYLabel(DataSource s, float value)
{ 
    return String.Format("{0:0.0}", value);
}


Summary


There are lots of parameters that can be twisted, which are not explained here - just look at the code. This library is far from being finished, but it is a good point to start from. The code is simple and self-explaining. From here, it will be simple to adapt the code for your needs.

I got so much inputs from here, and I wanted to give something back. So, here is my first article on The Code Project. I hope you like it.
To Do's

* Further code clean ups.

Version History


* 12.02.2009 - Implemented X auto-scaling.
* 28.01.2009 - Some more cleanups. Implemented Print Form.
* 27.01.2009 - New display mode, some cleanups.
* 25.01.2009 - Initial release.





Created by: Ivor. Last Modification: Thursday 11 of June, 2009 20:39:50 CEST by Ivor.