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 "KDChartBarPainter.h"
00030 #include <KDChartParams.h>
00031
00032 #include <qpainter.h>
00033
00034 #include <stdlib.h>
00035
00047 KDChartBarPainter::KDChartBarPainter( KDChartParams* params ) :
00048 KDChartAxesPainter( params )
00049 {
00050
00051
00052 }
00053
00054
00058 KDChartBarPainter::~KDChartBarPainter()
00059 {
00060
00061 }
00062
00063 bool KDChartBarPainter::isNormalMode() const
00064 {
00065 return KDChartParams::BarNormal == params()->barChartSubType();
00066 }
00067
00068 int KDChartBarPainter::clipShiftUp( bool normalMode, double areaWidthP1000 ) const
00069 {
00070 const bool bThreeDBars = params()->threeDBars() || (KDChartParams::BarMultiRows == params()->barChartSubType());
00071 return ( normalMode && !bThreeDBars )
00072 ? static_cast < int > ( areaWidthP1000 * 16.0 )
00073 : 0;
00074 }
00075
00076
00077 void KDChartBarPainter::initMyPainter( QPainter* painter )
00078 {
00079 _myPainter = painter;
00080 _painterDX = 0.0;
00081 _painterDY = 0.0;
00082 }
00083
00084 void KDChartBarPainter::shiftMyPainter( double dx, double dy )
00085 {
00086 if( dx != 0.0 || dy != 0.0 ){
00087 _myPainter->translate(dx, dy);
00088 _painterDX += dx;
00089 _painterDY += dy;
00090 }
00091 }
00092
00093 void KDChartBarPainter::shiftMyPainterBack()
00094 {
00095 if( _painterDX != 0.0 || _painterDY != 0.0 ){
00096 _myPainter->translate(-_painterDX, -_painterDY);
00097 _painterDX = 0.0;
00098 _painterDY = 0.0;
00099 }
00100 }
00101
00102
00103 void KDChartBarPainter::calculateXFront1_2( bool bNormalMode, bool bIsVeryFirstBar, bool bIsFirstDataset, bool _bThreeDBars,
00104 double xpos, double valueBlockGap, double datasetGap, double frontBarWidth,
00105 int& frontX1, int& frontX2, int& prevFrontX2 ){
00106
00107
00108
00109
00110
00111 if( _bThreeDBars || bIsVeryFirstBar || !bNormalMode ){
00112 frontX1 = static_cast<int>( xpos );
00113 }else if( bIsFirstDataset ){
00114
00115 frontX1 = prevFrontX2 + static_cast < int > ( valueBlockGap ) + 1;
00116 }else{
00117 frontX1 = prevFrontX2 + static_cast < int > ( datasetGap ) + 1;
00118 }
00119
00120
00121
00122
00123
00124 frontX2 = static_cast < int > ( xpos + frontBarWidth );
00125
00126
00127
00128 prevFrontX2 = frontX2;
00129 }
00130
00131
00132 void KDChartBarPainter::specificPaintData( QPainter* painter,
00133 const QRect& ourClipRect,
00134 KDChartTableDataBase* data,
00135 KDChartDataRegionList* regions,
00136 const KDChartAxisParams* ordinatePara,
00137 bool bNormalMode,
00138 uint chart,
00139 double logWidth,
00140 double areaWidthP1000,
00141 double logHeight,
00142 double axisYOffset,
00143 double minColumnValue,
00144 double maxColumnValue,
00145 double columnValueDistance,
00146 uint chartDatasetStart,
00147 uint chartDatasetEnd,
00148 uint datasetStart,
00149 uint datasetEnd )
00150 {
00151
00152
00153
00154
00155
00156
00157 QRect frontRectPositive,frontRectNegative,
00158 rightRectPositive, rightRectNegative,
00159 excessRectPositive,excessRectNegative;
00160
00161
00162
00163 _areaP1000 = areaWidthP1000;
00164
00165 if( !data ) return;
00166
00167 const QPen defaultOutlinePen( params()->outlineDataColor(),
00168 params()->outlineDataLineWidth(),
00169 params()->outlineDataLineStyle() );
00170
00171 abscissaInfos ai;
00172 ai.bCenterThePoints = true;
00173 calculateAbscissaInfos( *params(), *data,
00174 datasetStart, datasetEnd,
00175 logWidth, _dataRect,
00176 ai );
00177
00178 const QRect devRect( painter->window() );
00179
00180 initMyPainter( painter );
00181
00182 const bool ordinateIsLogarithmic
00183 = KDChartAxisParams::AxisCalcLogarithmic == ordinatePara->axisCalcMode();
00184
00185 const bool bMultiRows = KDChartParams::BarMultiRows == params()->barChartSubType();
00186 _bThreeDBars = params()->threeDBars() || bMultiRows;
00187 int numChartDataEntryDatasets = 0;
00188 uint myLastDataEntryDataset = 0;
00189 for( uint iD = chartDatasetStart; iD <= chartDatasetEnd; ++iD ){
00190 if( params()->chartSourceMode( iD ) == KDChartParams::DataEntry ){
00191 ++numChartDataEntryDatasets;
00192 myLastDataEntryDataset = iD;
00193 }
00194 }
00195
00196 const bool bHadClipping = painter->hasClipping();
00197 if( bMultiRows )
00198 painter->setClipping( false );
00199
00200
00201
00202 int numValues = 0;
00203 if ( params()->numValues() != -1 )
00204 numValues = params()->numValues();
00205 else
00206 numValues = data->usedCols();
00207
00208 double datasetGap = bMultiRows
00209 ? 0.0
00210 : params()->datasetGap()
00211 * ( params()->datasetGapIsRelative()
00212 ? areaWidthP1000
00213 : 1.0 );
00214 double valueBlockGap = bMultiRows
00215 ? 0.0
00216 : params()->valueBlockGap()
00217 * ( params()->valueBlockGapIsRelative()
00218 ? areaWidthP1000
00219 : 1.0 );
00220
00221
00222 double spaceBetweenValueBlocks = bMultiRows
00223 ? 0.0
00224 : valueBlockGap * numValues;
00225
00226
00227 double totalNumberOfBars = 0.0;
00228 double spaceBetweenDatasets = 0.0;
00229 switch ( params()->barChartSubType() ) {
00230 case KDChartParams::BarNormal: {
00231 totalNumberOfBars = numChartDataEntryDatasets * numValues;
00232 spaceBetweenDatasets = datasetGap
00233 * ( totalNumberOfBars - numValues );
00234 break;
00235 }
00236 case KDChartParams::BarStacked:
00237 case KDChartParams::BarPercent:
00238 case KDChartParams::BarMultiRows:
00239 totalNumberOfBars = numValues;
00240 spaceBetweenDatasets = 0;
00241 break;
00242 default:
00243 qFatal( "Unsupported bar chart type" );
00244 };
00245
00246 double barWidth;
00247 if( params()->barWidth() == KDCHART_AUTO_SIZE )
00248 barWidth = ( ( logWidth
00249 - spaceBetweenValueBlocks
00250 - spaceBetweenDatasets )
00251 / totalNumberOfBars );
00252 else if( 0 > params()->barWidth() )
00253 barWidth = params()->barWidth() * -areaWidthP1000;
00254 else
00255 barWidth = params()->barWidth();
00256
00257 const double sideBarWidth = _bThreeDBars
00258 ? ( barWidth - barWidth / (1.0 + params()->cosThreeDBarAngle()) ) *
00259 params()->threeDBarDepth()
00260 : 0.0;
00261 const double frontBarWidth = _bThreeDBars && !bMultiRows
00262 ? barWidth - sideBarWidth
00263 : barWidth;
00264 const double sideBarHeight = sideBarWidth;
00265
00266 double pixelsPerUnit = 0.0;
00267 if ( params()->barChartSubType() != KDChartParams::BarPercent )
00268 pixelsPerUnit = logHeight / ( columnValueDistance ? columnValueDistance : 10 );
00269
00270
00271
00272
00273
00274
00275 double zeroXAxisI;
00276 if ( params()->barChartSubType() == KDChartParams::BarPercent ) {
00277 if ( minColumnValue == 0.0 )
00278 zeroXAxisI = 0.0;
00279 else if ( maxColumnValue == 0.0 )
00280 zeroXAxisI = logHeight - sideBarHeight;
00281 else
00282 zeroXAxisI = ( logHeight - sideBarHeight ) / 2.0;
00283 } else {
00284 zeroXAxisI = logHeight
00285 - ordinatePara->axisZeroLineStartY()
00286 + _dataRect.y();
00287 }
00288
00289 double shiftUpperBars = (params()->barChartSubType() != KDChartParams::BarPercent)
00290 && (ordinatePara->axisTrueLineWidth() % 2)
00291 ? 1.0
00292 : 0.0;
00293
00294
00295 double yposPositivesStart = logHeight;
00296 double yposNegativesStart = logHeight;
00297 if( params()->barChartSubType() == KDChartParams::BarPercent ){
00298 yposPositivesStart += axisYOffset;
00299 yposNegativesStart += axisYOffset;
00300 }
00301
00302 for ( int iPaintExtraLinesOrTheData = 0;
00303 iPaintExtraLinesOrTheData < 3;
00304 ++iPaintExtraLinesOrTheData )
00305 {
00306
00307 const bool bDrawExtraLines = (1 != iPaintExtraLinesOrTheData);
00308 const bool bDrawExtraLinesInFront = (2 == iPaintExtraLinesOrTheData);
00309
00310 double xpos = 0.0 + valueBlockGap / 2.0;
00311
00312 double yposPositives = yposPositivesStart;
00313 double yposNegatives = yposNegativesStart;
00314
00315
00316
00317
00318
00319
00320 double nShiftX = bMultiRows
00321 ? sideBarWidth
00322 : 0.0;
00323 double nShiftY = bMultiRows
00324 ? sideBarHeight
00325 : 0.0;
00326
00327 double valueTotal = 0.0;
00328
00329
00330 int prevFrontX2 = 0;
00331 bool bIsVeryFirstBar = true;
00332 for ( int value = 0; value < numValues; ++value ) {
00333
00334 bool bFirstValidValueUnknown = true;
00335 uint firstValidValue = 0;
00336 uint lastValidPositiveValue = 0;
00337 double maxValueInThisColumn = 0.0, minValueInThisColumn = 0.0;
00338 if ( params()->barChartSubType() == KDChartParams::BarStacked ||
00339 params()->barChartSubType() == KDChartParams::BarPercent ) {
00340 valueTotal = 0.0;
00341
00342 for ( uint dataset = datasetStart;
00343 dataset <= datasetEnd;
00344 ++dataset ) {
00345
00346 QVariant vVal;
00347 if( data->cellCoord( dataset, value, vVal, 1 )
00348 && params()->chartSourceMode( dataset ) == KDChartParams::DataEntry
00349 && QVariant::Double == vVal.type() ){
00350
00351 const double cellValue
00352 = ordinateIsLogarithmic
00353 ? log10( vVal.toDouble() )
00354 : vVal.toDouble();
00355
00356
00357 if( bFirstValidValueUnknown ){
00358 firstValidValue = dataset;
00359 bFirstValidValueUnknown = false;
00360 }
00361 if( 0.0 <= cellValue )
00362 lastValidPositiveValue = dataset;
00363
00364 maxValueInThisColumn = QMAX( maxValueInThisColumn, cellValue );
00365 minValueInThisColumn = QMIN( minValueInThisColumn, cellValue );
00366 if( params()->barChartSubType() == KDChartParams::BarPercent )
00367 valueTotal += cellValue;
00368
00369 }
00370 }
00371 }
00372
00373
00374 shiftMyPainter( (numChartDataEntryDatasets-1)*nShiftX, (numChartDataEntryDatasets-1)*-nShiftY );
00375
00376
00377
00378 bool bIsFirstDataset = true;
00379 for ( uint dataset = bMultiRows
00380 ? chartDatasetEnd
00381 : chartDatasetStart;
00382 dataset >= chartDatasetStart && dataset <= chartDatasetEnd;
00383 bMultiRows
00384 ? --dataset
00385 : ++dataset ) {
00386
00387
00388 const bool bDataEntrySourceMode
00389 = (params()->chartSourceMode( dataset ) == KDChartParams::DataEntry);
00390
00391
00392 QVariant coord1;
00393 QVariant coord2;
00394 int propID;
00395 if( data->cellContent( dataset, value, coord1, coord2, propID )
00396 && QVariant::Double == coord1.type() ){
00397
00398 const double cellValue
00399 = ordinateIsLogarithmic
00400 ? log10( coord1.toDouble() )
00401 : coord1.toDouble();
00402
00403
00404
00405 double barHeight;
00406 if ( params()->barChartSubType() == KDChartParams::BarPercent )
00407
00408 barHeight = ( cellValue / valueTotal )
00409 * fabs( zeroXAxisI - logHeight + sideBarHeight );
00410 else {
00411 barHeight = pixelsPerUnit * cellValue;
00412
00413 if( 0.0 <= barHeight )
00414
00415 barHeight = barHeight - sideBarHeight;
00416 else
00417 barHeight -= sideBarHeight;
00418 }
00419
00420
00421
00422
00423 if( 0 == barHeight || 0.0 == barHeight ) {
00424 barHeight = 1.0;
00425 }
00426
00427
00428
00429 if( dataset >= datasetStart && dataset <= datasetEnd ) {
00430
00431
00432
00433
00434 bool skipMe = false;
00435 if( ai.bCellsHaveSeveralCoordinates ){
00436 skipMe = !calculateAbscissaAxisValue( coord2,
00437 ai, 0, xpos );
00438
00439 if( ai.bAbscissaHasTrueAxisDtValues &&
00440 QVariant::DateTime == coord2.type() )
00441 xpos -= frontBarWidth / 2.0;
00442 }
00443
00444 if( !skipMe ){
00445
00446 QColor myBarColor( params()->dataColor( dataset ) );
00447 QColor myShadow1Color( params()->dataShadow1Color( dataset ) );
00448 QColor myShadow2Color( params()->dataShadow2Color( dataset ) );
00449
00450
00451 const KDChartParams::LineMarkerStyle
00452 defaultMarkerStyle = params()->lineMarkerStyle( dataset );
00453 const QPen defaultPen( params()->lineColor().isValid()
00454 ? params()->lineColor()
00455 : params()->dataColor( dataset ),
00456 params()->lineWidth(),
00457 params()->lineStyle( dataset ) );
00458
00459
00460
00461
00462
00463 KDChartPropertySet propSet;
00464 bool bCellPropertiesFound =
00465 params()->calculateProperties( propID,
00466 propSet );
00467 bool bShowThisBar = bDataEntrySourceMode;
00468 if( bCellPropertiesFound ){
00469 if( bShowThisBar && !bDrawExtraLines ){
00470 int iDummy;
00471 if( propSet.hasOwnShowBar( iDummy, bShowThisBar ) ){
00472
00473 }
00474 if( propSet.hasOwnBarColor( iDummy, myBarColor ) ){
00475
00476 params()->calculateShadowColors( myBarColor,
00477 myShadow1Color,
00478 myShadow2Color );
00479 }
00480 }
00481 }
00482
00483 if( !bDrawExtraLines || bCellPropertiesFound ){
00484
00485 QRegion* region = 0;
00486 if( bDataEntrySourceMode && !bDrawExtraLines ){
00487 painter->setPen( defaultOutlinePen );
00488 if ( myBarColor.isValid() )
00489 painter->setBrush( myBarColor );
00490 else
00491 painter->setBrush( NoBrush );
00492
00493
00494
00495 if ( regions )
00496 region = new QRegion();
00497 }
00498
00499
00500 int frontX1 = 0;
00501 int frontX2 = 0;
00502 bool tooLow = false;
00503 bool tooHigh = false;
00504
00505
00506 if ( cellValue <= 0 || cellValue < minColumnValue ) {
00507
00508
00509
00510 double maxValueYPos = maxColumnValue * pixelsPerUnit;
00511
00512
00513 double yZero = yposNegatives - zeroXAxisI - sideBarHeight;
00514
00515 tooLow = (barHeight - yZero + logHeight + axisYOffset) < 0;
00516
00517
00518
00519
00520
00521 if ( cellValue <= 0 && cellValue > maxColumnValue && minColumnValue < 0 && maxColumnValue < 0 )
00522 tooLow = true;
00523 if ( tooLow && bNormalMode) {
00524
00525
00526 double delta = 0.0125 * logHeight;
00527 double height = -1*(-1.0 * (yZero + sideBarHeight) - 2 * delta);
00528 double height1 = height - 3.0 * delta;
00529
00530 int yArrowGap = static_cast < int > ( 2.5 * delta );
00531 calculateXFront1_2( bNormalMode, bIsVeryFirstBar, bIsFirstDataset, _bThreeDBars,
00532 xpos, valueBlockGap, datasetGap, frontBarWidth,
00533 frontX1, frontX2, prevFrontX2 );
00534
00535 const int xm = static_cast < int > ( (frontX1 + frontX2) / 2.0 );
00536 QRect rect( ourClipRect );
00537
00538 rect.setHeight( static_cast<int>( rect.height() + 3.0 * delta ) );
00539 painter->setClipRect( rect );
00540
00541
00542
00543 int arrowXAxisGap;
00544 QPoint arrowTop( xm,static_cast<int>( yZero + height1 + 2 * yArrowGap) );
00545 if ( arrowTop.y()== yposNegatives )
00546 arrowXAxisGap = -2;
00547 else
00548 arrowXAxisGap = static_cast <int> (yposNegatives - arrowTop.y() - 2);
00549
00550 if( bDrawExtraLines ){
00551 drawExtraLinesAndMarkers(
00552 propSet,
00553 defaultPen,
00554 defaultMarkerStyle,
00555 xm, static_cast<int>( yZero + height1 ),
00556 painter,
00557 ai.abscissaPara,
00558 ordinatePara,
00559 areaWidthP1000,
00560 logHeight/1000.0,
00561 bDrawExtraLinesInFront );
00562 }else if( bShowThisBar ){
00563 if( params()->drawSolidExcessArrows() ) {
00564
00565
00566
00567
00568
00569
00570
00571
00572 QPointArray points( 5 );
00573
00574
00575 points.setPoint( 0, frontX1, cellValue < 0 ?
00576 static_cast<int>(yZero+height1 - 3.0*delta)+(2*yArrowGap)+ arrowXAxisGap:
00577 static_cast<int>( yZero + height1)+(2*yArrowGap)+ arrowXAxisGap);
00578 points.setPoint( 1, frontX2,cellValue < 0 ?
00579 static_cast<int>(yZero+height1 - 3.0*delta)+(2*yArrowGap)+ arrowXAxisGap:
00580 static_cast<int>( yZero + height1)+(2*yArrowGap)+ arrowXAxisGap );
00581 points.setPoint( 2, frontX2, cellValue < 0 ?
00582 static_cast<int>(yZero+height1 - 3.0*delta)+(2*yArrowGap)+ arrowXAxisGap:
00583 static_cast<int>( yZero + height1)+(2*yArrowGap)+ arrowXAxisGap);
00584 points.setPoint( 3, xm, cellValue < 0 ?
00585 static_cast<int>( yZero + height1)+(2*yArrowGap)+ arrowXAxisGap:
00586 static_cast<int>(yZero+height1 - 3.0*delta)+(2*yArrowGap)+ arrowXAxisGap);
00587 points.setPoint( 4, frontX1, cellValue < 0 ?
00588 static_cast<int>(yZero+height1 - 3.0*delta)+(2*yArrowGap)+ arrowXAxisGap:
00589 static_cast<int>( yZero + height1)+(2*yArrowGap)+ arrowXAxisGap);
00590
00591
00592 if ( minColumnValue < 0 && maxColumnValue > 0 ) {
00593 points.setPoint(0, points.point(0).x(), static_cast <int> (yposNegatives - zeroXAxisI) );
00594 points.setPoint(1, points.point(1).x(), static_cast <int> (yposNegatives - zeroXAxisI) );
00595 }
00596
00597
00598 if ( minColumnValue < 0 && maxColumnValue < 0 ) {
00599
00600 if ( cellValue > maxColumnValue ) {
00601
00602
00603
00604
00605 int diffArrowBase = points.point(2).y() - points.point(3).y();
00606 double maxValueYPos = maxColumnValue * pixelsPerUnit;
00607 double minValueYPos = minColumnValue * pixelsPerUnit;
00608 double adjustedArrow = (cellValue == 0 ? minValueYPos - maxValueYPos + diffArrowBase + 2:
00609 minValueYPos - maxValueYPos - diffArrowBase + 1);
00610 points.setPoint( 0, frontX1, points.point(0).y() + static_cast <int> (adjustedArrow));
00611 points.setPoint( 1, frontX2, points.point(1).y() + static_cast <int> (adjustedArrow ));
00612 points.setPoint( 2, frontX2, points.point(2).y() + static_cast <int> (adjustedArrow));
00613 points.setPoint( 3, xm, points.point(3).y() + static_cast <int> (adjustedArrow));
00614 points.setPoint( 4, frontX1, points.point(4).y() + static_cast <int> (adjustedArrow));
00615 }
00616
00617 if ( cellValue < minColumnValue ) {
00618 points.setPoint( 0, frontX1, static_cast <int> (maxValueYPos));
00619 points.setPoint( 1, frontX2, static_cast <int> (maxValueYPos));
00620 }
00621 }
00622
00623
00624
00625
00626
00627 if ( params()->userWidth() != 0 ) {
00628 int userwidth = 0;
00629 if ( params()->userWidth() < 0 )
00630 userwidth = static_cast <int> (params()->userWidth() * -areaWidthP1000);
00631 else
00632 userwidth = static_cast <int> (params()->userWidth() * areaWidthP1000);
00633
00634 QRect tmpRect ( points.point(0), points.point(2));
00635 points.setPoint(0, static_cast <int>(tmpRect.center().x() - userwidth/2),
00636 points.point(0).y());
00637 points.setPoint(1, static_cast <int>(tmpRect.center().x() + userwidth/2),
00638 points.point(1).y());
00639 points.setPoint(2, static_cast <int>(tmpRect.center().x() + userwidth/2),
00640 points.point(2).y());
00641 points.setPoint(4, static_cast <int>(tmpRect.center().x() - userwidth/2),
00642 points.point(4).y());
00643
00644 }
00645
00646 painter->drawPolygon( points );
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659 QPoint tpLeft (points.point(4).x(), points.point(4).y());
00660 QPoint tpRight(points.point(2).x(), points.point(2).y());
00661
00662
00663 excessRectNegative.setTopLeft(tpLeft);
00664 excessRectNegative.setTopRight(tpRight);
00665 excessRectNegative.setBottomRight(points.point(1));
00666 excessRectNegative.setBottomLeft(points.point(0));
00667
00668
00669 if( region ) {
00670 points.translate( _dataRect.x(), _dataRect.y() );
00671 *region += QRegion( points );
00672 }
00673 } else {
00674
00675
00676
00677
00678
00679
00680
00681 QPointArray points( 5 );
00682
00683 points.setPoint( 0, frontX1, cellValue < 0 ?
00684 static_cast<int>(yZero+height1 - 3.0*delta) + arrowXAxisGap:
00685 static_cast<int>( yZero + height1)+(2 * yArrowGap)+ arrowXAxisGap);
00686 points.setPoint( 1, frontX2,cellValue < 0 ?
00687 static_cast<int>(yZero+height1 - 3.0*delta) + arrowXAxisGap:
00688 static_cast<int>( yZero + height1)+(2 * yArrowGap)+ arrowXAxisGap);
00689 points.setPoint( 2, frontX2, cellValue < 0 ?
00690 static_cast<int>(yZero+height1 - 3.0*delta) + arrowXAxisGap:
00691 static_cast<int>( yZero + height1)+(2 * yArrowGap)+ arrowXAxisGap);
00692 points.setPoint( 3, xm, cellValue < 0 ?
00693 static_cast<int>( yZero + height1) + arrowXAxisGap:
00694 static_cast<int>(yZero+height1 - 3.0*delta)+(2 * yArrowGap)+ arrowXAxisGap);
00695 points.setPoint( 4, frontX1, cellValue < 0 ?
00696 static_cast<int>(yZero+height1 - 3.0*delta) + arrowXAxisGap:
00697 static_cast<int>( yZero + height1)+(2 * yArrowGap)+ arrowXAxisGap);
00698
00699
00700 if ( minColumnValue < 0 && maxColumnValue > 0 ) {
00701 points.setPoint(0, points.point(0).x(), static_cast <int> (yposNegatives - zeroXAxisI) );
00702 points.setPoint(1, points.point(1).x(), static_cast <int> (yposNegatives - zeroXAxisI) );
00703 }
00704
00705
00706 if ( minColumnValue < 0 && maxColumnValue < 0 ) {
00707
00708 if ( cellValue > maxColumnValue ) {
00709
00710
00711
00712
00713 int diffArrowBase = points.point(2).y() - points.point(3).y();
00714 double maxValueYPos = maxColumnValue * pixelsPerUnit;
00715 double minValueYPos = minColumnValue * pixelsPerUnit;
00716 double adjustedArrow = (cellValue == 0 ?
00717 minValueYPos - maxValueYPos + diffArrowBase + 2:
00718 minValueYPos - maxValueYPos - diffArrowBase + 1);
00719 points.setPoint( 0, frontX1, points.point(0).y() + static_cast <int> (adjustedArrow)
00720 +(2*yArrowGap));
00721 points.setPoint( 1, frontX2, points.point(1).y() + static_cast <int> (adjustedArrow )
00722 + (2*yArrowGap));
00723 points.setPoint( 2, frontX2, points.point(2).y() + static_cast <int> (adjustedArrow)
00724 + (2*yArrowGap));
00725 points.setPoint( 3, xm, points.point(3).y() + static_cast <int> (adjustedArrow)
00726 + (2*yArrowGap));
00727 points.setPoint( 4, frontX1, points.point(4).y() + static_cast <int> (adjustedArrow)
00728 + (2*yArrowGap));
00729 }
00730
00731 if ( cellValue < minColumnValue ) {
00732 points.setPoint( 0, frontX1, static_cast <int> (maxValueYPos));
00733 points.setPoint( 1, frontX2, static_cast <int> (maxValueYPos));
00734 }
00735 }
00736
00737
00738
00739
00740 if ( params()->userWidth() != 0 ) {
00741 int userwidth = 0;
00742 if ( params()->userWidth() < 0 )
00743 userwidth = static_cast <int> (params()->userWidth() * -areaWidthP1000);
00744 else
00745 userwidth = static_cast <int> (params()->userWidth() * areaWidthP1000);
00746
00747 QRect tmpRect ( points.point(0), points.point(2));
00748 points.setPoint(0, static_cast <int>(tmpRect.center().x() - userwidth/2),
00749 points.point(0).y());
00750 points.setPoint(1, static_cast <int>(tmpRect.center().x() + userwidth/2),
00751 points.point(1).y());
00752 points.setPoint(2, static_cast <int>(tmpRect.center().x() + userwidth/2),
00753 points.point(2).y());
00754 points.setPoint(4, static_cast <int>(tmpRect.center().x() - userwidth/2),
00755 points.point(4).y());
00756
00757 }
00758
00759 painter->drawPolygon( points );
00760
00761
00762 excessRectNegative.setTopLeft(points.point(4));
00763 excessRectNegative.setTopRight(points.point(2));
00764 excessRectNegative.setBottomRight(points.point(1));
00765 excessRectNegative.setBottomLeft(points.point(0));
00766
00767
00768
00769 if ( region ) {
00770 points.translate( _dataRect.x(), _dataRect.y() );
00771 *region += QRegion( points );
00772 }
00773
00774 QPointArray points2( 6 );
00775 points2.setPoint( 0, frontX1, cellValue < 0 ?
00776 static_cast<int>( yZero + height1 - 3.0 * delta ) + arrowXAxisGap:
00777 static_cast<int>(yZero + height1) + arrowXAxisGap);
00778 points2.setPoint( 1, xm, cellValue < 0 ?
00779 static_cast<int>(yZero + height1) + arrowXAxisGap:
00780 static_cast<int>( yZero + height1 - 3.0 * delta ) + arrowXAxisGap);
00781 points2.setPoint( 2, frontX2, cellValue < 0 ?
00782 static_cast<int>(yZero + height1 - 3.0 * delta) + arrowXAxisGap:
00783 static_cast<int>(yZero + height1) + arrowXAxisGap);
00784 points2.setPoint( 3, frontX2, cellValue < 0 ?
00785 static_cast<int>(yZero + height1 - 3.75 * delta) + arrowXAxisGap :
00786 static_cast<int>(yZero + height1 - 0.75 * delta) + arrowXAxisGap);
00787 points2.setPoint( 4, xm, cellValue < 0 ?
00788 static_cast<int>(yZero + height1 - 0.75 * delta) + arrowXAxisGap:
00789 static_cast<int>(yZero + height1 - 3.75 * delta) + arrowXAxisGap);
00790 points2.setPoint( 5, frontX1, cellValue < 0 ?
00791 static_cast<int>(yZero + height1 - 3.75 * delta) + arrowXAxisGap:
00792 static_cast<int>(yZero + height1 - 0.75 * delta) + arrowXAxisGap);
00793 points2.translate( 0, yArrowGap );
00794
00795 if ( minColumnValue < 0 && maxColumnValue < 0 && cellValue > maxColumnValue ) {
00796
00797
00798
00799
00800 int diffArrowBase = points.point(2).y() - points.point(3).y();
00801 double maxValueYPos = maxColumnValue * pixelsPerUnit;
00802 double minValueYPos = minColumnValue * pixelsPerUnit;
00803 double adjustedArrow = (cellValue == 0 ? minValueYPos - maxValueYPos + diffArrowBase + 2:
00804 minValueYPos - maxValueYPos - diffArrowBase + 1);
00805 points2.translate( 0, 2*yArrowGap );
00806 points2.setPoint( 0, frontX1, points2.point(0).y() + static_cast <int> (adjustedArrow) );
00807 points2.setPoint( 1, xm, points2.point(1).y() + static_cast <int> (adjustedArrow));
00808 points2.setPoint( 2, frontX2, points2.point(2).y() + static_cast <int> (adjustedArrow));
00809 points2.setPoint( 3, frontX2, points2.point(3).y() + static_cast <int> (adjustedArrow));
00810 points2.setPoint( 4, xm, points2.point(4).y() + static_cast <int> (adjustedArrow));
00811 points2.setPoint( 5, frontX1, points2.point(5).y() + static_cast <int> (adjustedArrow));
00812 }
00813
00814
00815
00816 if ( params()->userWidth() != 0 ) {
00817 int userwidth = 0;
00818 if ( params()->userWidth() < 0 )
00819 userwidth = static_cast <int> (params()->userWidth() * -areaWidthP1000);
00820 else
00821 userwidth = static_cast <int> (params()->userWidth() * areaWidthP1000);
00822
00823
00824 points2.setPoint(0, excessRectNegative.topLeft().x(),points2.point(0).y());
00825 points2.setPoint(2, excessRectNegative.topRight().x(),points2.point(2).y());
00826 points2.setPoint(3, excessRectNegative.topRight().x(),points2.point(3).y());
00827 points2.setPoint(5, excessRectNegative.topLeft().x(),points2.point(5).y());
00828
00829 }
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839 painter->drawPolygon( points2 );
00840
00841 if ( region ) {
00842 QPointArray points2cpy( points2 );
00843 points2cpy.detach();
00844 points2cpy.translate( _dataRect.x(),
00845 _dataRect.y() );
00846 *region += QRegion( points2cpy );
00847 }
00848 if ( cellValue < 0 )
00849 points2.translate( 0, yArrowGap );
00850 else
00851 points2.translate( 0, -yArrowGap );
00852
00853 painter->drawPolygon( points2 );
00854
00855 if ( region ) {
00856 points2.translate( _dataRect.x(), _dataRect.y() );
00857 *region += QRegion( points2 );
00858 }
00859 }
00860 }
00861 painter->setClipRect( ourClipRect );
00862 }
00863 else {
00864
00865
00866
00867
00868
00869
00870
00871 int pt1Y = static_cast < int > ( yZero - barHeight );
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883 calculateXFront1_2( bNormalMode, bIsVeryFirstBar, bIsFirstDataset, _bThreeDBars,
00884 xpos, valueBlockGap, datasetGap, frontBarWidth,
00885 frontX1, frontX2, prevFrontX2 );
00886
00887 QPoint pt1( frontX1, pt1Y );
00888 QPoint pt2( frontX2,
00889 static_cast < int > ( yZero + sideBarHeight) );
00890
00891
00892 if( 0.0 > maxColumnValue ){
00893 pt2.setY(pt2.y() - static_cast < int > (pixelsPerUnit * maxColumnValue));
00894 }
00895 if( pt2.y() < pt1Y ) {
00896 pt1.setY( pt2.y() );
00897 pt2.setY( pt1Y );
00898 }
00899 if( pt2.x() < frontX1 ) {
00900 pt1.setX( frontX2 );
00901 pt2.setX( frontX1 );
00902 }
00903 if( bDrawExtraLines ){
00904 int y = pt2.y();
00905 if( _bThreeDBars )
00906 y -= static_cast < int > ( sideBarHeight );
00907 drawExtraLinesAndMarkers(
00908 propSet,
00909 defaultPen,
00910 defaultMarkerStyle,
00911 (frontX1+frontX2)/2, y,
00912 painter,
00913 ai.abscissaPara,
00914 ordinatePara,
00915 areaWidthP1000,
00916 logHeight/1000.0,
00917 bDrawExtraLinesInFront );
00918 }else if( bShowThisBar ){
00919
00920 QSize siz( pt2.x() - pt1.x(),
00921 pt2.y() - pt1.y() );
00922 QRect rect( pt1, siz );
00923
00924 if( 1.5 > frontBarWidth ){
00925 QPen oldPen( painter->pen() );
00926 painter->setPen( QPen(painter->brush().color(), 0) );
00927 painter->drawLine(pt1, QPoint(pt1.x(),pt2.y()));
00928 painter->setPen( oldPen );
00929 }else{
00930
00931 if ( tooLow || cellValue < minColumnValue) {
00932
00933 frontRectNegative.setTopLeft(excessRectNegative.bottomLeft());
00934 frontRectNegative.setTopRight(excessRectNegative.bottomRight());
00935 frontRectNegative.setBottomRight(excessRectNegative.topRight());
00936 frontRectNegative.setBottomLeft(excessRectNegative.topLeft());
00937
00938 } else {
00939 frontRectNegative.setTopLeft(rect.topLeft());
00940 frontRectNegative.setTopRight(rect.topRight());
00941 frontRectNegative.setBottomRight(rect.bottomRight());
00942 frontRectNegative.setBottomLeft(rect.bottomLeft());
00943 }
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959 if ( params()->userWidth() != 0 ) {
00960 int userwidth = 0;
00961 if ( params()->userWidth() < 0 )
00962 userwidth = static_cast <int> (params()->userWidth() * -areaWidthP1000);
00963 else
00964 userwidth = static_cast <int> (params()->userWidth() * areaWidthP1000);
00965
00966 rect.setLeft( static_cast <int> (rect.center().x() - (userwidth/2)));
00967 rect.setRight( static_cast <int> (rect.center().x() + (userwidth/2)));
00968 rect.setWidth( static_cast <int> (userwidth) );
00969 frontRectNegative.setLeft( tooLow || cellValue < minColumnValue ? static_cast <int> (excessRectNegative.center().x() - (userwidth/2)):rect.left());
00970 frontRectNegative.setRight( tooHigh ? static_cast <int> (excessRectNegative.center().x() + (userwidth/2)):rect.right());
00971
00972 }
00973
00974
00975 painter->drawRect( rect );
00976 }
00977
00978 if ( region ) {
00979 rect.moveBy( _dataRect.x(), _dataRect.y() );
00980 *region += QRegion( rect );
00981 }
00982 }
00983 }
00984 } else {
00985
00986
00987
00988
00989
00990 double maxValueYPos = maxColumnValue * pixelsPerUnit;
00991 double minValueYPos = minColumnValue * pixelsPerUnit;
00992 double minDataValueYPos = maxValueYPos - minValueYPos;
00993 double yZero = yposPositives - zeroXAxisI;
00994
00995
00996
00997
00998
00999
01000
01001
01002 if(!_bThreeDBars) {
01003 tooHigh = (barHeight - yZero) > 0;
01004 } else {
01005
01006
01007 int dataValueYPos = static_cast <int>( (cellValue * pixelsPerUnit) + sideBarHeight );
01008 tooHigh = dataValueYPos - (maxColumnValue * pixelsPerUnit) > 0;
01009 }
01010
01011 if ( tooHigh && bNormalMode ) {
01012 double delta = -0.0125 * logHeight;
01013 double height = -1.0 * yZero
01014 - 2.0 * delta;
01015 double height1 = height + -3.0 * delta;
01016
01017 int yArrowGap = static_cast < int > ( 2.5 * delta );
01018 calculateXFront1_2( bNormalMode, bIsVeryFirstBar, bIsFirstDataset, _bThreeDBars,
01019 xpos, valueBlockGap, datasetGap, frontBarWidth,
01020 frontX1, frontX2, prevFrontX2 );
01021
01022 const int xm = static_cast < int > ( (frontX1 + frontX2) / 2.0 );
01023 QRect rect( ourClipRect );
01024
01025 rect.setTop( static_cast<int>( rect.top() + 3 * delta ) );
01026 rect.setHeight( static_cast<int>( rect.height() - 3 * delta ) );
01027 painter->setClipRect( rect );
01028
01029 if( bDrawExtraLines ){
01030 drawExtraLinesAndMarkers(
01031 propSet,
01032 defaultPen,
01033 defaultMarkerStyle,
01034 xm, static_cast<int>( yZero + height1 ),
01035 painter,
01036 ai.abscissaPara,
01037 ordinatePara,
01038 areaWidthP1000,
01039 logHeight/1000.0,
01040 bDrawExtraLinesInFront );
01041 }else if( bShowThisBar ){
01042 if( params()->drawSolidExcessArrows() ) {
01043
01044
01045 QPointArray points( 5 );
01046
01047 points.setPoint( 0, frontX1,
01048 (minDataValueYPos < static_cast <int> (yZero))?
01049 static_cast <int> (minDataValueYPos-1):static_cast <int>(yZero));
01050 points.setPoint( 1, frontX2,
01051 (minDataValueYPos < static_cast <int> (yZero))?
01052 static_cast <int> (minDataValueYPos-1):static_cast <int>(yZero));
01053 points.setPoint( 2, frontX2, static_cast<int>( yZero + height1 - 3.0 * delta )
01054 + 2 * yArrowGap );
01055 points.setPoint( 3, xm, static_cast<int>( yZero + height1 )
01056 + 2 * yArrowGap );
01057 points.setPoint( 4, frontX1, static_cast<int>( yZero + height1 - 3.0 * delta )
01058 + 2 * yArrowGap );
01059
01060
01061 if ( cellValue > maxColumnValue && 0 > maxColumnValue ) {
01062
01063 points.setPoint( 0, frontX1,static_cast<int>( yZero + height1 - 3.0 * delta ) + 2 * yArrowGap);
01064 points.setPoint( 1, frontX2,static_cast<int>( yZero + height1 - 3.0 * delta ) + 2 * yArrowGap);
01065 }
01066
01067
01068
01069
01070 if ( params()->userWidth() != 0 ) {
01071 int userwidth = 0;
01072 if ( params()->userWidth() < 0 )
01073 userwidth = static_cast <int> (params()->userWidth() * -areaWidthP1000);
01074 else
01075 userwidth = static_cast <int> (params()->userWidth() * areaWidthP1000);
01076
01077 QRect tmpRect ( points.point(0), points.point(2));
01078 points.setPoint(0, static_cast <int>(tmpRect.center().x() - userwidth/2),
01079 points.point(0).y());
01080 points.setPoint(1, static_cast <int>(tmpRect.center().x() + userwidth/2),
01081 points.point(1).y());
01082 points.setPoint(2, static_cast <int>(tmpRect.center().x() + userwidth/2),
01083 points.point(2).y());
01084 points.setPoint(4, static_cast <int>(tmpRect.center().x() - userwidth/2),
01085 points.point(4).y());
01086
01087 }
01088
01089
01090 painter->drawPolygon( points );
01091
01092
01093 QPoint tpLeft (points.point(4).x(), points.point(4).y() - 2 * yArrowGap);
01094 QPoint tpRight(points.point(2).x(), points.point(2).y() - 2 * yArrowGap);
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106 excessRectPositive.setTopLeft(tpLeft);
01107 excessRectPositive.setTopRight(tpRight);
01108 excessRectPositive.setBottomRight(points.point(1));
01109 excessRectPositive.setBottomLeft(points.point(0));
01110
01111
01112 if( region ) {
01113 points.translate( _dataRect.x(), _dataRect.y() );
01114 *region += QRegion( points );
01115 }
01116 } else {
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126 QPointArray points( 5 );
01127
01128 points.setPoint( 0, frontX1,
01129 (minDataValueYPos < static_cast <int> (yZero))? static_cast <int> (minDataValueYPos - 1) : static_cast <int>(yZero));
01130 points.setPoint( 1, frontX2,
01131 (minDataValueYPos < static_cast <int> (yZero))? static_cast<int> ( minDataValueYPos - 1) : static_cast <int>(yZero));
01132 points.setPoint( 2, frontX2, static_cast<int>( yZero + height1 - 3.0 * delta ) );
01133 points.setPoint( 3, xm, static_cast<int>( yZero + height1 ) );
01134 points.setPoint( 4, frontX1, static_cast<int>( yZero + height1 - 3.0 * delta ) );
01135
01136
01137 if ( cellValue > maxColumnValue && 0 > maxColumnValue ) {
01138 points.setPoint( 0, frontX1, static_cast<int>( yZero + height1 - 3.0 * delta ));
01139 points.setPoint( 1, frontX2, static_cast<int>( yZero + height1 - 3.0 * delta ));
01140 }
01141
01142
01143
01144
01145 if ( params()->userWidth() != 0 ) {
01146 int userwidth = 0;
01147 if ( params()->userWidth() < 0 )
01148 userwidth = static_cast <int> (params()->userWidth() * -areaWidthP1000);
01149 else
01150 userwidth = static_cast <int> (params()->userWidth() * areaWidthP1000);
01151
01152 QRect tmpRect ( points.point(0), points.point(2));
01153 points.setPoint(0, static_cast <int>(tmpRect.center().x() - userwidth/2),
01154 points.point(0).y());
01155 points.setPoint(1, static_cast <int>(tmpRect.center().x() + userwidth/2),
01156 points.point(1).y());
01157 points.setPoint(2, static_cast <int>(tmpRect.center().x() + userwidth/2),
01158 points.point(2).y());
01159 points.setPoint(4, static_cast <int>(tmpRect.center().x() - userwidth/2),
01160 points.point(4).y());
01161
01162 }
01163
01164
01165
01166 painter->drawPolygon( points );
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177 excessRectPositive.setTopLeft(points.point(4));
01178 excessRectPositive.setTopRight(points.point(2));
01179 excessRectPositive.setBottomRight(points.point(1));
01180 excessRectPositive.setBottomLeft(points.point(0));
01181
01182
01183 if ( region ) {
01184 points.translate( _dataRect.x(), _dataRect.y() );
01185 *region += QRegion( points );
01186 }
01187
01188 QPointArray points2( 6 );
01189 points2.setPoint( 0, frontX1, static_cast<int>( yZero + height1 - 3.0 * delta ) );
01190 points2.setPoint( 1, xm, static_cast<int>( yZero + height1 ) );
01191 points2.setPoint( 2, frontX2, static_cast<int>( yZero + height1 - 3.0 * delta ) );
01192 points2.setPoint( 3, frontX2, static_cast<int>( yZero + height1 - 3.75 * delta ) );
01193 points2.setPoint( 4, xm, static_cast<int>( yZero + height1 - 0.75 * delta ) );
01194 points2.setPoint( 5, frontX1, static_cast<int>( yZero + height1 - 3.75 * delta ) );
01195 points2.translate( 0, yArrowGap );
01196
01197
01198
01199
01200 if ( params()->userWidth() != 0 ) {
01201 int userwidth = 0;
01202 if ( params()->userWidth() < 0 )
01203 userwidth = static_cast <int> (params()->userWidth() * -areaWidthP1000);
01204 else
01205 userwidth = static_cast <int> (params()->userWidth() * areaWidthP1000);
01206
01207 points2.setPoint(0, excessRectPositive.topLeft().x(),points2.point(0).y());
01208 points2.setPoint(2, excessRectPositive.topRight().x(),points2.point(2).y());
01209 points2.setPoint(3, excessRectPositive.topRight().x(),points2.point(3).y());
01210 points2.setPoint(5, excessRectPositive.topLeft().x(),points2.point(5).y());
01211
01212 }
01213
01214
01215 painter->drawPolygon( points2 );
01216
01217
01218
01219
01220
01221
01222
01223
01224 if ( region ) {
01225 QPointArray points2cpy( points2 );
01226 points2cpy.detach();
01227 points2cpy.translate( _dataRect.x(),
01228 _dataRect.y() );
01229 *region += QRegion( points2cpy );
01230 }
01231 points2.translate( 0, yArrowGap );
01232 painter->drawPolygon( points2 );
01233
01234
01235 if ( region ) {
01236 points2.translate( _dataRect.x(), _dataRect.y() );
01237 *region += QRegion( points2 );
01238 }
01239 }
01240 }
01241
01242 painter->setClipRect( ourClipRect );
01243 }
01244 else {
01245
01246 double y0 = yposPositives - zeroXAxisI;
01247
01248 int pt1Y = static_cast < int > ( y0 - barHeight - sideBarHeight);
01249
01250 calculateXFront1_2( bNormalMode, bIsVeryFirstBar, bIsFirstDataset, _bThreeDBars,
01251 xpos, valueBlockGap, datasetGap, frontBarWidth,
01252 frontX1, frontX2, prevFrontX2 );
01253
01254 QPoint pt1( frontX1, pt1Y );
01255 QPoint pt2( frontX2,
01256 static_cast < int > ( y0 + shiftUpperBars ) );
01257
01258 if( 0.0 < minColumnValue )
01259 pt2.setY(pt2.y() - static_cast < int > ( pixelsPerUnit * minColumnValue ));
01260
01261 if( pt2.y() < pt1Y ) {
01262 pt1.setY( pt2.y() );
01263 pt2.setY( pt1Y );
01264 }
01265 if( pt2.x() < frontX1 ) {
01266 pt1.setX( frontX2 );
01267 pt2.setX( frontX1 );
01268 }
01269 if( bDrawExtraLines ){
01270 int y = pt1.y();
01271 if( _bThreeDBars )
01272 y -= static_cast < int > ( sideBarHeight );
01273
01274 drawExtraLinesAndMarkers(
01275 propSet,
01276 defaultPen,
01277 defaultMarkerStyle,
01278 (frontX1+frontX2)/2, y,
01279 painter,
01280 ai.abscissaPara,
01281 ordinatePara,
01282 areaWidthP1000,
01283 logHeight/1000.0,
01284 bDrawExtraLinesInFront );
01285 }else if( bShowThisBar ){
01286
01287
01288 QSize siz( pt2.x() - pt1.x(),
01289 pt2.y() - pt1.y());
01290
01291 QRect rect( pt1, siz );
01292
01293 rect.setBottom(static_cast <int> (yZero));
01294
01295
01296 if( tooHigh ) {
01297 frontRectPositive.setTopLeft(excessRectPositive.topLeft());
01298 frontRectPositive.setTopRight(excessRectPositive.topRight());
01299 frontRectPositive.setBottomRight(excessRectPositive.bottomRight());
01300 frontRectPositive.setBottomLeft(excessRectPositive.bottomLeft());
01301 } else {
01302 frontRectPositive.setTopLeft(rect.topLeft());
01303 frontRectPositive.setTopRight(rect.topRight());
01304 frontRectPositive.setBottomRight(rect.bottomRight());
01305 frontRectPositive.setBottomLeft(rect.bottomLeft());
01306 }
01307
01308 if( 1.5 > frontBarWidth ){
01309
01310 QPen oldPen( painter->pen() );
01311 painter->setPen( QPen(painter->brush().color(), 0) );
01312 painter->drawLine(pt1, QPoint(pt1.x(),pt2.y()));
01313 painter->setPen( oldPen );
01314 }else{
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331 if ( params()->userWidth() != 0 ) {
01332 int userwidth = 0;
01333 if ( params()->userWidth() < 0 )
01334 userwidth = static_cast <int> (params()->userWidth() * -areaWidthP1000);
01335 else
01336 userwidth = static_cast <int> (params()->userWidth() * areaWidthP1000);
01337
01338 rect.setLeft( static_cast <int> (rect.center().x() - (userwidth/2)));
01339 rect.setRight( static_cast <int> (rect.center().x() + (userwidth/2)));
01340 rect.setWidth( static_cast <int> (userwidth) );
01341
01342 frontRectPositive.setLeft( tooHigh ? static_cast <int> (excessRectPositive.center().x() - (userwidth/2)):rect.left());
01343 frontRectPositive.setRight( tooHigh ? static_cast <int> (excessRectPositive.center().x() + (userwidth/2)):rect.right());
01344
01345 }
01346
01347
01348
01349 if (!tooHigh && !tooLow || params()->barChartSubType() == KDChartParams::BarPercent
01350 || params()->barChartSubType() == KDChartParams::BarStacked)
01351 painter->drawRect( rect );
01352
01353
01354
01355
01356 if ( region ) {
01357 rect.moveBy( _dataRect.x(), _dataRect.y() );
01358 *region += QRegion( rect );
01359 }
01360
01361 }
01362 }
01363 }
01364 }
01365 if ( bShowThisBar && _bThreeDBars && !bDrawExtraLines ) {
01366
01367
01368 QPointArray points( 4 );
01369
01370 if (cellValue <= 0 || cellValue < minColumnValue) {
01371 if ( tooLow || cellValue < minColumnValue ) {
01372 points.setPoint(0, excessRectNegative.topRight());
01373 points.setPoint(1, excessRectNegative.topRight().x() + static_cast<int>(sideBarHeight),
01374 excessRectNegative.top() - static_cast<int>(sideBarHeight));
01375 points.setPoint(2, excessRectNegative.bottomRight().x() + static_cast<int>(sideBarHeight),
01376 excessRectNegative.bottom() - static_cast<int>(sideBarHeight));
01377 points.setPoint(3, excessRectNegative.bottomRight());
01378 } else {
01379 points.setPoint( 0, frontRectNegative.bottomRight());
01380 points.setPoint( 1, frontRectNegative.bottomRight().x() + static_cast<int>(sideBarHeight),
01381 frontRectNegative.bottom() - static_cast<int>(sideBarHeight) );
01382 points.setPoint(2, frontRectNegative.bottomRight().x() + static_cast<int>(sideBarHeight),
01383 frontRectNegative.top() - static_cast<int>(sideBarHeight));
01384 points.setPoint(3, frontRectNegative.topRight() );
01385 }
01386
01387
01388 rightRectNegative.setTopLeft( points.point(0));
01389 rightRectNegative.setTopRight( points.point(2));
01390 rightRectNegative.setBottomRight(points.point(1));
01391 rightRectNegative.setBottomLeft(points.point(3));
01392
01393 } else {
01394
01395
01396
01397
01398 if ( tooHigh ) {
01399 points.setPoint(0, excessRectPositive.topRight());
01400 points.setPoint(1, excessRectPositive.topRight().x() + static_cast <int> (sideBarHeight),
01401 excessRectPositive.top() - static_cast <int> (sideBarHeight) );
01402 points.setPoint(2, excessRectPositive.bottomRight().x() + static_cast <int> (sideBarHeight),
01403 excessRectPositive.bottom() - static_cast <int> (sideBarHeight));
01404 points.setPoint(3, excessRectPositive.bottomRight());
01405
01406 } else {
01407 points.setPoint(0, frontRectPositive.topRight());
01408 points.setPoint(1, frontRectPositive.topRight().x() + static_cast <int> (sideBarHeight),
01409 frontRectPositive.top() - static_cast<int>(sideBarHeight));
01410 points.setPoint(2, frontRectPositive.bottomRight().x() + static_cast <int> (sideBarHeight),
01411 frontRectPositive.bottom() - static_cast<int>(sideBarHeight));
01412 points.setPoint(3, frontRectPositive.bottomRight());
01413 }
01414
01415
01416 rightRectPositive.setTopLeft( points.point(0));
01417 rightRectPositive.setTopRight( points.point(1));
01418 rightRectPositive.setBottomLeft( points.point(3));
01419 rightRectPositive.setBottomRight(points.point(2));
01420 }
01421
01422 if ( myShadow2Color.isValid() )
01423 painter->setBrush( QBrush( myShadow2Color, params()->shadowPattern() ) );
01424 else
01425 painter->setBrush( NoBrush );
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438 if( !tooHigh && !tooLow || tooHigh && cellValue <= 0 )
01439 painter->drawPolygon( points );
01440
01441
01442 if ( region ) {
01443 QPointArray points2cpy( points.copy() );
01444
01445 points2cpy.translate( _dataRect.x(), _dataRect.y() );
01446
01447
01448 *region += QRegion( points2cpy );
01449
01450 }
01451
01452
01453 if ( bNormalMode || bMultiRows ||
01454
01455
01456
01457 ( maxValueInThisColumn <= 0.0 && dataset == firstValidValue ) ||
01458
01459 ( minValueInThisColumn >= 0.0 && dataset == lastValidPositiveValue ) ||
01460
01461
01462
01463 ( dataset == lastValidPositiveValue ) ) {
01464 if ( cellValue <= 0 || cellValue < minColumnValue) {
01465
01466 if ( tooLow ) {
01467 points.setPoint(0,excessRectNegative.bottomLeft());
01468 points.setPoint(1,excessRectNegative.topLeft().x() + static_cast <int> (sideBarHeight),
01469 excessRectNegative.bottom() - static_cast <int> (sideBarHeight));
01470 points.setPoint(2,excessRectNegative.bottomRight().x() + static_cast <int> (sideBarHeight),
01471 excessRectNegative.bottom() - static_cast <int> (sideBarHeight));
01472 points.setPoint(3,excessRectNegative.bottomRight());
01473 }else {
01474
01475 points.setPoint(0,frontRectNegative.topLeft() );
01476 points.setPoint(1,frontRectNegative.topLeft().x() + static_cast <int> (sideBarHeight), rightRectNegative.top());
01477 points.setPoint(2,rightRectNegative.topRight() );
01478 points.setPoint(3,rightRectNegative.topRight().x() - static_cast <int> (sideBarHeight),
01479 frontRectNegative.topRight().y() );
01480 }
01481
01482 } else {
01483
01484 if ( tooHigh ) {
01485 points.setPoint(0, excessRectPositive.topLeft());
01486 points.setPoint(1, excessRectPositive.topLeft().x() + static_cast <int> (sideBarHeight),
01487 excessRectPositive.top() - static_cast <int> (sideBarHeight) );
01488 points.setPoint(2, excessRectPositive.topRight().x() + static_cast <int> (sideBarHeight),
01489 excessRectPositive.top() - static_cast <int> (sideBarHeight));
01490 points.setPoint(3, excessRectPositive.topRight());
01491
01492 } else {
01493
01494
01495 points.setPoint(0, frontRectPositive.topLeft());
01496 points.setPoint(1, frontRectPositive.topLeft().x() + static_cast <int> (sideBarHeight),
01497 rightRectPositive.top() );
01498 points.setPoint(2, rightRectPositive.topRight());
01499 points.setPoint(3, rightRectPositive.topRight().x() - static_cast <int> (sideBarHeight),
01500 frontRectPositive.topRight().y());
01501 }
01502 }
01503
01504 if ( cellValue < 0.0 ) {
01505 painter->setBrush( bMultiRows ? myBarColor : black );
01506 }
01507 else
01508 painter->setBrush( QBrush( myShadow1Color, params()->shadowPattern() ) );
01509 if ( !myShadow1Color.isValid() )
01510 painter->setBrush( NoBrush );
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525 if (!tooHigh && !tooLow || (tooHigh && cellValue <= 0) )
01526 painter->drawPolygon( points );
01527
01528
01529 if ( region ) {
01530 points.translate( _dataRect.x(), _dataRect.y() );
01531 *region += QRegion( points );
01532 }
01533
01534 }
01535
01536 }
01537
01538 if( regions && region ) {
01539 if( bShowThisBar && !bDrawExtraLines )
01540 regions->append(
01541 _bThreeDBars
01542 ? new KDChartDataRegion( *region, dataset, value, chart )
01543
01544 : new KDChartDataRegion( dataset, value, chart, region->boundingRect() ) );
01545 delete region;
01546 }
01547
01548 }
01549 }
01550 }else{
01551
01552
01553
01554 int iDummy1, iDummy2;
01555 calculateXFront1_2( bNormalMode, bIsVeryFirstBar, bIsFirstDataset, _bThreeDBars,
01556 xpos, valueBlockGap, datasetGap, frontBarWidth,
01557 iDummy1, iDummy2, prevFrontX2 );
01558 }
01559
01560
01561
01562 if ( params()->barChartSubType() == KDChartParams::BarStacked ||
01563 params()->barChartSubType() == KDChartParams::BarPercent )
01564 if ( barHeight < 0.0 )
01565 yposNegatives -= barHeight;
01566 else
01567 yposPositives -= barHeight;
01568 } else {
01569
01570
01571
01572 int iDummy1, iDummy2;
01573 calculateXFront1_2( bNormalMode, bIsVeryFirstBar, bIsFirstDataset, _bThreeDBars,
01574 xpos, valueBlockGap, datasetGap, frontBarWidth,
01575 iDummy1, iDummy2, prevFrontX2 );
01576 }
01577
01578
01579
01580 bool bAdvanceToNextValue =
01581 ( bMultiRows ? (dataset == chartDatasetStart) : (dataset == chartDatasetEnd)
01582 || ( params()->chartSourceMode( bMultiRows ? dataset-1 : dataset+1 )
01583 == KDChartParams::DataEntry ) );
01584
01585 if ( bNormalMode ) {
01586 if( bAdvanceToNextValue )
01587 xpos += barWidth;
01588
01589 if ( dataset < myLastDataEntryDataset )
01590 xpos += datasetGap;
01591 }
01592 if( bAdvanceToNextValue || bMultiRows ){
01593
01594 shiftMyPainter( -nShiftX, nShiftY );
01595 }
01596 bIsVeryFirstBar = false;
01597 bIsFirstDataset = false;
01598 }
01599
01600
01601
01602 if ( bNormalMode ){
01603
01604 xpos += valueBlockGap;
01605
01606 }else{
01607
01608 xpos += valueBlockGap + barWidth;
01609
01610 yposPositives = yposPositivesStart;
01611 yposNegatives = yposNegativesStart;
01612 }
01613
01614 shiftMyPainterBack();
01615 }
01616
01617 }
01618
01619
01620 if( bMultiRows )
01621 painter->setClipping( bHadClipping );
01622 }