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 >
C/C++ Source or Header  |  1998-10-16  |  12KB  |  374 lines

  1. /****************************************************************************
  2.   Module : Graph.cpp
  3.   Contents : Method definitions for the grphWin and GraphPane classes.
  4.   These functions control the display and behavior of a graph window.
  5. ****************************************************************************/
  6. #include <stdio.h> //For sprintf
  7. #include <math.h> //For sqrt
  8. #include <v/vbrush.h>
  9. #include <v/vcolor.h>
  10. #include <v/vmenu.h>
  11. #include <v/vfont.h>
  12.  
  13. #include "robapp.h"
  14. #include "menus.h"
  15. #include "proto.h"
  16.  
  17. /****************************************************************************
  18.   Constructor: grphWin
  19.   Parameters: name, the title of the window
  20.   h, the height of the window
  21.   w, the width of the window
  22.   fd, the data set to be displayed by the window
  23. ****************************************************************************/
  24.  
  25. grphWin::grphWin(void)
  26.     : vCmdWindow("Graph Display",700,400)
  27. {
  28.   mp = new vMenuPane(MainMenu);
  29.   AddPane(mp);
  30.   gp = new GraphPane();
  31.   AddPane(gp);
  32.   
  33.   ShowWindow();
  34.   gp->ShowVScroll(1);
  35.   gp->ShowHScroll(1);
  36.   gp->SetHScroll(20,50);
  37.   gp->SetVScroll(10,0);
  38.  
  39.   gp->Resize(0,0);
  40. }
  41.  
  42. /*******************************************************************************
  43.   Destructor : grphWin
  44.   *******************************************************************************/
  45.  
  46. grphWin::~grphWin(void)
  47. {
  48.   delete mp;
  49.   delete gp;
  50. }
  51.  
  52. void grphWin::CloseWin(void)
  53. {
  54.   myApp->CloseNotify(this);
  55.   vCmdWindow::CloseWin();
  56. }
  57.  
  58. void grphWin::SetDataSet(int x,int y) {
  59.   gp->SetDataSet(x,y);
  60.   if (myApp->Params.title[0] != '\0') {
  61.     char title[40];
  62.     sprintf(title,"Graph Display - %s",myApp->Params.title);
  63.     SetTitle(title);
  64.   }
  65.   ShowWindow();
  66. }
  67.  
  68. /****************************************************************************
  69.   Constructor: GraphPane
  70.   Parameters: fd, data set to be displayed.
  71. ****************************************************************************/
  72.  
  73. GraphPane::GraphPane(void)
  74.     : vCanvasPane()
  75. {
  76.   //Setup values for displaying the window
  77.   LeftMargin = 90;
  78.   TopMargin = 10;
  79.   FontHeight = 22;
  80.   FontWidth = 6;
  81.   Yextent = 1;
  82.   Xextent = 1;
  83.   Mark = 0.0;
  84.   data1=0;
  85.   data2=0;
  86. }
  87.  
  88. /***************************************************************************
  89.   Method: Resize
  90.   Parameters: newH, the new height of the window
  91.                 newW, the new width of the window
  92.   Purpose: Resize is called whenever the size of the window changes. It
  93.           recalculates parameters for the graph. If it is called with
  94.            newH == 0, it determines the height and width to use by itself.
  95.            This kludge is used to properly set height and width before the
  96.            first time the graph is displayed and after the canvas has been
  97.            added to the window (Trust me, it has to work this way).
  98. ****************************************************************************/
  99.  
  100. void GraphPane::Resize(int newW, int newH)
  101. {
  102.   if (!newH) {
  103.     Height = GetHeight();
  104.     Width = GetWidth();
  105.   }
  106.   else {
  107.     Height = newH;
  108.     Width = newW;
  109.   }
  110.  
  111.   BottomMargin = Height - 55;
  112.   RightMargin = Width - 10;
  113.   Xint = (RightMargin - LeftMargin) / Xextent;
  114.   Yint = (BottomMargin - TopMargin) / Yextent;
  115.  
  116.   #ifdef __UNIX__
  117.   if (newH) Redraw(0,0,0,0);
  118.   #endif
  119. }
  120.  
  121. /*****************************************************************************
  122.     Method: SetDataSet
  123.     Parameters: d1, the first data set, either orig or smooth
  124.             d2, model, if there is one
  125. *****************************************************************************/
  126. void GraphPane::SetDataSet(int d1, int d2)
  127. {
  128.   data1 = d1;
  129.   data2 = d2;
  130.   FailureDataSet* fd1;
  131.  
  132.   if (d1 == OrigData) fd1 = myApp->OrgData;
  133.   else if (d1 == SmoothData) fd1 = myApp->SmthData;
  134.   else if (d1 == ModelData) fd1 = myApp->ModData;
  135.  
  136.   Xextent = fd1->Failure_Data[fd1->Size - 1].time;
  137.  
  138.   //Yexent is one standard deviation from the average
  139.   /*
  140.  double avg = 0.0;
  141.   for (int cnt = 0; cnt < fd1->Size; cnt++)
  142.     avg += fd1->Failure_Data[cnt].intensity;
  143.   avg /= fd1->Size;
  144.   double std = 0.0;
  145.   for (int cnt = 0; cnt < fd1->Size; cnt++)
  146.     std += (avg - fd1->Failure_Data[cnt].intensity) *
  147.       (avg - fd1->Failure_Data[cnt].intensity);
  148.   std /= fd1->Size;
  149.   std = sqrt(std);
  150.   std *= 2.0;
  151.  
  152.   Yextent = 0.0;
  153.   for (int cnt = 0; cnt < fd1->Size; cnt++)
  154.     if ((fd1->Failure_Data[cnt].intensity <= avg + std) &&
  155.     (fd1->Failure_Data[cnt].intensity > Yextent))
  156.       Yextent = fd1->Failure_Data[cnt].intensity;
  157.       */
  158.   Yextent = fd1->Failure_Data[0].intensity;
  159.  
  160. for (int cnt = 1; cnt < fd1->Size; cnt++)
  161.   if (fd1->Failure_Data[cnt].intensity > Yextent)
  162.     Yextent = fd1->Failure_Data[cnt].intensity;
  163.  
  164.    Xint = (RightMargin - LeftMargin) / Xextent;
  165.    Yint = (BottomMargin - TopMargin) / Yextent;
  166.    Redraw(0,0,0,0);
  167. }
  168.  
  169. /****************************************************************************
  170.   Method : Redraw
  171.   Parameters : sx, the left most column that needs to be redrawn
  172.   sy, the top most row that needs to be redrawn
  173.   height, the height of the area to be redrawn
  174.   width, the width of the area to be redrawn
  175.   Purpose : Redraw is called whenever the graph pane has to be redrawn
  176. ****************************************************************************/
  177.  
  178. void GraphPane::Redraw(int, int, int, int)
  179. {
  180.   //temp variables
  181.   int x,y;
  182.   int len;
  183.   char str[128];
  184.   if (!data1 && !data2) return;
  185.   //SetBackground(vStdColors[vC_White]);
  186.   Clear();
  187.   vBrush mybrush;
  188.   mybrush.SetColor(vStdColors[vC_MedGray]);
  189.   SetBrush(mybrush);
  190.   DrawRectangle(LeftMargin+2,TopMargin,RightMargin-LeftMargin-2,
  191.         BottomMargin-TopMargin-2);
  192.  
  193.  //Print out the left hand label
  194.   vFont myfont(vfFixed,14);
  195.   SetFont(myfont);
  196.   y = (BottomMargin - TopMargin) / 2 + TopMargin;
  197.   DrawText(2,y - (FontHeight + 6) * 4,"  I");
  198.   DrawText(2,y - (FontHeight + 6) * 3,"F N");
  199.   DrawText(2,y - (FontHeight + 6) * 2,"A T");
  200.   DrawText(2,y - (FontHeight + 6),"I E");
  201.   DrawText(2,y,"L N");
  202.   DrawText(2,y + (FontHeight + 6),"U S");
  203.   DrawText(2,y + (FontHeight + 6) * 2,"R I");
  204.   DrawText(2,y + (FontHeight + 6) * 3,"E T");
  205.   DrawText(2,y + (FontHeight + 6) * 4,"  Y");
  206.  
  207.   myfont.SetFontValues(vfSerif,12);
  208.   SetFont(myfont);
  209.   //Print out bottom label
  210.   x = (((Width - LeftMargin) / 2) - (FontWidth * 2)) + LeftMargin;
  211.   y = BottomMargin + (FontHeight << 1);
  212.   DrawText(x,y-15,"Time");
  213.  
  214.   y = Height - 5;
  215.   x = LeftMargin + 2;
  216.   double isect = 0.0;
  217.   double bogus = 0.0; //Compute intersection of model, mark
  218.   
  219.   if (myApp->ModData)
  220.     myApp->Params.predfunc(myApp->Params.beta0,myApp->Params.beta1,isect,Mark,bogus);
  221.   len = sprintf(str,"Intensity: %.4f        Time: %.2f       Beta 0: %9e       Beta 1: %9e",
  222.         Mark,isect,myApp->Params.beta0,myApp->Params.beta1);
  223.   DrawText(x,y,str);
  224.  
  225.   //Print out the bottom scale
  226.   x = LeftMargin - FontWidth * 5;
  227.   y = BottomMargin + FontHeight;
  228.  
  229.   DrawText(x,y,"0.00");
  230.  
  231.   x = (RightMargin - LeftMargin) / 3 + LeftMargin;
  232.   len = sprintf(str,"%.2f",Xextent/3);
  233.   DrawText(x - (FontWidth * (len / 2))+3,y,str);
  234.   DrawLine(x,BottomMargin - 2,x,BottomMargin + 4); //Tick line
  235.  
  236.   x = (RightMargin - LeftMargin) * 2/3 + LeftMargin;
  237.   len = sprintf(str,"%.2f",Xextent * 2/3);
  238.   DrawText(x - (FontWidth * (len / 2))+3,y,str);
  239.   DrawLine(x,BottomMargin - 2,x,BottomMargin + 4); //Tick line
  240.  
  241.   x = RightMargin;
  242.   len = sprintf(str,"%.2f",Xextent);
  243.   DrawText(x - FontWidth * len,y,str);
  244.   DrawLine(x,BottomMargin - 2,x,BottomMargin + 4); //Tick line
  245.  
  246.   //Print left hand scale
  247.   y = (BottomMargin - TopMargin) * 2/3 + TopMargin;
  248.   len = sprintf(str,"%.4f",Yextent / 3);
  249.   x = LeftMargin - FontWidth * len - 4;
  250.   DrawText(x,y + FontHeight / 2-5,str);
  251.   DrawLine(LeftMargin - 3,y,LeftMargin + 3,y); //Tick line
  252.  
  253.   y = (BottomMargin - TopMargin) / 3 + TopMargin;
  254.   len = sprintf(str,"%.4f",Yextent * 2/3);
  255.   x = LeftMargin - FontWidth * len - 4;
  256.   DrawText(x,y + FontHeight / 2-5,str);
  257.   DrawLine(LeftMargin - 3,y,LeftMargin + 3,y); //Tick line
  258.  
  259.   y = TopMargin - FontHeight / 2;
  260.   len = sprintf(str,"%.4f",Yextent);
  261.   x = LeftMargin - FontWidth * len - 4;
  262.   DrawText(x,y + FontHeight-2,str);
  263.   DrawLine(LeftMargin - 3,TopMargin,LeftMargin + 3,TopMargin);
  264.  
  265.   //Finally, graph out each dat set
  266.   vPen p1(0,0,128);
  267.   SetPen(p1);
  268.   PlotLine(data1);
  269.   vPen p2(0,128,0);
  270.   SetPen(p2);
  271.   PlotLine(data2);
  272.   vPen p3(100,0,0,1);
  273.   SetPen(p3);
  274.   y = int(BottomMargin - (Yint * Mark));
  275.   DrawLine(LeftMargin+3,y,RightMargin-3,y);
  276. }
  277.  
  278. /*****************************************************************************
  279.   Method: PlotLine
  280.   Purpose: PlotLine is called after the background for the graph has been
  281.   drawn. It is responsible for drawing the actual graph.
  282. *****************************************************************************/
  283.  
  284. void GraphPane::PlotLine(int ds)
  285. {
  286.   if (!ds) return;
  287.   int xs,ys,xe,ye;
  288.   FailureDataSet* fd;
  289.   if (ds == OrigData) fd = myApp->OrgData;
  290.   else if (ds == SmoothData) fd = myApp->SmthData;
  291.   else if (ds == ModelData) fd = myApp->ModData;
  292.  
  293.   xs = int(LeftMargin + (fd->Failure_Data[0].time * Xint));
  294.   ys = int(BottomMargin - (fd->Failure_Data[0].intensity * Yint));
  295.   if (ys < TopMargin) ys = TopMargin;
  296.   if (ys > BottomMargin) ys = BottomMargin;
  297.  
  298.   for (int cnt = 0; cnt < fd->Size - 1; cnt++) {
  299.     xe = int(LeftMargin + (fd->Failure_Data[cnt + 1].time * Xint));
  300.     ye = int(BottomMargin - (fd->Failure_Data[cnt + 1].intensity * Yint));
  301.     if (xe > RightMargin) xe = RightMargin;
  302.     if (ye < TopMargin) ye = TopMargin;
  303.     if (ye > BottomMargin) ye = BottomMargin;
  304.     DrawLine(xs,ys,xe,ye);
  305.     xs = xe;
  306.     if (xs > RightMargin) return;
  307.     ys = ye;
  308.   }
  309. }
  310.  
  311. /*********************************************************************
  312.   Method : VScroll
  313.   Parameters : step, the amount of scrolling being done
  314.   Purpose : When the users clicks on the up or down arrows of the
  315.   vertical scroll bar in the graph pane, this function moves the
  316.   intensity mark up or down.
  317. *********************************************************************/
  318.  
  319. void GraphPane::VScroll(int step)
  320. {
  321.   int top,shown;
  322.   GetVScroll(shown,top);
  323.   SetVScroll(shown,top + step);
  324.   Mark  = float(100 - top) / 100.0 * Yextent;
  325.   Redraw(0,0,0,0);
  326. }
  327.  
  328. /***********************************************************
  329.   Method : VPage
  330.   Parameters : shown, dummay variable for V toolkit
  331.                top, the new place to put the intensity mark
  332.   Purpose : Called by V when users adjust vertical scrollbar directly,
  333.   this method adjusts the intensity mark.
  334. *****************************************************************/
  335. void GraphPane::VPage(int shown, int top)
  336. {
  337.   SetVScroll(shown,top);
  338.   Mark = float(100 - top) / 100.0 * Yextent;
  339.   Redraw(0,0,0,0);
  340. }
  341.  
  342. /***********************************************************
  343.   Method : HScroll
  344.   Parameters : step, dummy variable used by V
  345.   Purpose : To expand or contract a model as specified by the
  346.   user moving the horizontal scroll bar.
  347. *****************************************************************/
  348. void GraphPane::HScroll(int step)
  349. {
  350.   double tmp1,tmp2;
  351.  
  352.   if (!(data1 == ModelData || data2 == ModelData)) return;
  353.   int top,shown;
  354.   GetHScroll(shown,top);
  355.   if (step > 0) {
  356.     if (!ExpandModel(myApp->OrgData,myApp->ModData,myApp->Params.beta0,
  357.              myApp->Params.beta1,myApp->Params.modfunc)) {
  358.       Message("Out of Memory!");
  359.       myApp->Exit();
  360.     }
  361.     if (myApp->win1->GetValue(m_Recal)) {
  362.       tmp1 = 0.0;
  363.       if (myApp->Params.mtype == Logarithmic) tmp1 = myApp->StatMet.Alpha;
  364.       Recalibrate(myApp->OrgData,myApp->ModData,
  365.           myApp->Params.modfunc,myApp->Params.fitfunc,tmp1);
  366.     }
  367.   }
  368.   else if (step < 0)
  369.    ShrinkModel(myApp->ModData);
  370.   SetDataSet(ModelData,data2);
  371.   myApp->win2->SetDataSet(ModelData);
  372.   if (myApp->win7) myApp->win7->SetDataSet(ModelData,data2);
  373. }
  374.