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 + -
显示快捷键?