KDEUI
kplotaxis.cpp
Go to the documentation of this file.
00001 /* -*- C++ -*- 00002 This file is part of the KDE libraries 00003 Copyright (C) 2005 Andreas Nicolai <Andreas.Nicolai@gmx.net> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include "kplotaxis.h" 00022 00023 #include <math.h> //for log10(), pow(), modf() 00024 #include <kdebug.h> 00025 00026 class KPlotAxis::Private 00027 { 00028 public: 00029 Private( KPlotAxis *qq ) 00030 : q( qq ) 00031 , m_visible( true ) 00032 , m_showTickLabels( false ) 00033 , m_labelFmt( 'g' ) 00034 , m_labelFieldWidth( 0 ) 00035 , m_labelPrec( -1 ) 00036 { 00037 } 00038 00039 KPlotAxis *q; 00040 00041 bool m_visible : 1; // Property "visible" defines if Axis is drawn or not. 00042 bool m_showTickLabels : 1; 00043 char m_labelFmt; // Number format for number labels, see QString::arg() 00044 QString m_label; // The label of the axis. 00045 int m_labelFieldWidth; // Field width for number labels, see QString::arg() 00046 int m_labelPrec; // Number precision for number labels, see QString::arg() 00047 QList<double> m_MajorTickMarks, m_MinorTickMarks; 00048 }; 00049 00050 KPlotAxis::KPlotAxis( const QString &label ) 00051 : d( new Private( this ) ) 00052 { 00053 d->m_label = label; 00054 } 00055 00056 KPlotAxis::~KPlotAxis() 00057 { 00058 delete d; 00059 } 00060 00061 bool KPlotAxis::isVisible() const 00062 { 00063 return d->m_visible; 00064 } 00065 00066 void KPlotAxis::setVisible( bool visible ) 00067 { 00068 d->m_visible = visible; 00069 } 00070 00071 bool KPlotAxis::areTickLabelsShown() const 00072 { 00073 return d->m_showTickLabels; 00074 } 00075 00076 void KPlotAxis::setTickLabelsShown( bool b ) 00077 { 00078 d->m_showTickLabels = b; 00079 } 00080 00081 void KPlotAxis::setLabel( const QString& label ) 00082 { 00083 d->m_label = label; 00084 } 00085 00086 QString KPlotAxis::label() const 00087 { 00088 return d->m_label; 00089 } 00090 00091 void KPlotAxis::setTickLabelFormat( char format, int fieldWidth, int precision ) 00092 { 00093 d->m_labelFieldWidth = fieldWidth; 00094 d->m_labelFmt = format; 00095 d->m_labelPrec = precision; 00096 } 00097 00098 int KPlotAxis::tickLabelWidth() const 00099 { 00100 return d->m_labelFieldWidth; 00101 } 00102 00103 char KPlotAxis::tickLabelFormat() const 00104 { 00105 return d->m_labelFmt; 00106 } 00107 00108 int KPlotAxis::tickLabelPrecision() const 00109 { 00110 return d->m_labelPrec; 00111 } 00112 00113 void KPlotAxis::setTickMarks( double x0, double length ) { 00114 d->m_MajorTickMarks.clear(); 00115 d->m_MinorTickMarks.clear(); 00116 00117 //s is the power-of-ten factor of length: 00118 //length = t * s; s = 10^(pwr). e.g., length=350.0 then t=3.5, s = 100.0; pwr = 2.0 00119 double pwr = 0.0; 00120 modf( log10( length ), &pwr ); 00121 double s = pow( 10.0, pwr ); 00122 double t = length / s; 00123 00124 double TickDistance = 0.0; //The distance between major tickmarks 00125 int NumMajorTicks = 0; //will be between 3 and 5 00126 int NumMinorTicks = 0; //The number of minor ticks between major ticks (will be 4 or 5) 00127 00128 //adjust s and t such that t is between 3 and 5: 00129 if ( t < 3.0 ) { 00130 t *= 10.0; 00131 s /= 10.0; 00132 // t is now between 3 and 30 00133 } 00134 00135 if ( t < 6.0 ) { //accept current values 00136 TickDistance = s; 00137 NumMajorTicks = int( t ); 00138 NumMinorTicks = 5; 00139 } else if ( t < 10.0 ) { // adjust by a factor of 2 00140 TickDistance = s * 2.0; 00141 NumMajorTicks = int( t / 2.0 ); 00142 NumMinorTicks = 4; 00143 } else if ( t < 20.0 ) { //adjust by a factor of 4 00144 TickDistance = s * 4.0; 00145 NumMajorTicks = int( t / 4.0 ); 00146 NumMinorTicks = 4; 00147 } else { //adjust by a factor of 5 00148 TickDistance = s * 5.0; 00149 NumMajorTicks = int( t / 5.0 ); 00150 NumMinorTicks = 5; 00151 } 00152 00153 //We have determined the number of tickmarks and their separation 00154 //Now we determine their positions in the Data space. 00155 00156 //Tick0 is the position of a "virtual" tickmark; the first major tickmark 00157 //position beyond the "minimum" edge of the data range. 00158 double Tick0 = x0 - fmod( x0, TickDistance ); 00159 if ( x0 < 0.0 ) { 00160 Tick0 -= TickDistance; 00161 NumMajorTicks++; 00162 } 00163 00164 for ( int i=0; i<NumMajorTicks+1; i++ ) { 00165 double xmaj = Tick0 + i*TickDistance; 00166 if ( xmaj >= x0 && xmaj <= x0 + length ) { 00167 d->m_MajorTickMarks.append( xmaj ); 00168 } 00169 00170 for ( int j=1; j<NumMinorTicks; j++ ) { 00171 double xmin = xmaj + TickDistance*j/NumMinorTicks; 00172 if ( xmin >= x0 && xmin <= x0 + length ) 00173 d->m_MinorTickMarks.append( xmin ); 00174 } 00175 } 00176 } 00177 00178 QString KPlotAxis::tickLabel( double val ) const { 00179 if ( d->m_labelFmt == 't' ) { 00180 while ( val < 0.0 ) val += 24.0; 00181 while ( val >= 24.0 ) val -= 24.0; 00182 00183 int h = int(val); 00184 int m = int( 60.*(val - h) ); 00185 return QString( "%1:%2" ).arg( h, 2, 10, QLatin1Char('0') ).arg( m, 2, 10, QLatin1Char('0') ); 00186 } 00187 00188 return QString( "%1" ).arg( val, d->m_labelFieldWidth, d->m_labelFmt, d->m_labelPrec ); 00189 } 00190 00191 QList< double > KPlotAxis::majorTickMarks() const 00192 { 00193 return d->m_MajorTickMarks; 00194 } 00195 00196 QList< double > KPlotAxis::minorTickMarks() const 00197 { 00198 return d->m_MinorTickMarks; 00199 } 00200
KDE 4.6 API Reference