combo_chart.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:13k
- /*
- * ===========================================================================
- * 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);
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// CComboChartDataSource
- void 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
- *
- * ===========================================================================
- */
-