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