home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
vos2-121.zip
/
v
/
contrib
/
graph.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1998-10-16
|
12KB
|
374 lines
/****************************************************************************
Module : Graph.cpp
Contents : Method definitions for the grphWin and GraphPane classes.
These functions control the display and behavior of a graph window.
****************************************************************************/
#include <stdio.h> //For sprintf
#include <math.h> //For sqrt
#include <v/vbrush.h>
#include <v/vcolor.h>
#include <v/vmenu.h>
#include <v/vfont.h>
#include "robapp.h"
#include "menus.h"
#include "proto.h"
/****************************************************************************
Constructor: grphWin
Parameters: name, the title of the window
h, the height of the window
w, the width of the window
fd, the data set to be displayed by the window
****************************************************************************/
grphWin::grphWin(void)
: vCmdWindow("Graph Display",700,400)
{
mp = new vMenuPane(MainMenu);
AddPane(mp);
gp = new GraphPane();
AddPane(gp);
ShowWindow();
gp->ShowVScroll(1);
gp->ShowHScroll(1);
gp->SetHScroll(20,50);
gp->SetVScroll(10,0);
gp->Resize(0,0);
}
/*******************************************************************************
Destructor : grphWin
*******************************************************************************/
grphWin::~grphWin(void)
{
delete mp;
delete gp;
}
void grphWin::CloseWin(void)
{
myApp->CloseNotify(this);
vCmdWindow::CloseWin();
}
void grphWin::SetDataSet(int x,int y) {
gp->SetDataSet(x,y);
if (myApp->Params.title[0] != '\0') {
char title[40];
sprintf(title,"Graph Display - %s",myApp->Params.title);
SetTitle(title);
}
ShowWindow();
}
/****************************************************************************
Constructor: GraphPane
Parameters: fd, data set to be displayed.
****************************************************************************/
GraphPane::GraphPane(void)
: vCanvasPane()
{
//Setup values for displaying the window
LeftMargin = 90;
TopMargin = 10;
FontHeight = 22;
FontWidth = 6;
Yextent = 1;
Xextent = 1;
Mark = 0.0;
data1=0;
data2=0;
}
/***************************************************************************
Method: Resize
Parameters: newH, the new height of the window
newW, the new width of the window
Purpose: Resize is called whenever the size of the window changes. It
recalculates parameters for the graph. If it is called with
newH == 0, it determines the height and width to use by itself.
This kludge is used to properly set height and width before the
first time the graph is displayed and after the canvas has been
added to the window (Trust me, it has to work this way).
****************************************************************************/
void GraphPane::Resize(int newW, int newH)
{
if (!newH) {
Height = GetHeight();
Width = GetWidth();
}
else {
Height = newH;
Width = newW;
}
BottomMargin = Height - 55;
RightMargin = Width - 10;
Xint = (RightMargin - LeftMargin) / Xextent;
Yint = (BottomMargin - TopMargin) / Yextent;
#ifdef __UNIX__
if (newH) Redraw(0,0,0,0);
#endif
}
/*****************************************************************************
Method: SetDataSet
Parameters: d1, the first data set, either orig or smooth
d2, model, if there is one
*****************************************************************************/
void GraphPane::SetDataSet(int d1, int d2)
{
data1 = d1;
data2 = d2;
FailureDataSet* fd1;
if (d1 == OrigData) fd1 = myApp->OrgData;
else if (d1 == SmoothData) fd1 = myApp->SmthData;
else if (d1 == ModelData) fd1 = myApp->ModData;
Xextent = fd1->Failure_Data[fd1->Size - 1].time;
//Yexent is one standard deviation from the average
/*
double avg = 0.0;
for (int cnt = 0; cnt < fd1->Size; cnt++)
avg += fd1->Failure_Data[cnt].intensity;
avg /= fd1->Size;
double std = 0.0;
for (int cnt = 0; cnt < fd1->Size; cnt++)
std += (avg - fd1->Failure_Data[cnt].intensity) *
(avg - fd1->Failure_Data[cnt].intensity);
std /= fd1->Size;
std = sqrt(std);
std *= 2.0;
Yextent = 0.0;
for (int cnt = 0; cnt < fd1->Size; cnt++)
if ((fd1->Failure_Data[cnt].intensity <= avg + std) &&
(fd1->Failure_Data[cnt].intensity > Yextent))
Yextent = fd1->Failure_Data[cnt].intensity;
*/
Yextent = fd1->Failure_Data[0].intensity;
for (int cnt = 1; cnt < fd1->Size; cnt++)
if (fd1->Failure_Data[cnt].intensity > Yextent)
Yextent = fd1->Failure_Data[cnt].intensity;
Xint = (RightMargin - LeftMargin) / Xextent;
Yint = (BottomMargin - TopMargin) / Yextent;
Redraw(0,0,0,0);
}
/****************************************************************************
Method : Redraw
Parameters : sx, the left most column that needs to be redrawn
sy, the top most row that needs to be redrawn
height, the height of the area to be redrawn
width, the width of the area to be redrawn
Purpose : Redraw is called whenever the graph pane has to be redrawn
****************************************************************************/
void GraphPane::Redraw(int, int, int, int)
{
//temp variables
int x,y;
int len;
char str[128];
if (!data1 && !data2) return;
//SetBackground(vStdColors[vC_White]);
Clear();
vBrush mybrush;
mybrush.SetColor(vStdColors[vC_MedGray]);
SetBrush(mybrush);
DrawRectangle(LeftMargin+2,TopMargin,RightMargin-LeftMargin-2,
BottomMargin-TopMargin-2);
//Print out the left hand label
vFont myfont(vfFixed,14);
SetFont(myfont);
y = (BottomMargin - TopMargin) / 2 + TopMargin;
DrawText(2,y - (FontHeight + 6) * 4," I");
DrawText(2,y - (FontHeight + 6) * 3,"F N");
DrawText(2,y - (FontHeight + 6) * 2,"A T");
DrawText(2,y - (FontHeight + 6),"I E");
DrawText(2,y,"L N");
DrawText(2,y + (FontHeight + 6),"U S");
DrawText(2,y + (FontHeight + 6) * 2,"R I");
DrawText(2,y + (FontHeight + 6) * 3,"E T");
DrawText(2,y + (FontHeight + 6) * 4," Y");
myfont.SetFontValues(vfSerif,12);
SetFont(myfont);
//Print out bottom label
x = (((Width - LeftMargin) / 2) - (FontWidth * 2)) + LeftMargin;
y = BottomMargin + (FontHeight << 1);
DrawText(x,y-15,"Time");
y = Height - 5;
x = LeftMargin + 2;
double isect = 0.0;
double bogus = 0.0; //Compute intersection of model, mark
if (myApp->ModData)
myApp->Params.predfunc(myApp->Params.beta0,myApp->Params.beta1,isect,Mark,bogus);
len = sprintf(str,"Intensity: %.4f Time: %.2f Beta 0: %9e Beta 1: %9e",
Mark,isect,myApp->Params.beta0,myApp->Params.beta1);
DrawText(x,y,str);
//Print out the bottom scale
x = LeftMargin - FontWidth * 5;
y = BottomMargin + FontHeight;
DrawText(x,y,"0.00");
x = (RightMargin - LeftMargin) / 3 + LeftMargin;
len = sprintf(str,"%.2f",Xextent/3);
DrawText(x - (FontWidth * (len / 2))+3,y,str);
DrawLine(x,BottomMargin - 2,x,BottomMargin + 4); //Tick line
x = (RightMargin - LeftMargin) * 2/3 + LeftMargin;
len = sprintf(str,"%.2f",Xextent * 2/3);
DrawText(x - (FontWidth * (len / 2))+3,y,str);
DrawLine(x,BottomMargin - 2,x,BottomMargin + 4); //Tick line
x = RightMargin;
len = sprintf(str,"%.2f",Xextent);
DrawText(x - FontWidth * len,y,str);
DrawLine(x,BottomMargin - 2,x,BottomMargin + 4); //Tick line
//Print left hand scale
y = (BottomMargin - TopMargin) * 2/3 + TopMargin;
len = sprintf(str,"%.4f",Yextent / 3);
x = LeftMargin - FontWidth * len - 4;
DrawText(x,y + FontHeight / 2-5,str);
DrawLine(LeftMargin - 3,y,LeftMargin + 3,y); //Tick line
y = (BottomMargin - TopMargin) / 3 + TopMargin;
len = sprintf(str,"%.4f",Yextent * 2/3);
x = LeftMargin - FontWidth * len - 4;
DrawText(x,y + FontHeight / 2-5,str);
DrawLine(LeftMargin - 3,y,LeftMargin + 3,y); //Tick line
y = TopMargin - FontHeight / 2;
len = sprintf(str,"%.4f",Yextent);
x = LeftMargin - FontWidth * len - 4;
DrawText(x,y + FontHeight-2,str);
DrawLine(LeftMargin - 3,TopMargin,LeftMargin + 3,TopMargin);
//Finally, graph out each dat set
vPen p1(0,0,128);
SetPen(p1);
PlotLine(data1);
vPen p2(0,128,0);
SetPen(p2);
PlotLine(data2);
vPen p3(100,0,0,1);
SetPen(p3);
y = int(BottomMargin - (Yint * Mark));
DrawLine(LeftMargin+3,y,RightMargin-3,y);
}
/*****************************************************************************
Method: PlotLine
Purpose: PlotLine is called after the background for the graph has been
drawn. It is responsible for drawing the actual graph.
*****************************************************************************/
void GraphPane::PlotLine(int ds)
{
if (!ds) return;
int xs,ys,xe,ye;
FailureDataSet* fd;
if (ds == OrigData) fd = myApp->OrgData;
else if (ds == SmoothData) fd = myApp->SmthData;
else if (ds == ModelData) fd = myApp->ModData;
xs = int(LeftMargin + (fd->Failure_Data[0].time * Xint));
ys = int(BottomMargin - (fd->Failure_Data[0].intensity * Yint));
if (ys < TopMargin) ys = TopMargin;
if (ys > BottomMargin) ys = BottomMargin;
for (int cnt = 0; cnt < fd->Size - 1; cnt++) {
xe = int(LeftMargin + (fd->Failure_Data[cnt + 1].time * Xint));
ye = int(BottomMargin - (fd->Failure_Data[cnt + 1].intensity * Yint));
if (xe > RightMargin) xe = RightMargin;
if (ye < TopMargin) ye = TopMargin;
if (ye > BottomMargin) ye = BottomMargin;
DrawLine(xs,ys,xe,ye);
xs = xe;
if (xs > RightMargin) return;
ys = ye;
}
}
/*********************************************************************
Method : VScroll
Parameters : step, the amount of scrolling being done
Purpose : When the users clicks on the up or down arrows of the
vertical scroll bar in the graph pane, this function moves the
intensity mark up or down.
*********************************************************************/
void GraphPane::VScroll(int step)
{
int top,shown;
GetVScroll(shown,top);
SetVScroll(shown,top + step);
Mark = float(100 - top) / 100.0 * Yextent;
Redraw(0,0,0,0);
}
/***********************************************************
Method : VPage
Parameters : shown, dummay variable for V toolkit
top, the new place to put the intensity mark
Purpose : Called by V when users adjust vertical scrollbar directly,
this method adjusts the intensity mark.
*****************************************************************/
void GraphPane::VPage(int shown, int top)
{
SetVScroll(shown,top);
Mark = float(100 - top) / 100.0 * Yextent;
Redraw(0,0,0,0);
}
/***********************************************************
Method : HScroll
Parameters : step, dummy variable used by V
Purpose : To expand or contract a model as specified by the
user moving the horizontal scroll bar.
*****************************************************************/
void GraphPane::HScroll(int step)
{
double tmp1,tmp2;
if (!(data1 == ModelData || data2 == ModelData)) return;
int top,shown;
GetHScroll(shown,top);
if (step > 0) {
if (!ExpandModel(myApp->OrgData,myApp->ModData,myApp->Params.beta0,
myApp->Params.beta1,myApp->Params.modfunc)) {
Message("Out of Memory!");
myApp->Exit();
}
if (myApp->win1->GetValue(m_Recal)) {
tmp1 = 0.0;
if (myApp->Params.mtype == Logarithmic) tmp1 = myApp->StatMet.Alpha;
Recalibrate(myApp->OrgData,myApp->ModData,
myApp->Params.modfunc,myApp->Params.fitfunc,tmp1);
}
}
else if (step < 0)
ShrinkModel(myApp->ModData);
SetDataSet(ModelData,data2);
myApp->win2->SetDataSet(ModelData);
if (myApp->win7) myApp->win7->SetDataSet(ModelData,data2);
}