Description

PGL is a library that encapsulates plot capabilities in a MFC project for VC6 and VC7. It is designed to be able to easily plot data generated in a project without the need of any external software. In fact, with CView and CDialog derived classes, you can have your app display chart in 5 minutes.

The aim of PGL is not to have a user-friendly environment but rather being able to generate any plot from the source code.

PGL was originally using OpenGL to raster graphics but now it uses GDI+ (so you need to install Microsoft SDK to compile PGL).

Licensing

The source available on CodeProject is licensed under LGPL. However, the next releases are not free anymore (Ooops, sorry). You can check the latest development at PGL Home Page. Anyway, enjoy beautiful charting.

Features

line strip, fully customisable:

color (RGBA),

line dashing,

point type (circle, box, triangle, etc...)

line width,

filled,

line shadow,

multiple line strip,

etc...

line strip with level of detail capabilities (based on Douglas-Peukler line simplification algorithm),

Vector map,

Height map,

Text,

variable scale,

multiple fonts,

orientable,

Unlimited sub-plotting,

Automatic axis,

Time labelling,

Export to EPS, SVG, JPEG, TIFF, PNG,

CView derived class for fast integration in existing project,

CDialog derived class, etc...

UML

A UML diagram is available in pdf here. It is not complete but it should help you in understanding the library.

Installation

Here are the installation steps to use PGL in one of your projects:

Install GDI+ (part of Microsoft SDK).

Download Gdiplus.dll and make sure it is in the path,

Recompile the source, it will build .lib in the lib directory and the .dll in the bin directory

Add the directory with PGL binaries to your path. (by default it is C:\Program Files\PGL\bin)

Add the include directory and lib directory to Visual C++ include/lib directories.

Make sure the headers are available

That's it!

Getting your project started

Add the following in your StdAfx.h file :

#include"PGL.h"

Since PGL is using GDI+, you must initialize it :

Add the following variable to your CWinApp derived class

ULONG_PTR m_ulGdiplusToken;

Add the following to the CWinApp::OnInitInstance function to initialize GDI+

Add the following to the CWinApp::OnExitInstance function to clean up GDI+.

// shutdown GDI+
Gdiplus::GdiplusShutdown(m_ulGdiplusToken);

Your project should work fine now.

Examples

All these examples are accessible in the source. See the example menu of TestPGL.

Example 1 : Drawing a simple line

This is a first explanatory example. We suppose that the points (x,y) of the line have been generated and are stored in two array pX,pY of size nPoints ( note that you can also pass data as std::vector<double> to PGL).

Here's the code I used to generate the data: a simple sinusoid. Note that the y are in [-1.1, 1.1] but PGL will handle axe labelling the have nice units.

Add the line to the graph (note that an object can be added to only one graph):

pGraph->AddObject(pLine);

Make PGL scale the plot (automatically)

pGraph->ZoomAll();

Create a dialog box and display the plot:

CPGLGraphBitDlg graphdlg(this, pGraph);
graphdlg.DoModal();

You should have the same as the image above. Note that this image (PNG) has been generated by PGL.

Example 2 : Adding a line with level of detail control

You may have to plot line with thousands of points. This can become very heavy and especially if you export it to EPS, the files can become very large. To overcome this problem, you can use a line with LOD included in PGL.

In this examples, we approximate the previous line. Starting from the previous example,

Change the line of code

CPGLLine2D* pLine = new CPGLLine2D;

to

CPGLLine2DLOD* pLine = new CPGLLine2DLOD;

Change tolerance of level of detail

pLine->SetTol(0.05);

Shrink the number of points by a desired compression ratio (here to 10% with 2% threshold)

pLine->ShrinkNorm(0.1,0.02);

On the figure above, you can see the original line and the approximated one. You can gain a serious amount of points using this technique!

Example 3: Customizing axis, labeling, etc...

As you can see in the previous image, all the parameters of the objects are changeable in the code. In this example, we shall

change the title text,

turn off horizontal grid,

show right label,

change number of ticks on the top axis,

switch to time labelling for the x-axis,

and more...

We start from the second example and add the following line of code before calling ZoomAll().

Get a pointer the axis object (there a huge mistake of English but in French it's ok :)(axe -> axis))

I've also disabled the line drawing and set the tolerance to 0.025 for the LOD line. Of course, you can do much more. This is just an example.

Example 4: Sub-plotting !

What about putting multiple plots on a figure: that's possible in PGL in many ways. In fact you can add plots to plots, and so on.

The class CPGLGraph is inherited from a generic plot class : CPGLRegion. You can either

use the function Divide(m,n) to divide the region in an array of m rows and n columns (Note that this method erase all object in the region). After that, you can access the elements with GetChilds(i) (the regions are created row by row). You can get the number of children with GetNChilds():

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

Share

About the Author

Jonathan de Halleux is Civil Engineer in Applied Mathematics. He finished his PhD in 2004 in the rainy country of Belgium. After 2 years in the Common Language Runtime (i.e. .net), he is now working at Microsoft Research on Pex (http://research.microsoft.com/pex).

I want to confirm with that PGL 2.0 is now under Open Source or ZLIB license.If the above is correct, will it be ok if I remove the "This is not free software" legend from the source files and re-distribute it?I downloaded PGL 2.0 fromhttp://projectdistributor.net/Releases/Release.aspx?releaseId=104 last year

The ZoomAll does not work right. I tried to use the methods in region but there is no effect.

All at all I am dispointed. With a lot of work I included this class in my project (a lot of problems with Visual C++ 6.0) but without documentation it is nearly useless. If I have to read and understand all code I prevere to write my own Plot-Window class.

I want to know the autoscaling of the graphs using OpenGL in C++.I had created X and Y-Axis and want to do autoscale for both.Means, when I give Max_Y_Scale as 100 then Y-Axis should display 10 to 100 as a 10 scale, if it is 1000 then it should display last 10 values differenciating as 10 scales.I had used following code to do that,