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 "KDChartLinesPainter.h"
00030 #include <KDChartParams.h>
00031 #include <KDChartPropertySet.h>
00032
00033 #include <qpainter.h>
00034
00035 #if COMPAT_QT_VERSION >= 0x030000
00036 #include <qvaluevector.h>
00037 #else
00038 #include <qarray.h>
00039 #endif
00040
00041 #include <stdlib.h>
00042
00055 KDChartLinesPainter::KDChartLinesPainter( KDChartParams* params ) :
00056 KDChartAxesPainter( params )
00057 {
00058
00059
00060 }
00061
00062
00066 KDChartLinesPainter::~KDChartLinesPainter()
00067 {
00068
00069 }
00070
00071
00082 void KDChartLinesPainter::paintData( QPainter* painter,
00083 KDChartTableDataBase* data,
00084 bool paint2nd,
00085 KDChartDataRegionList* regions )
00086 {
00087 paintDataInternal( painter, data,
00088 true,
00089 params()->lineMarker() && !params()->threeDLines(),
00090 false,
00091 paint2nd,
00092 regions );
00093 }
00094
00115 void KDChartLinesPainter::paintDataInternal( QPainter* painter,
00116 KDChartTableDataBase* data,
00117 bool centerThePoints,
00118 bool drawMarkers,
00119 bool isArea,
00120 bool paint2nd,
00121 KDChartDataRegionList* regions )
00122 {
00123 mCenterThePoints = centerThePoints;
00124 mDrawMarkers = drawMarkers;
00125 mIsArea = isArea;
00126 mChartType = paint2nd ? params()->additionalChartType()
00127 : params()->chartType();
00128
00129 KDChartAxesPainter::paintData( painter, data, paint2nd, regions );
00130 }
00131
00132
00133 #define DEGTORAD(d) (d)*M_PI/180
00134
00140 QPoint KDChartLinesPainter::project( int x, int y, int z )
00141 {
00142
00143 double xrad = DEGTORAD( params()->threeDLineXRotation() );
00144 double yrad = DEGTORAD( params()->threeDLineYRotation() );
00145 QPoint ret( static_cast<int>( x*cos( yrad ) + z * sin( yrad ) ),
00146 static_cast<int>( y*cos( xrad ) - z * sin( xrad ) ) );
00147 return ret;
00148 }
00149
00150 bool KDChartLinesPainter::isNormalMode() const
00151 {
00152 return KDChartParams::LineNormal == params()->lineChartSubType();
00153 }
00154
00155 int KDChartLinesPainter::clipShiftUp( bool, double ) const
00156 {
00157 return 0;
00158 }
00159
00160
00161 class MyPoint
00162 {
00163 public:
00164 MyPoint() : bValid( false ), bSkipThis( false ), cellValue( 0.0 ) {}
00165 void set( int x, int y, double value ) {
00166 bValid = true;
00167 p.setX( x );
00168 p.setY( y );
00169 cellValue = value;
00170 }
00171 void setSkipThis( bool skipThis ) {
00172 bSkipThis = skipThis;
00173 }
00174 QPoint p;
00175 bool bValid;
00176 bool bSkipThis;
00177 double cellValue;
00178 };
00179
00180
00181 void KDChartLinesPainter::specificPaintData( QPainter* painter,
00182 const QRect& ,
00183 KDChartTableDataBase* data,
00184 KDChartDataRegionList* regions,
00185 const KDChartAxisParams* ordinatePara,
00186 bool ,
00187 uint chart,
00188 double logWidth,
00189 double ,
00190 double logHeight,
00191 double axisYOffset,
00192 double minColumnValue,
00193 double maxColumnValue,
00194 double columnValueDistance,
00195 uint ,
00196 uint ,
00197 uint datasetStart,
00198 uint datasetEnd )
00199 {
00200 if( !data ) return;
00201
00202
00203 abscissaInfos ai;
00204 ai.bCenterThePoints = mCenterThePoints;
00205 calculateAbscissaInfos( *params(), *data,
00206 datasetStart, datasetEnd,
00207 logWidth, _dataRect,
00208 ai );
00209 mCenterThePoints = ai.bCenterThePoints;
00210
00211 bool bOrdinateDecreasing = ordinatePara
00212 ? ordinatePara->axisValuesDecreasing()
00213 : false;
00214 bool bOrdinateIsLogarithmic
00215 = ordinatePara
00216 ? (KDChartAxisParams::AxisCalcLogarithmic == ordinatePara->axisCalcMode())
00217 : false;
00218
00219
00220 const double ordinatePixelsPerUnit
00221 = ( ordinatePara
00222 && (0.0 != ordinatePara->trueAxisDeltaPixels())
00223 && (0.0 != ordinatePara->trueAxisDelta()))
00224 ? ordinatePara->trueAxisDeltaPixels() / ordinatePara->trueAxisDelta()
00225 : logHeight / columnValueDistance;;
00226
00227
00228
00229 const bool showThreeDLines = !mIsArea && params()->threeDLines();
00230
00231 enum { Normal, Stacked, Percent } mode = Normal;
00232 if ( ( ( mChartType == KDChartParams::Line )
00233 && ( params()->lineChartSubType() == KDChartParams::LineNormal ) )
00234 || ( ( mChartType == KDChartParams::Area )
00235 && ( params()->areaChartSubType() == KDChartParams::AreaNormal ) ) )
00236 mode = Normal;
00237 else if ( ( ( mChartType == KDChartParams::Line )
00238 && ( params()->lineChartSubType() == KDChartParams::LineStacked ) )
00239 || ( ( mChartType == KDChartParams::Area )
00240 && ( params()->areaChartSubType() == KDChartParams::AreaStacked ) ) )
00241 mode = Stacked;
00242 else if ( ( ( mChartType == KDChartParams::Line )
00243 && ( params()->lineChartSubType() == KDChartParams::LinePercent ) )
00244 || ( ( mChartType == KDChartParams::Area )
00245 && ( params()->areaChartSubType() == KDChartParams::AreaPercent ) ) )
00246 mode = Percent;
00247 else
00248 qDebug( "Internal error in KDChartLinesPainter::paintDataInternal(): Unknown subtype" );
00249
00250
00251 QMap < int, double > currentValueSums;
00252 if ( mode == Stacked || mode == Percent ) {
00253
00254
00255 for ( int value = 0; value < ai.numValues; ++value )
00256 currentValueSums[ value ] = 0.0;
00257 }
00258 QMap < int, double > totalValueSums;
00259
00260
00261 double zeroXAxisI;
00262 if ( mode == Percent ) {
00263 if ( minColumnValue == 0.0 )
00264 zeroXAxisI = logHeight + axisYOffset;
00265 else if( maxColumnValue == 0.0 )
00266 zeroXAxisI = _dataRect.y() + axisYOffset;
00267 else
00268 zeroXAxisI = logHeight / 2.0 + _dataRect.y();
00269 } else
00270 zeroXAxisI = ordinatePara->axisZeroLineStartY() - _dataRect.y();
00271
00272
00273
00274
00275 int xShift = mCenterThePoints ? static_cast < int > ( ai.pointDist * 0.5 ) : 0;
00276
00277
00278
00279
00280 int arrayNumDatasets = 0;
00281 int arrayNumValues = ai.bAbscissaHasTrueAxisDtValues
00282 ? data->cols()
00283 : ai.numValues;
00284 int dataset;
00285 for( dataset = datasetEnd;
00286 ( dataset >= static_cast < int > ( datasetStart ) && dataset >= 0 );
00287 --dataset )
00288 ++arrayNumDatasets;
00289 #if COMPAT_QT_VERSION >= 0x030000
00290 QValueVector<MyPoint> allPoints(
00291 #else
00292 QArray<MyPoint> allPoints(
00293 #endif
00294 arrayNumDatasets * arrayNumValues );
00295
00296 KDChartPropertySet curPropSet;
00297 int curPropSetId = KDChartPropertySet::UndefinedID;
00298
00299 for( dataset = datasetEnd; ( dataset >= (int)datasetStart && dataset >= 0 ); --dataset ) {
00300
00301 int prevPointX = -1;
00302 int prevPointY = -1;
00303
00304 const KDChartParams::LineMarkerStyle
00305 defaultMarkerStyle = params()->lineMarkerStyle( dataset );
00306 const QPen default2DPen( params()->lineColor().isValid()
00307 ? params()->lineColor()
00308 : params()->dataColor( dataset ),
00309 params()->lineWidth(),
00310 params()->lineStyle( dataset ) );
00311
00312 if( ai.bAbscissaHasTrueAxisDtValues )
00313 ai.numValues = data->cols();
00314
00315 QVariant vValY;
00316 QVariant vValX;
00317 int cellPropID;
00318 for( int value = 0; value < ai.numValues; ++value ) {
00319
00320
00321 double valueTotal = 0.0;
00322 if( mode == Percent ) {
00323 valueTotal = 0.0;
00324
00325 for ( uint dataset2 = datasetStart;
00326 dataset2 <= datasetEnd;
00327 ++dataset2 ) {
00328 if( data->cellCoord( dataset2, value, vValY, 1 ) &&
00329 QVariant::Double == vValY.type() )
00330 valueTotal += vValY.toDouble();
00331 }
00332 }
00333
00334 if( data->cellContent( dataset, value, vValY, vValX, cellPropID ) &&
00335 QVariant::Double == vValY.type() &&
00336 ( !ai.bCellsHaveSeveralCoordinates || QVariant::Invalid != vValX.type() ) ){
00337
00338
00339
00340
00341 double cellValue = vValY.toDouble();
00342 double drawValue = 0.0;
00343
00344 if ( mode == Stacked )
00345 drawValue = ( cellValue + currentValueSums[ value ] ) * ordinatePixelsPerUnit;
00346 else if ( mode == Percent )
00347 drawValue = ( ( cellValue + currentValueSums[ value ] ) / valueTotal ) * 100.0 * ordinatePixelsPerUnit;
00348 else {
00349
00350 if( bOrdinateIsLogarithmic ){
00351 if( 0.0 < cellValue )
00352 drawValue = log10( cellValue ) * ordinatePixelsPerUnit;
00353 else
00354 drawValue = -10250.0;
00355
00356
00357 }else{
00358 drawValue = cellValue * ordinatePixelsPerUnit * (bOrdinateDecreasing ? -1.0 : 1.0);
00359
00360
00361 }
00362 }
00363
00364
00365
00366
00367 double xValue;
00368 bool skipMe = !calculateAbscissaAxisValue( vValX, ai, value,
00369 xValue );
00370
00371
00372
00373
00374 if( !skipMe ){
00375
00376
00377
00378 double pY = QMIN( zeroXAxisI - drawValue,
00379 (logHeight + axisYOffset) * 3 );
00380 pY = QMAX( pY, -(logHeight + axisYOffset) * 3 );
00381
00382 int myPointX = static_cast < int > ( xValue ) + xShift;
00383 int myPointY = static_cast < int > ( pY );
00384
00385 if( cellPropID == curPropSetId &&
00386 myPointX == prevPointX &&
00387 myPointY == prevPointY ){
00388 allPoints[ static_cast < int > ( datasetEnd-dataset )
00389 * arrayNumValues + value ].setSkipThis( true );
00390 skipMe = true;
00391
00392 }else{
00393
00394 allPoints[ static_cast < int > ( datasetEnd-dataset )
00395 * arrayNumValues + value ].set( myPointX, myPointY, cellValue );
00396
00397 }
00398 if( !skipMe ){
00399
00400
00401
00402
00403 if( cellPropID != curPropSetId ){
00404
00405
00406
00407 if( cellPropID != KDChartPropertySet::UndefinedID &&
00408 params()->calculateProperties( cellPropID,
00409 curPropSet ) ){
00410 curPropSetId = cellPropID;
00411
00412
00413 }else{
00414 curPropSetId = KDChartPropertySet::UndefinedID;
00415 }
00416 }
00417
00418
00419 if( mChartType == KDChartParams::Line ){
00420 if( curPropSetId != KDChartPropertySet::UndefinedID ){
00421 drawExtraLinesAndMarkers(
00422 curPropSet,
00423 default2DPen,
00424 defaultMarkerStyle,
00425 myPointX, myPointY,
00426 painter,
00427 ai.abscissaPara,
00428 ordinatePara,
00429 logWidth/1000.0,
00430 logHeight/1000.0,
00431 false );
00432 }
00433 }
00434 prevPointX = myPointX;
00435 prevPointY = myPointY;
00436 }
00437 }
00438
00439 if ( mode == Stacked || mode == Percent ) {
00440 if( cellValue == KDCHART_POS_INFINITE )
00441 currentValueSums[ value ] = KDCHART_POS_INFINITE;
00442 else if( currentValueSums[ value ] != KDCHART_POS_INFINITE )
00443 currentValueSums[ value ] += cellValue;
00444 }
00445 }
00446 }
00447 }
00448
00449
00450
00451 QPointArray previousPoints;
00452
00453
00454
00455
00456
00457
00458 const bool defaultDrawMarkers = mDrawMarkers;
00459
00460 for ( dataset = datasetEnd; ( dataset >= (int)datasetStart && dataset >= 0 ); --dataset ) {
00461
00462
00463
00464
00465
00466 const QPen default2DPen( params()->lineColor().isValid()
00467 ? params()->lineColor()
00468 : params()->dataColor( dataset ),
00469 params()->lineWidth(),
00470 params()->lineStyle( dataset ) );
00471 bool currentDrawMarkers = defaultDrawMarkers;
00472 const KDChartParams::LineMarkerStyle markerStyle = params()->lineMarkerStyle( dataset );
00473
00474
00475 QPtrVector< QPointArray > points( 2 );
00476 points.setAutoDelete( true );
00477
00478
00479
00480 QPtrVector< QPointArray > oripoints( 2 );
00481 oripoints.setAutoDelete( true );
00482
00483 int i = 0;
00484 for( i = 0; i < 2; ++i ) {
00485 points.insert( i, new QPointArray( ai.numValues + 2 ) );
00486 oripoints.insert( i, new QPointArray( ai.numValues + 2 ) );
00487 }
00488
00489 if( ai.bAbscissaHasTrueAxisDtValues )
00490 ai.numValues = data->cols();
00491
00492 int point = 0;
00493
00494 for ( int value = 0; value < ai.numValues; ++value ) {
00495
00496
00497
00498 currentDrawMarkers = defaultDrawMarkers;
00499 int cellPropID;
00500 if( data->cellProp( dataset, value, cellPropID ) &&
00501 cellPropID != curPropSetId ){
00502 if( cellPropID != KDChartPropertySet::UndefinedID &&
00503 params()->calculateProperties( cellPropID,
00504 curPropSet ) )
00505 curPropSetId = cellPropID;
00506 else
00507 curPropSetId = KDChartPropertySet::UndefinedID;
00508 }
00509 if( curPropSetId != KDChartPropertySet::UndefinedID ){
00510
00511
00512
00513 int iDummy;
00514 curPropSet.hasOwnShowMarker( iDummy, currentDrawMarkers );
00515 }
00516
00517
00518 int iVec = static_cast < int > ( datasetEnd-dataset ) * arrayNumValues + value;
00519 if( allPoints[ iVec ].bValid && !allPoints[ iVec ].bSkipThis ){
00520 const MyPoint& mp = allPoints[iVec];
00521
00522
00523
00524
00525
00526
00527 if( showThreeDLines ) {
00528 points[0]->setPoint( point, project( mp.p.x(), mp.p.y(),
00529 (datasetStart+dataset)*params()->threeDLineDepth() ) );
00530 points[1]->setPoint( point, project( mp.p.x(), mp.p.y(),
00531 (datasetStart+dataset + 1)*params()->threeDLineDepth() ) );
00532 oripoints[0]->setPoint( point, mp.p.x(), mp.p.y() );
00533 oripoints[1]->setPoint( point, mp.p.x() - (datasetStart+dataset + 1)*params()->threeDLineDepth(),
00534 mp.p.y() - (datasetStart+dataset + 1)*params()->threeDLineDepth() );
00535
00536 } else
00537
00538 points[0]->setPoint( point, mp.p );
00539 ++point;
00540
00541 int x = mp.p.x();
00542 int y = QMAX(QMIN(mp.p.y(),
00543 static_cast < int > (logHeight +axisYOffset)),
00544 0);
00545 bool markerIsOutside = y != mp.p.y();
00546
00547 if ( currentDrawMarkers ){
00548 uint theAlignment = Qt::AlignCenter;
00549 bool hasOwnSize = false;
00550 int theWidth = 0;
00551 int theHeight = 0;
00552 QColor theColor(params()->dataColor( dataset ));
00553 int theStyle = markerStyle;
00554 if( curPropSetId != KDChartPropertySet::UndefinedID ){
00555
00556
00557
00558 int iDummy;
00559 curPropSet.hasOwnMarkerAlign( iDummy, theAlignment );
00560 curPropSet.hasOwnMarkerColor( iDummy, theColor );
00561 curPropSet.hasOwnMarkerStyle( iDummy, theStyle );
00562 QSize size(theWidth, theHeight);
00563 hasOwnSize = curPropSet.hasOwnMarkerSize(iDummy, size);
00564 if( hasOwnSize ){
00565 theWidth = size.width();
00566 theHeight = size.height();
00567 }
00568 }
00569
00570 drawMarker( painter,
00571 params(),
00572 _areaWidthP1000, _areaHeightP1000,
00573 _dataRect.x(),
00574 _dataRect.y(),
00575 markerIsOutside
00576 ? KDChartParams::LineMarker1Pixel
00577 : theStyle,
00578 theColor,
00579 QPoint(x,y),
00580 dataset, value, chart, regions,
00581 hasOwnSize ? &theWidth : 0,
00582 hasOwnSize ? &theHeight : 0,
00583 theAlignment );
00584
00585 }
00586
00587 else if( regions ) {
00588 QRect rect( QPoint( x-1, y-1 ), QPoint( x+1, y+1 ) );
00589 rect.moveBy( _dataRect.x(), _dataRect.y() );
00590 regions->append(
00591 new KDChartDataRegion(dataset, value, chart, rect) );
00592 }
00593
00594 }
00595 }
00596 if ( point ) {
00597 bool bDrawLines = (0 != params()->lineWidth());
00598
00599 if ( mIsArea ) {
00600
00601
00602
00603
00604 painter->setPen( QPen( Qt::NoPen ) );
00605 const QBrush datasetBrush( params()->dataColor( dataset ), Qt::SolidPattern );
00606 painter->setBrush( datasetBrush );
00607 QBrush currentBrush( datasetBrush );
00608
00609 if ( mode == Normal || dataset == (int)datasetEnd ) {
00612
00613
00614 QPoint lastPoint = points[0]->point( point - 1 );
00615
00616
00617
00618
00619
00620 int yCoord;
00621 if ( params()->areaLocation() == KDChartParams::AreaBelow ||
00622 mode == Percent )
00623 yCoord = static_cast<int>(zeroXAxisI);
00624 else
00625 yCoord = static_cast<int>(axisYOffset);
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641 curPropSetId = KDChartPropertySet::UndefinedID;
00642 for( int value = 0; value < point-1; ++value ) {
00643
00644 int cellPropID;
00645 if( data->cellProp( dataset, value, cellPropID ) &&
00646 cellPropID != curPropSetId ){
00647
00648 if( cellPropID != KDChartPropertySet::UndefinedID &&
00649 params()->calculateProperties( cellPropID,
00650 curPropSet ) ){
00651 curPropSetId = cellPropID;
00652 }else{
00653 curPropSetId = KDChartPropertySet::UndefinedID;
00654 }
00655
00656 QBrush theAreaBrush = datasetBrush;
00657
00658 if( curPropSetId != KDChartPropertySet::UndefinedID ){
00659
00660
00661
00662 int iDummy;
00663 curPropSet.hasOwnAreaBrush( iDummy, theAreaBrush );
00664 }
00665 painter->setBrush( theAreaBrush );
00666
00667 }
00668 QPointArray segment( 4 );
00669 segment.setPoint( 0, points[0]->point( value ) );
00670 segment.setPoint( 1, points[0]->point( value+1 ) );
00671 segment.setPoint( 2, points[0]->point( value+1 ).x(), yCoord );
00672 segment.setPoint( 3, points[0]->point( value ).x(), yCoord );
00673 painter->drawPolygon( segment );
00674 }
00675
00676
00677
00678
00679
00680
00681
00682 }
00683 else {
00684
00685
00686
00687
00688
00689 QPointArray thisSection = points[0]->copy();
00690
00691 thisSection.resize( point + previousPoints.size() );
00692
00693
00694
00695 for ( unsigned int i = 0; i < previousPoints.size(); ++i ) {
00696 thisSection.setPoint( point + i,
00697 previousPoints.point( previousPoints.size() - i - 1 ) );
00698
00699
00700 }
00701 painter->drawPolygon( thisSection );
00702 }
00703
00704 painter->setBrush( Qt::NoBrush );
00705 painter->setPen( QPen( params()->outlineDataColor(),
00706 params()->outlineDataLineWidth() ) );
00707 } else {
00708
00709 if( showThreeDLines ) {
00710
00711
00712
00713 painter->setBrush( params()->dataColor( dataset ) );
00714 painter->setPen( QPen( params()->outlineDataColor(),
00715 params()->outlineDataLineWidth() ) );
00716 } else {
00717
00718
00719
00720 painter->setBrush( Qt::NoBrush );
00721 painter->setPen( default2DPen );
00722 }
00723 }
00724
00725
00726
00727
00728 if( bDrawLines &&
00729 ( (mode != Percent) || !mIsArea || (dataset != (int)datasetEnd) ) ){
00730 if( showThreeDLines ) {
00731
00732
00733 for ( int value = 0; value < point-1; ++value ) {
00734
00735
00736
00737
00738
00739 QPointArray rotatedSegment( 4 );
00740 rotatedSegment.setPoint( 0, points[0]->point( value ));
00741 rotatedSegment.setPoint( 1, points[0]->point( value+1 ) );
00742 rotatedSegment.setPoint( 2, points[1]->point( value+1 ) );
00743 rotatedSegment.setPoint( 3, points[1]->point( value ) );
00744
00745
00746 QPointArray trueSegment( 4 );
00747 trueSegment.setPoint( 0, oripoints[0]->point( value ));
00748 trueSegment.setPoint( 1, oripoints[0]->point( value+1 ) );
00749 trueSegment.setPoint( 2, oripoints[1]->point( value+1 ) );
00750 trueSegment.setPoint( 3, oripoints[1]->point( value ) );
00751
00752
00753
00754
00755
00756 int dx30 = rotatedSegment.point(3).x() - rotatedSegment.point(0).x();
00757 int dy30 = rotatedSegment.point(3).y() - rotatedSegment.point(0).y();
00758
00759 int dx12 = rotatedSegment.point(2).x() - rotatedSegment.point(1).x();
00760 int dy12 = rotatedSegment.point(2).y() - rotatedSegment.point(1).y();
00761
00762
00763 QPointArray segment( 4 );
00764 segment.setPoint( 0, trueSegment.point(0) );
00765 segment.setPoint( 1, trueSegment.point(1) );
00766 segment.setPoint( 2, trueSegment.point(1).x() + dx12, trueSegment.point(1).y() + dy12 );
00767 segment.setPoint( 3, trueSegment.point(0).x() + dx30, trueSegment.point(0).y() + dy30);
00768
00769
00770
00771 painter->drawPolygon( segment );
00772
00773
00774
00775
00776 }
00777 } else {
00778 QPoint p1, p2;
00779
00780
00781
00782 bool b4PMarkers = KDChartParams::LineMarker4Pixels == markerStyle;
00783 bool bTinyMarkers =
00784 KDChartParams::LineMarker1Pixel == markerStyle || b4PMarkers;
00785 curPropSetId = KDChartPropertySet::UndefinedID;
00786 painter->setPen( default2DPen );
00787 for ( int value = 0; value < point-1; ++value ) {
00788 p1 = points[0]->point( value );
00789 p2 = points[0]->point( value+1 );
00790
00791
00792
00793 currentDrawMarkers = defaultDrawMarkers;
00794 int cellPropID;
00795 if( data->cellProp( dataset, value, cellPropID ) &&
00796 cellPropID != curPropSetId ){
00797 if( cellPropID != KDChartPropertySet::UndefinedID &&
00798 params()->calculateProperties( cellPropID,
00799 curPropSet ) ){
00800 curPropSetId = cellPropID;
00801 }else{
00802 curPropSetId = KDChartPropertySet::UndefinedID;
00803 }
00804
00805 int theLineWidth = default2DPen.width();
00806 QColor theLineColor = default2DPen.color();
00807 Qt::PenStyle theLineStyle = default2DPen.style();
00808 if( curPropSetId != KDChartPropertySet::UndefinedID ){
00809
00810
00811
00812 int iDummy;
00813 curPropSet.hasOwnLineWidth ( iDummy, theLineWidth );
00814 curPropSet.hasOwnLineColor ( iDummy, theLineColor );
00815 curPropSet.hasOwnLineStyle ( iDummy, theLineStyle );
00816 curPropSet.hasOwnShowMarker( iDummy, currentDrawMarkers );
00817 }
00818 painter->setPen( QPen( theLineColor,
00819 theLineWidth,
00820 theLineStyle ) );
00821 }
00822
00823 if( !currentDrawMarkers ){
00824
00825 painter->drawLine( p1, p2 );
00826 }else{
00827 int dx = p2.x() - p1.x();
00828 int dy = p2.y() - p1.y();
00829 if( !bTinyMarkers || (abs(dx) > 4) || (abs(dy) > 4) ){
00830 if( bTinyMarkers ) {
00831 double m = !dx ? 100.0
00832 : !dy ? 0.01
00833 : ((double)dy / (double)dx);
00834 double am = fabs(m);
00835 int dxx;
00836 int dyy;
00837 if( 0.25 > am ){
00838 dxx = 3;
00839 dyy = 0;
00840 }else if( 0.67 > am ){
00841 dxx = 3;
00842 dyy = 1;
00843 }else if( 1.33 > am ){
00844 dxx = 2;
00845 dyy = 2;
00846 }else if( 4.0 > am ){
00847 dxx = 1;
00848 dyy = 3;
00849 }else{
00850 dxx = 0;
00851 dyy = 3;
00852 }
00853 if( 0 > dx )
00854 dxx *= -1;
00855 if( 0 > dy )
00856 dyy *= -1;
00857 if( b4PMarkers ){
00858 if( 0 < dx )
00859 ++p1.rx();
00860 else if( 0 > dx )
00861 ++p2.rx();
00862 if( 0 < dy )
00863 ++p1.ry();
00864 else if( 0 > dy )
00865 ++p2.ry();
00866 }
00867 p1.rx() += dxx; p1.ry() += dyy;
00868 p2.rx() -= dxx; p2.ry() -= dyy;
00869 }
00870
00871 painter->drawLine( p1, p2 );
00872 }
00873 }
00874 }
00875 }
00876 }
00877 }
00878
00879
00880
00881 points[0]->resize( point );
00882 previousPoints = points[0]->copy();
00883 }
00884
00885
00886
00887
00888 if( mChartType == KDChartParams::Line ){
00889 for( dataset = datasetEnd; ( dataset >= (int)datasetStart && dataset >= 0 ); --dataset ) {
00890
00891 const KDChartParams::LineMarkerStyle
00892 defaultMarkerStyle = params()->lineMarkerStyle( dataset );
00893 const QPen default2DPen( params()->lineColor().isValid()
00894 ? params()->lineColor()
00895 : params()->dataColor( dataset ),
00896 params()->lineWidth(),
00897 params()->lineStyle( dataset ) );
00898
00899 if( ai.bAbscissaHasTrueAxisDtValues )
00900 ai.numValues = data->cols();
00901
00902 for ( int value = 0; value < ai.numValues; ++value ) {
00903 int iVec = static_cast < int > ( datasetEnd-dataset ) * arrayNumValues + value;
00904 if( allPoints[ iVec ].bValid ){
00905 const MyPoint& mp = allPoints[iVec];
00906
00907
00908
00909
00910
00911
00912 int cellPropID;
00913 if( data->cellProp( dataset, value, cellPropID ) &&
00914 cellPropID != curPropSetId ){
00915 if( cellPropID != KDChartPropertySet::UndefinedID &&
00916 params()->calculateProperties( cellPropID,
00917 curPropSet ) )
00918 curPropSetId = cellPropID;
00919 else
00920 curPropSetId = KDChartPropertySet::UndefinedID;
00921 }
00922 if( curPropSetId != KDChartPropertySet::UndefinedID ){
00923 drawExtraLinesAndMarkers(
00924 curPropSet,
00925 default2DPen,
00926 defaultMarkerStyle,
00927 mp.p.x(), mp.p.y(),
00928 painter,
00929 ai.abscissaPara,
00930 ordinatePara,
00931 logWidth/1000.0,
00932 logHeight/1000.0,
00933 true );
00934 }
00935 }
00936 }
00937 }
00938 }
00939
00940
00941
00942
00943
00944 }