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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: combo_chart.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 20:49:21  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.5
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: combo_chart.cpp,v 1000.1 2004/06/01 20:49:21 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 <math.h>
  41. #include <gui/opengl/glcolortable.hpp>
  42. #include <gui/graph/combo_chart.hpp>
  43. #include <gui/graph/igraph_utils.hpp>
  44. BEGIN_NCBI_SCOPE
  45. ///////////////////////////////////////////////////////////////////////////////
  46. /// class CComboChart 
  47. CComboChart::CComboChart()
  48. : m_Style(eLinePlot),
  49.   m_MarkerSize(6)
  50. {
  51. }
  52. CComboChart::~CComboChart()
  53. {
  54. }
  55. bool    CComboChart::SetDataSource(IGraphDataSource* pDS)
  56. {
  57.     IComboChartDataSource* pComboChartDS = dynamic_cast<IComboChartDataSource*>(pDS);
  58.     bool bOk =  pComboChartDS!= NULL;
  59.     CGraphBase::SetDataSource(bOk ? pDS : NULL);
  60.     
  61.     int SeriesN = pComboChartDS ? pComboChartDS->GetArraysCount() : 0;
  62.     //m_Labels.GetContainer().resize(SeriesN);
  63.     m_Colors.GetContainer().resize(SeriesN);
  64.     m_Markers.GetContainer().resize(SeriesN);
  65.     
  66.     CGlColor DefC(0.5f, 0.5f, 0.5f);
  67.     for( int i = 0; i <  SeriesN; i++ ) {
  68.         m_Colors.GetContainer()[i] = DefC;
  69.         m_Markers.GetContainer()[i] = CGraphDotMarker::eNone;
  70.     }
  71.     return bOk;
  72. }
  73. CGlColor   CComboChart::GetColor(int iSeries)   const
  74. {
  75.     return m_Colors.GetContainer()[iSeries];
  76. }
  77. void    CComboChart::SetColor(int iSeries, CGlColor Color)
  78. {
  79.     m_Colors.GetContainer()[iSeries] = Color;
  80. }
  81. void    CComboChart::AssignAutoColors()
  82. {
  83.     TColorAdapter::TCont& Cont = m_Colors.GetContainer();
  84.      
  85.     int N = Cont.size();
  86.     CGlColorTable Table(N);
  87.     for( int i = 0; i < N;  i++ ) 
  88.         Cont[i] = Table.GetColor(i);
  89. }
  90. CGraphDotMarker::EMarkerType  CComboChart::GetMarkerType(int iSeries)  const
  91. {
  92.     return x_GetMarker(iSeries);
  93. }
  94. void    CComboChart::SetMarkerType(int iSeries, CGraphDotMarker::EMarkerType Type)
  95. {
  96.     m_Markers.GetContainer()[iSeries] = Type;
  97. }
  98. void    CComboChart::AssignAutoMarkers()
  99. {
  100.     const int eStart = CGraphDotMarker::eRect;
  101.     const int eEnd = CGraphDotMarker::eCross;
  102.     int eN = eEnd - eStart + 1;
  103.     
  104.     TIntAdapter::TCont& Cont = m_Markers.GetContainer();
  105.     for( TIntAdapter::TCont::size_type i = 0; i < Cont.size();  i++ ) {
  106.         int iType = eStart + (i % eN);
  107.         Cont[i] = static_cast<CGraphDotMarker::EMarkerType>(iType);
  108.     }
  109. }
  110. void    CComboChart::Render(CGlPane* pPane)
  111. {
  112.     _ASSERT(pPane);
  113.     IComboChartDataSource* pSource = GetComboChartDataSource();
  114.     if(pPane && pSource) {        
  115.         pPane->OpenOrtho();
  116.         try {            
  117.             TModelRect rcVisible = pPane->GetVisibleRect();
  118.             int iStart = (int) floor(rcVisible.Left());
  119.             int iEnd = (int) ceil(rcVisible.Right());
  120.             
  121.             if (m_Style == eLinePlot) {
  122.                 iStart--; iEnd++; // extend range to draw lines crossing bounds
  123.             }
  124.             iStart = max(iStart, 0); 
  125.             if (pSource->GetArraysCount() > 0) {
  126.                 INumericArray* pValues = pSource->GetValueArray(0);
  127.                 iEnd = min(iEnd, pValues->GetSize() - 1);
  128.             }
  129.             
  130.             switch(m_Style) {
  131.             case eLinePlot: x_RenderLinePlot(iStart, iEnd, pPane);  break;
  132.             case eBarChart: x_RenderBarChart(iStart, iEnd, pPane); break;
  133.             case eStackedBarChart: x_RenderStackedBarChart(iStart, iEnd); break;
  134.             case ePercentBarChart: x_RenderPercentBarChart(iStart, iEnd); break;
  135.             }//switch
  136.         }
  137.         catch(...)  {
  138.             //need to trace it
  139.         }
  140.         pPane->Close();
  141.     }
  142. }
  143. void    CComboChart::x_RenderLinePlot(int iStart, int iEnd, CGlPane* pPane)
  144. {
  145.     IComboChartDataSource* pSource = GetComboChartDataSource();
  146.     double MarkerW = pPane->UnProjectWidth(m_MarkerSize);
  147.     double MarkerH = pPane->UnProjectHeight(m_MarkerSize);
  148.     int SerN = pSource->GetArraysCount(); //###
  149.     for( int iSer=0;  iSer<SerN; iSer++  )   {
  150.         //drawing polyline for current Series
  151.         INumericArray* pValues = pSource->GetValueArray(iSer);
  152.         
  153.         glColorC(x_GetColor(iSer));
  154.         glBegin(GL_LINE_STRIP);
  155.         for( int i = iStart;  i<=iEnd;  i++ )    {
  156.             TModelUnit V = pValues->GetElem(i);
  157.             glVertex2d(i + 0.5, V);
  158.             
  159.         }
  160.         glEnd();
  161.         for( int i = iStart;  i<=iEnd;  i++ )    {
  162.             TModelUnit V = pValues->GetElem(i);
  163.             CGraphDotMarker::RenderMarker(i + 0.5, V, MarkerW, MarkerH, x_GetMarker(iSer));
  164.         }
  165.     }
  166. }
  167. void CComboChart::x_RenderBarChart(int iStart, int iEnd, CGlPane* pPane)
  168. {
  169.     IComboChartDataSource* pSource = GetComboChartDataSource();
  170.     TModelUnit BottomY = pPane->GetVisibleRect().Bottom();
  171.     int SerN = pSource->GetArraysCount();
  172.     TModelUnit BarW = 1.0 / SerN;
  173.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  174.     for( int iSer = 0;  iSer < SerN;  iSer++ )   {
  175.         //drawing current Series
  176.         INumericArray* pValues = pSource->GetValueArray(iSer);
  177.         glColorC(x_GetColor(iSer));
  178.         double dL = BarW * (iSer + 0.2);
  179.         double dR = BarW * (iSer + 0.8);
  180.         for( int i = iStart;  i<=iEnd; i++ )    {
  181.             TModelUnit V = pValues->GetElem(i);
  182.             TModelUnit Xl = dL + i;
  183.             TModelUnit Xr = dR + i;
  184.             glRectd(Xl, BottomY, Xr, V);        
  185.         }                
  186.     }
  187. }
  188. void CComboChart::x_RenderStackedBarChart(int iStart, int iEnd)
  189. {
  190.     IComboChartDataSource* pSource = GetComboChartDataSource();
  191.     int SerN = pSource->GetArraysCount();
  192.     double dL = 0.2; //##
  193.     double dR = 0.8;
  194.     
  195.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  196.     for( int i = iStart;  i <= iEnd; i++ )    {
  197.         // drawing column
  198.         TModelUnit Min = 0;
  199.         TModelUnit Max = 0;
  200.         
  201.         for( int iSer = 0;  iSer < SerN; iSer++  )   {        
  202.             INumericArray* pValues = pSource->GetValueArray(iSer);
  203.             //nst SSeriesProperties& Prop = GetProperties(iSer);
  204.             glColorC(x_GetColor(iSer));
  205.             
  206.             TModelUnit V = pValues->GetElem(i);
  207.             TModelUnit Top, Bottom;
  208.             if(V>0) {
  209.                 Bottom = Max;
  210.                 Top = Max += V;                
  211.             } else {
  212.                 Top = Min;
  213.                 Bottom = Min += V;
  214.             }
  215.             glRectd(i + dL, Bottom, i + dR, Top);        
  216.         }                
  217.     }
  218. }
  219. void CComboChart::x_RenderPercentBarChart(int iStart, int iEnd)
  220. {
  221.     IComboChartDataSource* pSource = GetComboChartDataSource();
  222.     int SerN = pSource->GetArraysCount();
  223.     double dL = 0.2;
  224.     double dR = 0.8;
  225.     
  226.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  227.     for( int i = iStart;  i<=iEnd; i++ )    {
  228.         // drawing column
  229.         TModelUnit Sum = 0;
  230.         for( int iSer = 0;  iSer < SerN; iSer++  )  {
  231.             INumericArray* pValues = pSource->GetValueArray(iSer);
  232.             Sum += pValues->GetElem(i);
  233.         }
  234.         if(Sum > 0) { // otherwise - skip this column
  235.             TModelUnit kY = 100.0 / Sum;
  236.             TModelUnit Bottom = 0;
  237.             for( int iSer = 0;  iSer < SerN;  iSer++ )   {        
  238.                 INumericArray* pValues = pSource->GetValueArray(iSer);
  239.                 //nst SSeriesProperties& Prop = GetProperties(iSer);
  240.                 glColorC(x_GetColor(iSer));
  241.                         
  242.                 TModelUnit V = pValues->GetElem(i);     
  243.                 V *= kY;
  244.                 glRectd(i + dL, Bottom, i + dR, Bottom + V);        
  245.                 Bottom += V;
  246.             }                
  247.         }
  248.     }
  249. }
  250. void    CComboChart::CalculateLimits()
  251. {
  252.     IComboChartDataSource* pSource = GetComboChartDataSource();
  253.     if(pSource && pSource->GetArraysCount()) {
  254.         //set horizontal limits
  255.         m_Limits.SetLeft(0);
  256.         INumericArray* pArray = pSource->GetValueArray(0);
  257.         int Right = max(pArray->GetSize(), 1); // if no elems available, expand range to 1
  258.         m_Limits.SetRight(Right);
  259.         
  260.         // calculate vertical limits
  261.         switch(m_Style) {
  262.         case eLinePlot:
  263.         case eBarChart: {
  264.             TModelUnit Min = 0, Max = 0;
  265.             pSource->CalculateMinMax(Min, Max);
  266.             if(Max <= Min)
  267.                 Min = Max - 1;
  268.             m_Limits.SetBottom(Min);
  269.             m_Limits.SetTop(Max);
  270.             break;
  271.         }
  272.         case eStackedBarChart: {
  273.             TModelUnit Min = 0, Max = 0;
  274.             
  275.             int SerN = pSource->GetArraysCount();
  276.             if(SerN > 0) {            
  277.                 INumericArray* pValues = pSource->GetValueArray(0);
  278.                 int ElemN = pValues->GetSize();
  279.                 
  280.             
  281.                 for( int iElem = 0; iElem < ElemN;  iElem++ )   {
  282.                     // for each  Elem calculate local Min and Max                
  283.                     TModelUnit LocMin = 0, LocMax = 0;
  284.                 
  285.                     for( int iSer = 0;  iSer < SerN;  iSer++  )   {
  286.                         INumericArray* pValues = pSource->GetValueArray(iSer); 
  287.                         TModelUnit V = pValues->GetElem(iElem);
  288.                         if(V>0) 
  289.                                 LocMax += V;
  290.                         else    LocMin += V;
  291.                     }
  292.                     Min = min(Min, LocMin);
  293.                     Max= max(Max, LocMax);
  294.                 }
  295.             }
  296.             else Max = 1;
  297.             m_Limits.SetBottom(Min);
  298.             m_Limits.SetTop(Max);       
  299.             break;
  300.         }
  301.         case ePercentBarChart:  {
  302.             m_Limits.SetBottom(0.0);
  303.             m_Limits.SetTop(100.0);
  304.             break;
  305.         }
  306.         } //switch              
  307.     }
  308.     else m_Limits.Init();
  309. }
  310. bool    CComboChart::ShowMarkers()
  311. {
  312.     return m_Style == eLinePlot;
  313. }
  314. IStringArray*   CComboChart::GetLabelArray()
  315. {
  316.     IComboChartDataSource*    pDS = GetComboChartDataSource();
  317.     return pDS ? pDS->GetLabelsArray() : NULL;
  318. }
  319. IColorArray*    CComboChart::GetColorArray()
  320. {
  321.     return static_cast<IColorArray*>(&m_Colors);
  322. }
  323. INumericArray*  CComboChart::GetMarkerArray()
  324. {
  325.     return static_cast<INumericArray*>(&m_Markers);
  326. }
  327. ///////////////////////////////////////////////////////////////////////////////
  328. /// CComboChartDataSource
  329. void    CComboChartDataSource::CreateArrays()
  330. {
  331.     CSeriesBase::CreateArrays();
  332.     TStringAdapter* pCAd = new TStringAdapter(m_ArrCount);
  333.     AddArray(static_cast<IDataArray*>(pCAd));
  334.     
  335.     for ( int i = 0;  i < m_ArrCount;  i++ ) {
  336.         TValueAdapter* pValAd = new TValueAdapter(m_Length);
  337.         AddArray(static_cast<IDataArray*>(pValAd));
  338.     }
  339. }
  340. void    CComboChartDataSource::CalculateMinMax(TModelUnit& Min, TModelUnit& Max)
  341. {
  342.     bool bFirst = true;
  343.     Min = Max = 0;
  344.     int ArrN = x_GetArraysCount();
  345.     for( int i = 0; i < ArrN ;  i++ ) {
  346.         TValueCont&   Cont = GetValueContainer(i);
  347.         
  348. //        for( TIntAdapter::TCont::size_type j = 0;  j < Cont.size();  j++ ) {}
  349. ITERATE( TValueCont, itEl, Cont) {
  350.             if (bFirst) {
  351.                 Min = Max = *itEl;//Cont[j];
  352.                 bFirst = false;
  353.             } else {
  354.                 Min = min(Min, *itEl);
  355.                 Max = max(Max, *itEl);
  356.             }
  357.         }
  358.     }
  359. }
  360. END_NCBI_SCOPE
  361. /*
  362.  * ===========================================================================
  363.  * $Log: combo_chart.cpp,v $
  364.  * Revision 1000.1  2004/06/01 20:49:21  gouriano
  365.  * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.5
  366.  *
  367.  * Revision 1.5  2004/05/21 22:27:42  gorelenk
  368.  * Added PCH ncbi_pch.hpp
  369.  *
  370.  * Revision 1.4  2004/05/11 20:25:16  yazhuk
  371.  * Suppressed  the second call to CalculateLimits()
  372.  *
  373.  * Revision 1.3  2003/08/11 16:10:57  yazhuk
  374.  * Compilation fixes for GCC
  375.  *
  376.  * Revision 1.2  2003/08/08 15:59:36  yazhuk
  377.  * Comments added
  378.  *
  379.  * ===========================================================================
  380.  */
  381.