axis.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:12k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: axis.cpp,v $
  4.  * PRODUCTION Revision 1000.2  2004/06/01 20:49:18  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: axis.cpp,v 1000.2 2004/06/01 20:49:18 gouriano Exp $
  10.  * ===========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ===========================================================================
  33.  *
  34.  * Authors:  Andrey Yazhuk
  35.  *
  36.  * File Description:
  37.  *
  38.  */
  39. #include <ncbi_pch.hpp>
  40. #include <gui/graph/axis.hpp>
  41. #include <math.h>
  42. #include <stdio.h>
  43. BEGIN_NCBI_SCOPE
  44. ////////////////////////////////////////////////////////////////////////////////
  45. /// class CAxisRenderer
  46. const int CAxisRenderer::kDefTickSize = 5;
  47. CAxisRenderer::CAxisRenderer(bool bHorz)
  48. :   m_bHorz(bHorz),
  49.     m_Type(eDec),
  50.     m_PosType(ePosMin),
  51.     m_FixedPosValue(0),
  52.     m_TextAlignType(eLeftText),
  53.     m_sFormatTempl("%g"),    
  54.     m_TickStyle(eBothSides), m_TickSize(kDefTickSize),
  55.     m_Color(0.0f, 0.0f, 0.2f),
  56.     m_TextColor(0.5f, 0.5f, 0.5f),
  57.     m_Font(CGlBitmapFont::eHelvetica12)
  58. {
  59. }
  60. CAxisRenderer::~CAxisRenderer()
  61. {
  62. }
  63. void    CAxisRenderer::SetHorizontal(bool bHorz)
  64. {
  65.     m_bHorz = bHorz;
  66. }
  67. void    CAxisRenderer::SetPositionType(EPosition Type)
  68. {
  69.     m_PosType = Type;
  70. }
  71. void    CAxisRenderer::SetFixedPosition(TModelUnit Value)
  72. {
  73.     m_FixedPosValue = Value;
  74. }
  75. void    CAxisRenderer::SetTextAlign(ETextAlign Type)
  76. {
  77.     m_TextAlignType = Type;
  78. }
  79. // function tales sTempl that is a printf-style temaplate for formatting a value of
  80. // TModelUnit type
  81. void    CAxisRenderer::SetFormattingTemplate(const string& sTempl)
  82. {
  83.     m_sFormatTempl = sTempl;
  84. }
  85. /*###void    CAxisRenderer::SetFont(CGlBitmapFont::EFont Type)
  86. {
  87.     m_Font = CGlBitmapFont(Type);
  88. }*/
  89. void    CAxisRenderer::SetTickStyle(ETickStyle Style)
  90. {
  91.     m_TickStyle = Style;
  92. }
  93. void    CAxisRenderer::SetTickSize(int SizePix)
  94. {
  95.     m_TickSize = SizePix;
  96. }
  97. void    CAxisRenderer::SetScaleType(EScaleType Type)   
  98. {   
  99.     m_Type = Type;  
  100. }
  101. void    CAxisRenderer::SetColor(CGlColor Color)
  102. {
  103.     m_Color = Color;
  104. }
  105. void    CAxisRenderer::SetTextColor(CGlColor Color)
  106. {
  107.     m_TextColor = Color;
  108. }
  109. void    CAxisRenderer::Render(CGlPane* pAreaPane, CGlPane* pGraphPane, CRegularGridGen* pGen)
  110. {
  111.     // in order for CGlPane::Project() to work we need to initilize pane
  112.     pGraphPane->OpenOrtho();
  113.     pGraphPane->Close();
  114.     TVPRect   rcVP = pAreaPane->GetViewport();
  115.     TVPRect   rcGraphVP = pGraphPane->GetViewport();
  116.     // now drawing
  117.     pAreaPane->OpenPixels();    
  118.     
  119.     pGen->GenerateGrid(pGraphPane, m_bHorz);
  120.     x_GenerateLabels(pAreaPane, pGraphPane, pGen);
  121.     glLineWidth(0.1f);
  122.     
  123.     int dTickMin = (m_TickStyle == eMinSide || m_TickStyle == eBothSides) ? -m_TickSize : 0;
  124.     int dTickMax = (m_TickStyle == eMaxSide || m_TickStyle == eBothSides) ? m_TickSize : 0;
  125.      
  126.     if(m_bHorz) {
  127.         x_DrawHorzLabels(pAreaPane, pGraphPane, pGen, dTickMin, dTickMax);        
  128.     } else {
  129.         int vpX = 0;
  130.         switch(m_PosType) {
  131.         case ePosMin: vpX = rcGraphVP.Left(); break;
  132.         case ePosMax: vpX = rcGraphVP.Right(); break;
  133.         case ePosFixedValue: vpX = pGraphPane->ProjectX(m_FixedPosValue); break;
  134.         }
  135.         
  136.         glColorC(m_Color);        
  137.         glBegin(GL_LINES);
  138.             // draw axis
  139.             double vpBottom = rcGraphVP.Bottom();
  140.             double vpTop = rcGraphVP.Top();
  141.         
  142.             glVertex2d(vpX, vpBottom);
  143.             glVertex2d(vpX, vpTop);
  144.             
  145.             if (m_TickStyle != eNoTick) {
  146.                 // draw Ticks        
  147.                 ITERATE(CRegularGridGen, it, *pGen) {
  148.                     double wY = *it;
  149.                     int vpY = pGraphPane->ProjectY(wY);
  150.                     if(vpY >= vpBottom  &&  vpY <= vpTop)
  151.                     {
  152.                         glVertex2d(vpX + dTickMin, vpY);
  153.                         glVertex2d(vpX + dTickMax, vpY);
  154.                     }
  155.                 }
  156.             }
  157.         glEnd();
  158.         // drawing Labels
  159.         x_LayoutLabels(rcVP.Bottom(), rcVP.Top());
  160.         glColorC(m_TextColor);
  161.         int H = (int)m_Font.TextHeight();        
  162.         ITERATE(vector<SLabelDescr>, itL, m_vLabels) {
  163.             if (itL->m_bVisible) {
  164.                 int tX = vpX;
  165.                 switch (m_TextAlignType) {
  166.                 case eLeftText: tX +=10; break;
  167.                 case eRightText: tX -= 10 + itL->m_Width; break;
  168.                 case eCenterText: tX -= itL->m_Width / 2; break;
  169.                 }
  170.                 int tY = itL->m_Pos - H/2;        
  171.                 m_Font.TextOut(tX, tY, itL->m_Str.c_str());
  172.             }            
  173.         }
  174.     }    
  175.     pAreaPane->Close();
  176. }
  177. void    CAxisRenderer::x_DrawHorzLabels(CGlPane* pAreaPane, CGlPane* pGraphPane, CRegularGridGen* pGen, int dTickMin, int dTickMax)
  178. {
  179.     TVPRect   rcVP = pAreaPane->GetViewport();   
  180.     TVPRect   rcGraphVP = pGraphPane->GetViewport();
  181.     int vpY = 0;
  182.     switch(m_PosType) {
  183.     case ePosMin: vpY = rcGraphVP.Bottom(); break;
  184.     case ePosMax: vpY = rcGraphVP.Top(); break;
  185.     case ePosFixedValue: vpY = pGraphPane->ProjectY(m_FixedPosValue); break;
  186.     }
  187.     glColorC(m_Color);            
  188.     glBegin(GL_LINES);
  189.     
  190.         // draw axis
  191.         int vpLeft = pGraphPane->GetViewport().Left();
  192.         int vpRight = pGraphPane->GetViewport().Right();        
  193.         glVertex2d(vpLeft, vpY);
  194.         glVertex2d(vpRight, vpY);
  195.         if (m_TickStyle != eNoTick) {
  196.             // draw Ticks        
  197.             ITERATE(CRegularGridGen, it, *pGen) {
  198.                 double wX = *it;
  199.                 int vpX = pGraphPane->ProjectX(wX);
  200.                 if(vpX >= vpLeft  &&  vpX <= vpRight)
  201.                 {
  202.                     glVertex2d(vpX, vpY + dTickMin);
  203.                     glVertex2d(vpX, vpY + dTickMax);
  204.                 }
  205.             }
  206.         }
  207.     glEnd();
  208.     // drawing Labels
  209.     x_LayoutLabels(rcVP.Left(), rcVP.Right());
  210.     glColorC(m_TextColor);
  211.     int tY = vpY - 10 - (int) m_Font.TextHeight();        
  212.     ITERATE(vector<SLabelDescr>, itL, m_vLabels) {
  213.         if (itL->m_bVisible) {
  214.             int tX = itL->m_Pos;
  215.             switch (m_TextAlignType) {
  216.             case eLeftText: break;
  217.             case eRightText: tX -= itL->m_Width; break;
  218.             case eCenterText: tX -= itL->m_Width / 2; break;
  219.             }
  220.                          
  221.             m_Font.TextOut(tX, tY, itL->m_Str.c_str());
  222.         }            
  223.     }
  224. }
  225. void    CAxisRenderer::x_GenerateLabels(CGlPane* pAreaPane, CGlPane* pGraphPane, CRegularGridGen* pGen)
  226. {
  227.     m_vLabels.resize(0);
  228.     int vpZ, vpStart, vpFinish;
  229.     ITERATE(CRegularGridGen, it, *pGen) {            
  230.         if(m_bHorz) {
  231.             vpZ = pGraphPane->ProjectX(*it);
  232.             vpStart = pGraphPane->GetViewport().Left();
  233.             vpFinish = pGraphPane->GetViewport().Right();
  234.         } else {
  235.             vpZ = pGraphPane->ProjectY(*it);
  236.             vpStart = pGraphPane->GetViewport().Bottom();
  237.             vpFinish = pGraphPane->GetViewport().Top();                    
  238.         }
  239.     
  240.         if(vpZ >= vpStart  &&  vpZ <= vpFinish)
  241.         {
  242.             SLabelDescr Label;
  243.             Label.m_Value = *it;
  244.             Label.m_Pos = vpZ;
  245.             TModelUnit V = x_GetLabelValue(*it);
  246.             Label.m_Str = x_FormatLabel(V);
  247.             Label.m_Width = (int)m_Font.TextWidth(Label.m_Str.c_str());
  248.             m_vLabels.push_back(Label);
  249.         }
  250.     }
  251. }
  252. #define LABEL_SPACE_X 8
  253. #define LABEL_SPACE_Y 1
  254. void    CAxisRenderer::x_LayoutLabels(int Start, int Finish)
  255. {
  256.     int Min = Start;
  257.     int Max = Finish;
  258.     int Space = m_bHorz ? LABEL_SPACE_X : LABEL_SPACE_Y;
  259.     int H = (int)m_Font.TextHeight();
  260.     NON_CONST_ITERATE(vector<SLabelDescr>, it, m_vLabels) {
  261.         int Size = m_bHorz ? it->m_Width : H;
  262.         int LabelMin = it->m_Pos - Size / 2;
  263.         int LabelMax = LabelMin + Size + Space;
  264.         if (LabelMin < Min  || LabelMax > Max)
  265.             it->m_bVisible = false;
  266.         else {
  267.             it->m_bVisible = true;
  268.             Min = LabelMax + 1;
  269.         }
  270.     }
  271. }
  272. string CAxisRenderer::x_FormatLabel(TModelUnit Value)
  273. {
  274.     char S[200];
  275.     sprintf(S, m_sFormatTempl.c_str(), Value);
  276.     return S;
  277. }
  278. TModelUnit  CAxisRenderer::x_GetLabelValue(TModelUnit Value)
  279. {
  280.   switch(m_Type) {
  281.   case eLog2: return pow(2.0, Value);
  282.   case eLog10: return pow(10.0, Value);
  283.   case eLn: return exp(Value);
  284.   case eDec: return Value;
  285.   default: {
  286.     _ASSERT(false);
  287.     return -1;
  288.   }
  289.   }
  290. }
  291. ////////////////////////////////////////////////////////////////////////////////
  292. /// class CAxisArea
  293. CAxisArea::CAxisArea()
  294. : m_BoundsColor(0.5f, 0.5f, 0.5f)
  295. {
  296. }
  297. CAxisArea::~CAxisArea()
  298. {
  299. }
  300. //override this functions in order to customize axes
  301. void    CAxisArea::SetupAxes()
  302. {
  303.     static const int kDefTickSize = 4;
  304.     m_XAxis.SetHorizontal(true);
  305.     m_XAxis.SetTickSize(kDefTickSize);
  306.     m_XAxis.SetTickStyle(CAxisRenderer::eBothSides);
  307.     m_XAxis.SetTextAlign(CAxisRenderer::eCenterText);
  308.     m_YAxis.SetHorizontal(false);
  309.     m_YAxis.SetTickSize(kDefTickSize);
  310.     m_YAxis.SetTickStyle(CAxisRenderer::eBothSides);
  311.     m_YAxis.SetTextAlign(CAxisRenderer::eRightText);
  312. }
  313. void    CAxisArea::SetScaleType(EScaleType TypeX, EScaleType TypeY)
  314. {
  315.     m_XAxis.SetScaleType(TypeX);
  316.     m_YAxis.SetScaleType(TypeY);
  317. }
  318. void    CAxisArea::Render(CGlPane* pAreaPane, CGlPane* pGraphPane, CRegularGridGen* pGen)
  319. {
  320.     //drawing bounding rectangle
  321.     /*pAreaPane->OpenPixels();    
  322.     
  323.     TVPRect rcGraphVP = pGraphPane->GetViewport();
  324.     
  325.     glColorC(m_BoundsColor);    
  326.     glPolygonMode(GL_FRONT, GL_LINE);
  327.     glRectd(rcGraphVP.Left(), rcGraphVP.Bottom(), rcGraphVP.Right(), rcGraphVP.Top());
  328.    
  329.     pAreaPane->Close(); */
  330.     // drawing Axes
  331.     m_XAxis.Render(pAreaPane, pGraphPane, pGen);
  332.     m_YAxis.Render(pAreaPane, pGraphPane, pGen);
  333. }
  334. END_NCBI_SCOPE
  335.   
  336. /*
  337.  * ===========================================================================
  338.  * $Log: axis.cpp,v $
  339.  * Revision 1000.2  2004/06/01 20:49:18  gouriano
  340.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.9
  341.  *
  342.  * Revision 1.9  2004/05/21 22:27:42  gorelenk
  343.  * Added PCH ncbi_pch.hpp
  344.  *
  345.  * Revision 1.8  2004/03/19 14:56:43  gorelenk
  346.  * Fixed compilation errors on MSVC 7.10
  347.  *
  348.  * Revision 1.7  2003/09/25 20:38:29  yazhuk
  349.  * Refactored rendering
  350.  *
  351.  * Revision 1.6  2003/09/17 16:24:15  dicuccio
  352.  * Use CGlBitmapFont instead of CGlutFont
  353.  *
  354.  * Revision 1.5  2003/08/19 00:35:52  dicuccio
  355.  * Fixed compilation errors following API change for IGlFont
  356.  *
  357.  * Revision 1.4  2003/08/12 21:18:52  ucko
  358.  * #include <stdio.h> for sprintf
  359.  *
  360.  * Revision 1.3  2003/08/11 16:10:57  yazhuk
  361.  * Compilation fixes for GCC
  362.  *
  363.  * Revision 1.2  2003/08/08 15:59:36  yazhuk
  364.  * Comments added
  365.  *
  366.  * ===========================================================================
  367.  */
  368.