![]() |
Desktop Development »
Miscellaneous »
Charting Controls
Intermediate
Plot Graphic LibraryBy Jonathan de HalleuxA library to plot data (lines, maps...) in MFC projects. |
VC6, VC7Win2K, WinXP, MFC, Dev
|
|
Advanced Search |
|
|
|
||||||||||||||||

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).
A UML diagram is available in pdf here. It is not complete but it should help you in understanding the library.
PGL in one of your projects:
GDI+ (part of Microsoft SDK). PGL binaries to your path. (by default it is C:\Program Files\PGL\bin) That's it!
#include "PGL.h"
PGL is using GDI+, you must initialize it :
CWinApp derived class
ULONG_PTR m_ulGdiplusToken;
GDI+
// initialize <code>GDI+ (gdi+ is in Gdiplus namespace) Gdiplus::GdiplusStartupInput gdiplusStartupInput; Gdiplus::GdiplusStartup(&m_ulGdiplusToken, &gdiplusStartupInput, NULL);
GDI+.
// shutdown GDI+ Gdiplus::GdiplusShutdown(m_ulGdiplusToken);
Your project should work fine now.
All these examples are accessible in the source. See the example menu of TestPGL.
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.
// generate data int nPoints = 50; double* pX=new double[nPoints]; double* pY=new double[nPoints]; for (UINT i=0;i< nPoints;i++) { pX[i]=i; pY[i]=sin(i/(double)nPoints*2*3.14)*1.1; }
CPGLGraph* pGraph = new CPGLGraph;
Note that you can check all PGL object with ASSERT_VALID since they all inherit from CObject. CPGLLine2D* pLine = new CPGLLine2D;
PGL will handle the memory afterwards. That is, it will delete the pointers of data at the object destruction. This means pX,pY MUST have been allocated on the heap !
pLine->SetDatas( nPoints /* number of points */, pX /* x(i) */, pY /* y(i) */);
pGraph->AddObject(pLine);
PGL scale the plot (automatically)
pGraph->ZoomAll();
CPGLGraphBitDlg graphdlg(this, pGraph);
graphdlg.DoModal();
PGL.
PGL.

CPGLLine2D* pLine = new CPGLLine2D;
to
CPGLLine2DLOD* pLine = new CPGLLine2DLOD;
pLine->SetTol(0.05);
pLine->ShrinkNorm(0.1,0.02);

ZoomAll().
CPGLAxe2D* pAxis = pGraph->GetAxe();
pAxis->SetTitle(str);
or
pAxis->GetTitle()->SetString(str);
pAxis->GetTitle()->SetColor(0 /* red */,0.5f /* green */, 0 /* blue*/ /* alpha optional */);
pAxis->SetShowGrid(1,FALSE);
pAxis->GetRightLabel()->Show(TRUE); pAxis->GetRightLabel()->SetString("This is the right label");
pAxis->GetRightNumber()->Show();
pAxis->SetTopSecondTicksNb(5);
// enable time labelling pAxis->SetTimeLabel(TRUE); // set origin, time step and format (see COleDateTime.Format for details) pAxis->SetTimeLabelFormat(COleDateTime::GetCurrentTime() /* Time at zero. */, COleDateTimeSpan(0,0,30,0) /* Time per unit */, "%H:%M:%S" /* String format */);
PGL in many ways. In fact you can add plots to plots, and so on.

CPGLGraph is inherited from a generic plot class : CPGLRegion. You can either
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():
// allocated somewhere CPGLRegion* pRegion; // dividing pRegion->Divide(m,n); // accessing region at row 2 and column 1 (zero based index) CPGLRegion* pChildRegion = pRegion->GetChild(2*n+1);
AddRegion. To use this method you must SetNormBBox(...) to set the bounding box (in Normalized coordinates with respect to the parent region)
CPGLRegion* pChildRegion = pRegion->AddRegion(); pChildRegion->SetNormBBox(0.1 /* llx */ , 0.2 /* lly */ , 0.7 /* urx */ , 0.8 /* ury */);

The sources of PGL are provided. Open the workspace
It contains 6 projects :
PGL. Multi-layer graphic interface to export in multiple graphic format such as EPS or SVG. PGL. The graphic library.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 7 May 2003 Editor: Nick Parker |
Copyright 2001 by Jonathan de Halleux Everything else Copyright © CodeProject, 1999-2009 Web11 | Advertise on the Code Project |