combo_chart.cpp

来自「ncbi源码」· C++ 代码 · 共 428 行

CPP
428
字号
/* * =========================================================================== * PRODUCTION $Log: combo_chart.cpp,v $ * PRODUCTION Revision 1000.1  2004/06/01 20:49:21  gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.5 * PRODUCTION * =========================================================================== *//*  $Id: combo_chart.cpp,v 1000.1 2004/06/01 20:49:21 gouriano Exp $ * =========================================================================== * *                            PUBLIC DOMAIN NOTICE *               National Center for Biotechnology Information * *  This software/database is a "United States Government Work" under the *  terms of the United States Copyright Act.  It was written as part of *  the author's official duties as a United States Government employee and *  thus cannot be copyrighted.  This software/database is freely available *  to the public for use. The National Library of Medicine and the U.S. *  Government have not placed any restriction on its use or reproduction. * *  Although all reasonable efforts have been taken to ensure the accuracy *  and reliability of the software and data, the NLM and the U.S. *  Government do not and cannot warrant the performance or results that *  may be obtained by using this software or data. The NLM and the U.S. *  Government disclaim all warranties, express or implied, including *  warranties of performance, merchantability or fitness for any particular *  purpose. * *  Please cite the author in any work or product based on this material. * * =========================================================================== * * Authors:  Andrey Yazhuk * * File Description: * */#include <ncbi_pch.hpp>#include <math.h>#include <gui/opengl/glcolortable.hpp>#include <gui/graph/combo_chart.hpp>#include <gui/graph/igraph_utils.hpp>BEGIN_NCBI_SCOPE////////////////////////////////////////////////////////////////////////////////// class CComboChart CComboChart::CComboChart(): m_Style(eLinePlot),  m_MarkerSize(6){}CComboChart::~CComboChart(){}bool    CComboChart::SetDataSource(IGraphDataSource* pDS){    IComboChartDataSource* pComboChartDS = dynamic_cast<IComboChartDataSource*>(pDS);    bool bOk =  pComboChartDS!= NULL;    CGraphBase::SetDataSource(bOk ? pDS : NULL);        int SeriesN = pComboChartDS ? pComboChartDS->GetArraysCount() : 0;    //m_Labels.GetContainer().resize(SeriesN);    m_Colors.GetContainer().resize(SeriesN);    m_Markers.GetContainer().resize(SeriesN);        CGlColor DefC(0.5f, 0.5f, 0.5f);    for( int i = 0; i <  SeriesN; i++ ) {        m_Colors.GetContainer()[i] = DefC;        m_Markers.GetContainer()[i] = CGraphDotMarker::eNone;    }    return bOk;}CGlColor   CComboChart::GetColor(int iSeries)   const{    return m_Colors.GetContainer()[iSeries];}void    CComboChart::SetColor(int iSeries, CGlColor Color){    m_Colors.GetContainer()[iSeries] = Color;}void    CComboChart::AssignAutoColors(){    TColorAdapter::TCont& Cont = m_Colors.GetContainer();         int N = Cont.size();    CGlColorTable Table(N);    for( int i = 0; i < N;  i++ )         Cont[i] = Table.GetColor(i);}CGraphDotMarker::EMarkerType  CComboChart::GetMarkerType(int iSeries)  const{    return x_GetMarker(iSeries);}void    CComboChart::SetMarkerType(int iSeries, CGraphDotMarker::EMarkerType Type){    m_Markers.GetContainer()[iSeries] = Type;}void    CComboChart::AssignAutoMarkers(){    const int eStart = CGraphDotMarker::eRect;    const int eEnd = CGraphDotMarker::eCross;    int eN = eEnd - eStart + 1;        TIntAdapter::TCont& Cont = m_Markers.GetContainer();    for( TIntAdapter::TCont::size_type i = 0; i < Cont.size();  i++ ) {        int iType = eStart + (i % eN);        Cont[i] = static_cast<CGraphDotMarker::EMarkerType>(iType);    }}void    CComboChart::Render(CGlPane* pPane){    _ASSERT(pPane);    IComboChartDataSource* pSource = GetComboChartDataSource();    if(pPane && pSource) {                pPane->OpenOrtho();        try {                        TModelRect rcVisible = pPane->GetVisibleRect();            int iStart = (int) floor(rcVisible.Left());            int iEnd = (int) ceil(rcVisible.Right());                        if (m_Style == eLinePlot) {                iStart--; iEnd++; // extend range to draw lines crossing bounds            }            iStart = max(iStart, 0);             if (pSource->GetArraysCount() > 0) {                INumericArray* pValues = pSource->GetValueArray(0);                iEnd = min(iEnd, pValues->GetSize() - 1);            }                        switch(m_Style) {            case eLinePlot: x_RenderLinePlot(iStart, iEnd, pPane);  break;            case eBarChart: x_RenderBarChart(iStart, iEnd, pPane); break;            case eStackedBarChart: x_RenderStackedBarChart(iStart, iEnd); break;            case ePercentBarChart: x_RenderPercentBarChart(iStart, iEnd); break;            }//switch        }        catch(...)  {            //need to trace it        }        pPane->Close();    }}void    CComboChart::x_RenderLinePlot(int iStart, int iEnd, CGlPane* pPane){    IComboChartDataSource* pSource = GetComboChartDataSource();    double MarkerW = pPane->UnProjectWidth(m_MarkerSize);    double MarkerH = pPane->UnProjectHeight(m_MarkerSize);    int SerN = pSource->GetArraysCount(); //###    for( int iSer=0;  iSer<SerN; iSer++  )   {        //drawing polyline for current Series        INumericArray* pValues = pSource->GetValueArray(iSer);                glColorC(x_GetColor(iSer));        glBegin(GL_LINE_STRIP);        for( int i = iStart;  i<=iEnd;  i++ )    {            TModelUnit V = pValues->GetElem(i);            glVertex2d(i + 0.5, V);                    }        glEnd();        for( int i = iStart;  i<=iEnd;  i++ )    {            TModelUnit V = pValues->GetElem(i);            CGraphDotMarker::RenderMarker(i + 0.5, V, MarkerW, MarkerH, x_GetMarker(iSer));        }    }}void CComboChart::x_RenderBarChart(int iStart, int iEnd, CGlPane* pPane){    IComboChartDataSource* pSource = GetComboChartDataSource();    TModelUnit BottomY = pPane->GetVisibleRect().Bottom();    int SerN = pSource->GetArraysCount();    TModelUnit BarW = 1.0 / SerN;    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);    for( int iSer = 0;  iSer < SerN;  iSer++ )   {        //drawing current Series        INumericArray* pValues = pSource->GetValueArray(iSer);        glColorC(x_GetColor(iSer));        double dL = BarW * (iSer + 0.2);        double dR = BarW * (iSer + 0.8);        for( int i = iStart;  i<=iEnd; i++ )    {            TModelUnit V = pValues->GetElem(i);            TModelUnit Xl = dL + i;            TModelUnit Xr = dR + i;            glRectd(Xl, BottomY, Xr, V);                }                    }}void CComboChart::x_RenderStackedBarChart(int iStart, int iEnd){    IComboChartDataSource* pSource = GetComboChartDataSource();    int SerN = pSource->GetArraysCount();    double dL = 0.2; //##    double dR = 0.8;        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);    for( int i = iStart;  i <= iEnd; i++ )    {        // drawing column        TModelUnit Min = 0;        TModelUnit Max = 0;                for( int iSer = 0;  iSer < SerN; iSer++  )   {                    INumericArray* pValues = pSource->GetValueArray(iSer);            //nst SSeriesProperties& Prop = GetProperties(iSer);            glColorC(x_GetColor(iSer));                        TModelUnit V = pValues->GetElem(i);            TModelUnit Top, Bottom;            if(V>0) {                Bottom = Max;                Top = Max += V;                            } else {                Top = Min;                Bottom = Min += V;            }            glRectd(i + dL, Bottom, i + dR, Top);                }                    }}void CComboChart::x_RenderPercentBarChart(int iStart, int iEnd){    IComboChartDataSource* pSource = GetComboChartDataSource();    int SerN = pSource->GetArraysCount();    double dL = 0.2;    double dR = 0.8;        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);    for( int i = iStart;  i<=iEnd; i++ )    {        // drawing column        TModelUnit Sum = 0;        for( int iSer = 0;  iSer < SerN; iSer++  )  {            INumericArray* pValues = pSource->GetValueArray(iSer);            Sum += pValues->GetElem(i);        }        if(Sum > 0) { // otherwise - skip this column            TModelUnit kY = 100.0 / Sum;            TModelUnit Bottom = 0;            for( int iSer = 0;  iSer < SerN;  iSer++ )   {                        INumericArray* pValues = pSource->GetValueArray(iSer);                //nst SSeriesProperties& Prop = GetProperties(iSer);                glColorC(x_GetColor(iSer));                                        TModelUnit V = pValues->GetElem(i);                     V *= kY;                glRectd(i + dL, Bottom, i + dR, Bottom + V);                        Bottom += V;            }                        }    }}void    CComboChart::CalculateLimits(){    IComboChartDataSource* pSource = GetComboChartDataSource();    if(pSource && pSource->GetArraysCount()) {        //set horizontal limits        m_Limits.SetLeft(0);        INumericArray* pArray = pSource->GetValueArray(0);        int Right = max(pArray->GetSize(), 1); // if no elems available, expand range to 1        m_Limits.SetRight(Right);                // calculate vertical limits        switch(m_Style) {        case eLinePlot:        case eBarChart: {            TModelUnit Min = 0, Max = 0;            pSource->CalculateMinMax(Min, Max);            if(Max <= Min)                Min = Max - 1;            m_Limits.SetBottom(Min);            m_Limits.SetTop(Max);            break;        }        case eStackedBarChart: {            TModelUnit Min = 0, Max = 0;                        int SerN = pSource->GetArraysCount();            if(SerN > 0) {                            INumericArray* pValues = pSource->GetValueArray(0);                int ElemN = pValues->GetSize();                                            for( int iElem = 0; iElem < ElemN;  iElem++ )   {                    // for each  Elem calculate local Min and Max                                    TModelUnit LocMin = 0, LocMax = 0;                                    for( int iSer = 0;  iSer < SerN;  iSer++  )   {                        INumericArray* pValues = pSource->GetValueArray(iSer);                         TModelUnit V = pValues->GetElem(iElem);                        if(V>0)                                 LocMax += V;                        else    LocMin += V;                    }                    Min = min(Min, LocMin);                    Max= max(Max, LocMax);                }            }            else Max = 1;            m_Limits.SetBottom(Min);            m_Limits.SetTop(Max);                   break;        }        case ePercentBarChart:  {            m_Limits.SetBottom(0.0);            m_Limits.SetTop(100.0);            break;        }        } //switch                  }    else m_Limits.Init();}bool    CComboChart::ShowMarkers(){    return m_Style == eLinePlot;}IStringArray*   CComboChart::GetLabelArray(){    IComboChartDataSource*    pDS = GetComboChartDataSource();    return pDS ? pDS->GetLabelsArray() : NULL;}IColorArray*    CComboChart::GetColorArray(){    return static_cast<IColorArray*>(&m_Colors);}INumericArray*  CComboChart::GetMarkerArray(){    return static_cast<INumericArray*>(&m_Markers);}////////////////////////////////////////////////////////////////////////////////// CComboChartDataSourcevoid    CComboChartDataSource::CreateArrays(){    CSeriesBase::CreateArrays();    TStringAdapter* pCAd = new TStringAdapter(m_ArrCount);    AddArray(static_cast<IDataArray*>(pCAd));        for ( int i = 0;  i < m_ArrCount;  i++ ) {        TValueAdapter* pValAd = new TValueAdapter(m_Length);        AddArray(static_cast<IDataArray*>(pValAd));    }}void    CComboChartDataSource::CalculateMinMax(TModelUnit& Min, TModelUnit& Max){    bool bFirst = true;    Min = Max = 0;    int ArrN = x_GetArraysCount();    for( int i = 0; i < ArrN ;  i++ ) {        TValueCont&   Cont = GetValueContainer(i);        //        for( TIntAdapter::TCont::size_type j = 0;  j < Cont.size();  j++ ) {}	ITERATE( TValueCont, itEl, Cont) {            if (bFirst) {                Min = Max = *itEl;//Cont[j];                bFirst = false;            } else {                Min = min(Min, *itEl);                Max = max(Max, *itEl);            }        }    }}END_NCBI_SCOPE/* * =========================================================================== * $Log: combo_chart.cpp,v $ * Revision 1000.1  2004/06/01 20:49:21  gouriano * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.5 * * Revision 1.5  2004/05/21 22:27:42  gorelenk * Added PCH ncbi_pch.hpp * * Revision 1.4  2004/05/11 20:25:16  yazhuk * Suppressed  the second call to CalculateLimits() * * Revision 1.3  2003/08/11 16:10:57  yazhuk * Compilation fixes for GCC * * Revision 1.2  2003/08/08 15:59:36  yazhuk * Comments added * * =========================================================================== */ 

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?