00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "KDChartHiLoPainter.h"
00030 #include <KDChartParams.h>
00031 #include "KDChartTextPiece.h"
00032
00033 #include <qpainter.h>
00034
00035 #include <stdlib.h>
00036
00048 KDChartHiLoPainter::KDChartHiLoPainter( KDChartParams* params ) :
00049 KDChartAxesPainter( params )
00050 {
00051
00052
00053 }
00054
00055
00059 KDChartHiLoPainter::~KDChartHiLoPainter()
00060 {
00061
00062 }
00063
00064
00078 QString KDChartHiLoPainter::fallbackLegendText( uint dataset ) const
00079 {
00080 return QObject::tr( "Value " ) + QString::number( dataset + 1 );
00081 }
00082
00083
00093 uint KDChartHiLoPainter::numLegendFallbackTexts( KDChartTableDataBase* data ) const
00094 {
00095 return data->usedRows();
00096 }
00097
00098
00099 bool KDChartHiLoPainter::isNormalMode() const
00100 {
00101 return KDChartParams::HiLoNormal == params()->hiLoChartSubType();
00102 }
00103
00104 int KDChartHiLoPainter::clipShiftUp( bool, double ) const
00105 {
00106 return 0;
00107 }
00108
00109 void KDChartHiLoPainter::specificPaintData( QPainter* painter,
00110 const QRect& ourClipRect,
00111 KDChartTableDataBase* data,
00112 KDChartDataRegionList* ,
00113 const KDChartAxisParams* axisPara,
00114 bool ,
00115 uint ,
00116 double logWidth,
00117 double areaWidthP1000,
00118 double logHeight,
00119 double axisYOffset,
00120 double ,
00121 double ,
00122 double ,
00123 uint chartDatasetStart,
00124 uint chartDatasetEnd,
00125 uint datasetStart,
00126 uint datasetEnd )
00127 {
00128 double areaHeightP1000 = logHeight / 1000.0;
00129 double averageValueP1000 = ( areaWidthP1000 + areaHeightP1000 ) / 2.0;
00130 int datasetNum=abs(static_cast<int>(chartDatasetEnd-chartDatasetStart))+1;
00131
00132 painter->setPen( params()->outlineDataColor() );
00133
00134
00135
00136 int numValues = 0;
00137 if ( params()->numValues() != -1 )
00138 numValues = params()->numValues();
00139 else
00140 numValues = data->usedCols();
00141
00142
00143
00144 if( (numValues < 2) ||
00145 ((params()->hiLoChartSubType() == KDChartParams::HiLoClose) && (numValues < 3)) ||
00146 ((params()->hiLoChartSubType() == KDChartParams::HiLoOpenClose) && (numValues < 4)) ){
00147 qDebug( "\nNot enough data to display a High/Low Chart!\n" );
00148 qDebug( "type requiring" );
00149 qDebug( "---- ---------" );
00150 qDebug( "High/Low 2 data cells per series" );
00151 qDebug( "High/Low/Close 3 data cells per series" );
00152 qDebug( "High/Low/open/Close 4 data cells per series\n" );
00153 return;
00154 }
00155
00156 double pixelsPerUnit = 0.0;
00157 if( 0.0 != axisPara->trueAxisHigh() - axisPara->trueAxisLow() )
00158 pixelsPerUnit = logHeight / (axisPara->trueAxisHigh() - axisPara->trueAxisLow());
00159 else
00160 pixelsPerUnit = logHeight / 10;
00161
00162
00163 double pointDist = logWidth / (double)datasetNum;
00164
00165
00166 double zeroXAxisI = axisPara->axisZeroLineStartY() - _dataRect.y();
00167
00168 const int nLineWidth = params()->lineWidth();
00169
00170
00171 for ( uint dataset = chartDatasetStart;
00172 dataset <= chartDatasetEnd;
00173 ++dataset ) {
00174
00175
00176 QVariant valueA;
00177 QVariant valueB;
00178 if( dataset >= datasetStart &&
00179 dataset <= datasetEnd &&
00180 data->cellCoord( dataset, 0, valueA, 1 ) &&
00181 data->cellCoord( dataset, 1, valueB, 1 ) &&
00182 QVariant::Double == valueA.type() &&
00183 QVariant::Double == valueB.type() ){
00184 const double cellValue1 = valueA.toDouble();
00185 const double cellValue2 = valueB.toDouble();
00186 const double lowValue = QMIN( cellValue1, cellValue2 );
00187 const double highValue = QMAX( cellValue1, cellValue2 );
00188 const double lowDrawValue = lowValue * pixelsPerUnit;
00189 const double highDrawValue = highValue * pixelsPerUnit;
00190
00191 painter->setPen( QPen( params()->dataColor( dataset ),
00192 nLineWidth ) );
00193
00194 int xpos = static_cast<int>(
00195 pointDist * ( (double)(dataset-chartDatasetStart) + 0.5 ) );
00196 int lowYPos = static_cast<int>( zeroXAxisI - lowDrawValue );
00197 int highYPos = static_cast<int>( zeroXAxisI - highDrawValue );
00198
00199 painter->drawLine( xpos, lowYPos, xpos, highYPos );
00200
00201
00202
00203
00204 int openCloseTickLength = static_cast<int>( pointDist * 0.1 );
00205
00206
00207 bool hasOpen = false, hasClose = false;
00208 double openValue = 0.0, openDrawValue = 0.0,
00209 closeValue = 0.0, closeDrawValue = 0.0;
00210
00211
00212 if( params()->hiLoChartSubType() == KDChartParams::HiLoOpenClose ) {
00213
00214 if( data->cellCoord( dataset, 2, valueA, 1 ) &&
00215 QVariant::Double == valueA.type() ) {
00216 hasOpen = true;
00217 openValue = valueA.toDouble();
00218 openDrawValue = openValue * pixelsPerUnit;
00219 painter->drawLine( xpos - openCloseTickLength,
00220 static_cast<int>( zeroXAxisI - openDrawValue ),
00221 xpos,
00222 static_cast<int>( zeroXAxisI - openDrawValue ) );
00223 }
00224 }
00225
00226
00227
00228
00229
00230 if( ( params()->hiLoChartSubType() == KDChartParams::HiLoClose &&
00231 data->cellCoord( dataset, 2, valueA, 1 ) &&
00232 QVariant::Double == valueA.type() ) ||
00233 ( params()->hiLoChartSubType() == KDChartParams::HiLoOpenClose &&
00234 data->cellCoord( dataset, 3, valueB, 1 ) &&
00235 QVariant::Double == valueB.type() ) ) {
00236 hasClose = true;
00237 closeValue = ( params()->hiLoChartSubType() == KDChartParams::HiLoClose )
00238 ? valueA.toDouble()
00239 : valueB.toDouble();
00240 closeDrawValue = closeValue * pixelsPerUnit;
00241 painter->drawLine( xpos,
00242 static_cast<int>( zeroXAxisI - closeDrawValue ),
00243 xpos + openCloseTickLength,
00244 static_cast<int>( zeroXAxisI - closeDrawValue ) );
00245 }
00246
00247
00248 if( params()->hiLoChartPrintLowValues() ) {
00249
00250 QFont theFont( params()->hiLoChartLowValuesFont() );
00251 if ( params()->hiLoChartLowValuesUseFontRelSize() ) {
00252 int nTxtHeight =
00253 static_cast < int > ( params()->hiLoChartLowValuesFontRelSize()
00254 * averageValueP1000 );
00255 theFont.setPointSizeFloat( nTxtHeight );
00256 }
00257 KDChartTextPiece lowText( painter, QString::number( lowValue ),
00258 theFont );
00259 int width = lowText.width();
00260 int height = lowText.height();
00261
00262
00263 int valX = 0, valY = 0;
00264
00265
00266
00267 if( zeroXAxisI - lowDrawValue + height < axisYOffset+logHeight ) {
00268
00269 valX = xpos - ( width / 2 );
00270 valY = (int)lowDrawValue - lowText.fontLeading();
00271 } else {
00272
00273 if( !hasOpen || height < openDrawValue ) {
00274
00275
00276 valX = xpos - width - nLineWidth;
00277 valY = static_cast<int>(zeroXAxisI)
00278 - lowYPos
00279 + height/2
00280 + nLineWidth/2;
00281 } else
00282 ;
00283 }
00284 lowText.draw( painter,
00285 valX, static_cast<int>( zeroXAxisI - valY ),
00286 ourClipRect,
00287 params()->hiLoChartLowValuesColor() );
00288 }
00289
00290
00291 if( params()->hiLoChartPrintHighValues() ) {
00292
00293 QFont theFont( params()->hiLoChartHighValuesFont() );
00294 if ( params()->hiLoChartHighValuesUseFontRelSize() ) {
00295 int nTxtHeight =
00296 static_cast < int > ( params()->hiLoChartHighValuesFontRelSize()
00297 * averageValueP1000 );
00298 theFont.setPointSizeFloat( nTxtHeight );
00299 }
00300 KDChartTextPiece highText( painter, QString::number( highValue ),
00301 theFont );
00302 int width = highText.width();
00303 int height = highText.height();
00304
00305
00306 int valX = 0, valY = 0;
00307 if( zeroXAxisI - highDrawValue - height > axisYOffset ) {
00308
00309 valX = xpos - ( width / 2 );
00310 valY = (int)highDrawValue + highText.fontLeading() + height;
00311 } else {
00312
00313 if( !hasClose ||
00314 height < ( _dataRect.height() - closeDrawValue ) ) {
00315
00316
00317 valX = xpos + nLineWidth;
00318 valY = static_cast<int>(zeroXAxisI)
00319 - highYPos
00320 + height/2
00321 - nLineWidth/2;
00322 } else
00323 ;
00324 }
00325 highText.draw( painter,
00326 valX, static_cast<int>( zeroXAxisI - valY ),
00327 ourClipRect,
00328 params()->hiLoChartHighValuesColor() );
00329 }
00330
00331
00332 if( params()->hiLoChartPrintOpenValues() &&
00333 params()->hiLoChartSubType() == KDChartParams::HiLoOpenClose ) {
00334
00335 QFont theFont( params()->hiLoChartOpenValuesFont() );
00336 if ( params()->hiLoChartOpenValuesUseFontRelSize() ) {
00337 int nTxtHeight =
00338 static_cast < int > ( params()->hiLoChartOpenValuesFontRelSize()
00339 * averageValueP1000 );
00340 theFont.setPointSizeFloat( nTxtHeight );
00341 }
00342 KDChartTextPiece openText( painter, QString::number( openValue ),
00343 theFont );
00344 int width = openText.width();
00345 int height = openText.height();
00346
00347
00348
00349 int valX = 0, valY = 0;
00350 valX = xpos - openCloseTickLength - width;
00351 valY = (int)openDrawValue + ( height / 2 );
00352 openText.draw( painter,
00353 valX, static_cast<int>( zeroXAxisI - valY ),
00354 ourClipRect,
00355 params()->hiLoChartOpenValuesColor() );
00356 }
00357
00358
00359 if( params()->hiLoChartPrintCloseValues() &&
00360 ( params()->hiLoChartSubType() == KDChartParams::HiLoOpenClose
00361 ||
00362 params()->hiLoChartSubType() == KDChartParams::HiLoClose ) ) {
00363
00364 QFont theFont( params()->hiLoChartCloseValuesFont() );
00365 if ( params()->hiLoChartCloseValuesUseFontRelSize() ) {
00366 int nTxtHeight =
00367 static_cast < int > ( params()->hiLoChartCloseValuesFontRelSize()
00368 * averageValueP1000 );
00369 theFont.setPointSizeFloat( nTxtHeight );
00370 }
00371 KDChartTextPiece closeText( painter, QString::number( closeValue ),
00372 theFont );
00373
00374 int height = closeText.height();
00375
00376
00377
00378 int valX = 0, valY = 0;
00379 valX = xpos + openCloseTickLength;
00380 valY = (int)closeDrawValue + ( height / 2 );
00381 closeText.draw( painter,
00382 valX, static_cast<int>( zeroXAxisI - valY ),
00383 ourClipRect,
00384 params()->hiLoChartCloseValuesColor() );
00385 }
00386
00387 } else
00388 continue;
00389 }
00390 }