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 #include <QPainter>
00027 #include <QDebug>
00028 #include <QApplication>
00029 #include <QAbstractProxyModel>
00030 #include <QStandardItemModel>
00031 #include <QSizeF>
00032
00033 #include "KDChartAbstractCoordinatePlane.h"
00034 #include "KDChartChart.h"
00035 #include "KDChartDataValueAttributes.h"
00036 #include "KDChartTextAttributes.h"
00037 #include "KDChartMarkerAttributes.h"
00038 #include "KDChartAbstractDiagram.h"
00039 #include "KDChartAbstractDiagram_p.h"
00040 #include "KDChartAttributesModel.h"
00041 #include "KDChartAbstractThreeDAttributes.h"
00042 #include "KDChartThreeDLineAttributes.h"
00043
00044 #include <KDABLibFakes>
00045
00046
00047 using namespace KDChart;
00048
00049 namespace KDChart {
00050 class PrivateAttributesModel : public AttributesModel {
00051 Q_OBJECT
00052 public:
00053 explicit PrivateAttributesModel( QAbstractItemModel* model, QObject * parent = 0 )
00054 : AttributesModel(model,parent) {}
00055 };
00056 }
00057
00058 AbstractDiagram::Private::Private()
00059 : plane( 0 )
00060 , attributesModel( new PrivateAttributesModel(0,0) )
00061 , allowOverlappingDataValueTexts( false )
00062 , antiAliasing( true )
00063 , percent( false )
00064 , datasetDimension( 1 )
00065 , databoundariesDirty(true)
00066 , lastRoundedValue()
00067 , lastX( 0 )
00068 , mCachedFontMetrics( QFontMetrics( qApp->font() ) )
00069 {
00070 }
00071
00072 AbstractDiagram::Private::~Private()
00073 {
00074 if( attributesModel && qobject_cast<PrivateAttributesModel*>(attributesModel) )
00075 delete attributesModel;
00076 }
00077
00078 void AbstractDiagram::Private::init()
00079 {
00080 }
00081
00082 void AbstractDiagram::Private::init( AbstractCoordinatePlane* newPlane )
00083 {
00084 plane = newPlane;
00085 }
00086
00087 bool AbstractDiagram::Private::usesExternalAttributesModel()const
00088 {
00089 return ( ! attributesModel.isNull() ) &&
00090 ( ! qobject_cast<PrivateAttributesModel*>(attributesModel) );
00091 }
00092
00093 void AbstractDiagram::Private::setAttributesModel( AttributesModel* amodel )
00094 {
00095 if( !attributesModel.isNull() &&
00096 qobject_cast<PrivateAttributesModel*>(attributesModel) ) {
00097 delete attributesModel;
00098 }
00099 attributesModel = amodel;
00100 }
00101
00102 AbstractDiagram::Private::Private( const AbstractDiagram::Private& rhs ) :
00103
00104 plane( 0 ),
00105 attributesModelRootIndex( QModelIndex() ),
00106 attributesModel( rhs.attributesModel ),
00107 allowOverlappingDataValueTexts( rhs.allowOverlappingDataValueTexts ),
00108 antiAliasing( rhs.antiAliasing ),
00109 percent( rhs.percent ),
00110 datasetDimension( rhs.datasetDimension ),
00111 mCachedFontMetrics( rhs.cachedFontMetrics() )
00112 {
00113 attributesModel = new PrivateAttributesModel( 0, 0);
00114 attributesModel->initFrom( rhs.attributesModel );
00115 }
00116
00117 #define d d_func()
00118
00119 AbstractDiagram::AbstractDiagram ( QWidget* parent, AbstractCoordinatePlane* plane )
00120 : QAbstractItemView ( parent ), _d( new Private() )
00121 {
00122 _d->init( plane );
00123 }
00124
00125 AbstractDiagram::~AbstractDiagram()
00126 {
00127 delete _d;
00128 }
00129
00130 void AbstractDiagram::init()
00131 {
00132 }
00133
00134
00135 bool AbstractDiagram::compare( const AbstractDiagram* other )const
00136 {
00137 if( other == this ) return true;
00138 if( ! other ){
00139
00140 return false;
00141 }
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 return
00189 (horizontalScrollBarPolicy() == other->horizontalScrollBarPolicy()) &&
00190 (verticalScrollBarPolicy() == other->verticalScrollBarPolicy()) &&
00191
00192 (frameShadow() == other->frameShadow()) &&
00193 (frameShape() == other->frameShape()) &&
00194 (frameWidth() == other->frameWidth()) &&
00195 (lineWidth() == other->lineWidth()) &&
00196 (midLineWidth() == other->midLineWidth()) &&
00197
00198 (alternatingRowColors() == other->alternatingRowColors()) &&
00199 (hasAutoScroll() == other->hasAutoScroll()) &&
00200 #if QT_VERSION > 0x040199
00201 (dragDropMode() == other->dragDropMode()) &&
00202 (dragDropOverwriteMode() == other->dragDropOverwriteMode()) &&
00203 (horizontalScrollMode() == other->horizontalScrollMode ()) &&
00204 (verticalScrollMode() == other->verticalScrollMode()) &&
00205 #endif
00206 (dragEnabled() == other->dragEnabled()) &&
00207 (editTriggers() == other->editTriggers()) &&
00208 (iconSize() == other->iconSize()) &&
00209 (selectionBehavior() == other->selectionBehavior()) &&
00210 (selectionMode() == other->selectionMode()) &&
00211 (showDropIndicator() == other->showDropIndicator()) &&
00212 (tabKeyNavigation() == other->tabKeyNavigation()) &&
00213 (textElideMode() == other->textElideMode()) &&
00214
00215 attributesModel()->compare( other->attributesModel() ) &&
00216
00217 (rootIndex().column() == other->rootIndex().column()) &&
00218 (rootIndex().row() == other->rootIndex().row()) &&
00219 (allowOverlappingDataValueTexts() == other->allowOverlappingDataValueTexts()) &&
00220 (antiAliasing() == other->antiAliasing()) &&
00221 (percentMode() == other->percentMode()) &&
00222 (datasetDimension() == other->datasetDimension());
00223 }
00224
00225
00226 AbstractCoordinatePlane* AbstractDiagram::coordinatePlane() const
00227 {
00228 return d->plane;
00229 }
00230
00231 const QPair<QPointF, QPointF> AbstractDiagram::dataBoundaries () const
00232 {
00233 if( d->databoundariesDirty ){
00234 d->databoundaries = calculateDataBoundaries ();
00235 d->databoundariesDirty = false;
00236 }
00237 return d->databoundaries;
00238 }
00239
00240 void AbstractDiagram::setDataBoundariesDirty() const
00241 {
00242 d->databoundariesDirty = true;
00243 }
00244
00245 void AbstractDiagram::setModel ( QAbstractItemModel * newModel )
00246 {
00247 QAbstractItemView::setModel( newModel );
00248 AttributesModel* amodel = new PrivateAttributesModel( newModel, this );
00249 amodel->initFrom( d->attributesModel );
00250 d->setAttributesModel(amodel);
00251 scheduleDelayedItemsLayout();
00252 d->databoundariesDirty = true;
00253 emit modelsChanged();
00254 }
00255
00261 void AbstractDiagram::setAttributesModel( AttributesModel* amodel )
00262 {
00263 if( amodel->sourceModel() != model() ) {
00264 qWarning("KDChart::AbstractDiagram::setAttributesModel() failed: "
00265 "Trying to set an attributesmodel which works on a different "
00266 "model than the diagram.");
00267 return;
00268 }
00269 if( qobject_cast<PrivateAttributesModel*>(amodel) ) {
00270 qWarning("KDChart::AbstractDiagram::setAttributesModel() failed: "
00271 "Trying to set an attributesmodel that is private to another diagram.");
00272 return;
00273 }
00274 d->setAttributesModel(amodel);
00275 scheduleDelayedItemsLayout();
00276 d->databoundariesDirty = true;
00277 emit modelsChanged();
00278 }
00279
00280 bool AbstractDiagram::usesExternalAttributesModel()const
00281 {
00282 return d->usesExternalAttributesModel();
00283 }
00284
00286 AttributesModel* AbstractDiagram::attributesModel() const
00287 {
00288 return d->attributesModel;
00289 }
00290
00292 void AbstractDiagram::setRootIndex ( const QModelIndex& idx )
00293 {
00294 QAbstractItemView::setRootIndex(idx);
00295 setAttributesModelRootIndex( d->attributesModel->mapFromSource(idx) );
00296 }
00297
00299 void AbstractDiagram::setAttributesModelRootIndex( const QModelIndex& idx )
00300 {
00301 d->attributesModelRootIndex=idx;
00302 d->databoundariesDirty = true;
00303 scheduleDelayedItemsLayout();
00304 }
00305
00308 QModelIndex AbstractDiagram::attributesModelRootIndex() const
00309 {
00310 if ( !d->attributesModelRootIndex.isValid() )
00311 d->attributesModelRootIndex = d->attributesModel->mapFromSource( rootIndex() );
00312 return d->attributesModelRootIndex;
00313 }
00314
00315 QModelIndex AbstractDiagram::columnToIndex( int column ) const
00316 {
00317 if( model() )
00318 return QModelIndex( model()->index( 0, column, rootIndex() ) );
00319 return QModelIndex();
00320 }
00321
00322 void AbstractDiagram::setCoordinatePlane( AbstractCoordinatePlane* parent )
00323 {
00324 d->plane = parent;
00325 }
00326
00327 void AbstractDiagram::doItemsLayout()
00328 {
00329 if ( d->plane ) {
00330 d->plane->layoutDiagrams();
00331 update();
00332 }
00333 QAbstractItemView::doItemsLayout();
00334 }
00335
00336 void AbstractDiagram::dataChanged( const QModelIndex &topLeft,
00337 const QModelIndex &bottomRight )
00338 {
00339
00340 d->databoundariesDirty = true;
00341 scheduleDelayedItemsLayout();
00342 }
00343
00344
00345 void AbstractDiagram::setHidden( const QModelIndex & index, bool hidden )
00346 {
00347 d->attributesModel->setData(
00348 d->attributesModel->mapFromSource( index ),
00349 qVariantFromValue( hidden ),
00350 DataHiddenRole );
00351 emit dataHidden();
00352 }
00353
00354 void AbstractDiagram::setHidden( int column, bool hidden )
00355 {
00356 d->attributesModel->setHeaderData(
00357 column, Qt::Vertical,
00358 qVariantFromValue( hidden ),
00359 DataHiddenRole );
00360 emit dataHidden();
00361 }
00362
00363 void AbstractDiagram::setHidden( bool hidden )
00364 {
00365 d->attributesModel->setModelData(
00366 qVariantFromValue( hidden ),
00367 DataHiddenRole );
00368 emit dataHidden();
00369 }
00370
00371 bool AbstractDiagram::isHidden() const
00372 {
00373 return qVariantValue<bool>(
00374 attributesModel()->modelData( DataHiddenRole ) );
00375 }
00376
00377 bool AbstractDiagram::isHidden( int column ) const
00378 {
00379 return qVariantValue<bool>(
00380 attributesModel()->data(
00381 attributesModel()->mapFromSource(columnToIndex( column )),
00382 DataHiddenRole ) );
00383 }
00384 bool AbstractDiagram::isHidden( const QModelIndex & index ) const
00385 {
00386 return qVariantValue<bool>(
00387 attributesModel()->data(
00388 attributesModel()->mapFromSource(index),
00389 DataHiddenRole ) );
00390 }
00391
00392
00393 void AbstractDiagram::setDataValueAttributes( const QModelIndex & index,
00394 const DataValueAttributes & a )
00395 {
00396 d->attributesModel->setData(
00397 d->attributesModel->mapFromSource( index ),
00398 qVariantFromValue( a ),
00399 DataValueLabelAttributesRole );
00400 emit propertiesChanged();
00401 }
00402
00403
00404 void AbstractDiagram::setDataValueAttributes( int column, const DataValueAttributes & a )
00405 {
00406 d->attributesModel->setHeaderData(
00407 column, Qt::Vertical,
00408 qVariantFromValue( a ), DataValueLabelAttributesRole );
00409 emit propertiesChanged();
00410 }
00411
00412 DataValueAttributes AbstractDiagram::dataValueAttributes() const
00413 {
00414 return qVariantValue<DataValueAttributes>(
00415 attributesModel()->modelData( KDChart::DataValueLabelAttributesRole ) );
00416 }
00417
00418 DataValueAttributes AbstractDiagram::dataValueAttributes( int column ) const
00419 {
00420 return qVariantValue<DataValueAttributes>(
00421 attributesModel()->data( attributesModel()->mapFromSource(columnToIndex( column )),
00422 KDChart::DataValueLabelAttributesRole ) );
00423 }
00424
00425 DataValueAttributes AbstractDiagram::dataValueAttributes( const QModelIndex & index ) const
00426 {
00427 return qVariantValue<DataValueAttributes>(
00428 attributesModel()->data( attributesModel()->mapFromSource(index),
00429 KDChart::DataValueLabelAttributesRole ) );
00430 }
00431
00432 void AbstractDiagram::setDataValueAttributes( const DataValueAttributes & a )
00433 {
00434 d->attributesModel->setModelData( qVariantFromValue( a ), DataValueLabelAttributesRole );
00435 emit propertiesChanged();
00436 }
00437
00438 void AbstractDiagram::setAllowOverlappingDataValueTexts( bool allow )
00439 {
00440 d->allowOverlappingDataValueTexts = allow;
00441 emit propertiesChanged();
00442 }
00443
00444 bool AbstractDiagram::allowOverlappingDataValueTexts() const
00445 {
00446 return d->allowOverlappingDataValueTexts;
00447 }
00448
00449 void AbstractDiagram::setAntiAliasing( bool enabled )
00450 {
00451 d->antiAliasing = enabled;
00452 emit propertiesChanged();
00453 }
00454
00455 bool AbstractDiagram::antiAliasing() const
00456 {
00457 return d->antiAliasing;
00458 }
00459
00460 void AbstractDiagram::setPercentMode ( bool percent )
00461 {
00462 d->percent = percent;
00463 emit propertiesChanged();
00464 }
00465
00466 bool AbstractDiagram::percentMode() const
00467 {
00468 return d->percent;
00469 }
00470
00471
00472 void AbstractDiagram::paintDataValueText( QPainter* painter,
00473 const QModelIndex& index,
00474 const QPointF& pos,
00475 double value )
00476 {
00477
00478 const DataValueAttributes a( dataValueAttributes(index) );
00479 if ( !a.isVisible() ) return;
00480
00481
00482 int decimalDigits = a.decimalDigits();
00483 int decimalPos = QString::number( value ).indexOf( QLatin1Char( '.' ) );
00484 QString roundedValue;
00485 if ( a.dataLabel().isNull() ) {
00486 if ( decimalPos > 0 && value != 0 )
00487 roundedValue = roundValues ( value, decimalPos, decimalDigits );
00488 else
00489 roundedValue = QString::number( value );
00490 } else
00491 roundedValue = a.dataLabel();
00492
00493 if ( !a.prefix().isNull() )
00494 roundedValue.prepend( a.prefix() );
00495
00496 if ( !a.suffix().isNull() )
00497 roundedValue.append( a.suffix() );
00498
00499 const TextAttributes ta( a.textAttributes() );
00500
00501 if ( ta.isVisible() ) {
00502
00503 QPointF pt( pos );
00504
00505
00506
00507
00508
00509
00510
00511
00512 const RelativePosition relPos( a.position( value >= 0.0 ) );
00513 const Qt::Alignment alignBottomLeft = Qt::AlignBottom | Qt::AlignLeft;
00514 const QFont calculatedFont( ta.calculatedFont( d->plane, KDChartEnums::MeasureOrientationMinimum ) );
00515
00516 if( (relPos.alignment() & alignBottomLeft) != alignBottomLeft ){
00517 const QRectF boundRect(
00518 d->cachedFontMetrics( calculatedFont, this )->boundingRect( roundedValue ) );
00519 if( relPos.alignment() & Qt::AlignRight )
00520 pt.rx() -= boundRect.width();
00521 else if( relPos.alignment() & Qt::AlignHCenter )
00522 pt.rx() -= 0.5 * boundRect.width();
00523
00524 if( relPos.alignment() & Qt::AlignTop )
00525 pt.ry() += boundRect.height();
00526 else if( relPos.alignment() & Qt::AlignVCenter )
00527 pt.ry() += 0.5 * boundRect.height();
00528 }
00529
00530
00531
00532 if ( a.showRepetitiveDataLabels() ||
00533 pos.x() <= d->lastX ||
00534 d->lastRoundedValue != roundedValue ) {
00535 d->lastRoundedValue = roundedValue;
00536 d->lastX = pos.x();
00537
00538 PainterSaver painterSaver( painter );
00539 painter->setPen( ta.pen() );
00540 painter->setFont( calculatedFont );
00541 painter->translate( pt );
00542 painter->rotate( ta.rotation() );
00543 painter->drawText( QPointF(0, 0), roundedValue );
00544 }
00545 }
00546 }
00547
00548
00549 QString AbstractDiagram::roundValues( double value,
00550 const int decimalPos,
00551 const int decimalDigits ) const {
00552
00553 QString digits( QString::number( value ).mid( decimalPos+1 ) );
00554 QString num( QString::number( value ) );
00555 num.truncate( decimalPos );
00556 int count = 0;
00557 for ( int i = digits.length(); i >= decimalDigits ; --i ) {
00558 count += 1;
00559 int lastval = QString( digits.data() [i] ).toInt();
00560 int val = QString( digits.data() [i-1] ) .toInt();
00561 if ( lastval >= 5 ) {
00562 val += 1;
00563 digits.replace( digits.length() - count,1 , QString::number( val ) );
00564 }
00565 }
00566
00567 digits.truncate( decimalDigits );
00568 num.append( QLatin1Char( '.' ) + digits );
00569
00570 return num;
00571
00572 }
00573
00574 void AbstractDiagram::paintDataValueTexts( QPainter* painter )
00575 {
00576 if ( !checkInvariants() ) return;
00577 const int rowCount = model()->rowCount(rootIndex());
00578 const int columnCount = model()->columnCount(rootIndex());
00579 for ( int i=datasetDimension()-1; i<columnCount; i += datasetDimension() ) {
00580 for ( int j=0; j< rowCount; ++j ) {
00581 const QModelIndex index = model()->index( j, i, rootIndex() );
00582 double value = model()->data( index ).toDouble();
00583 const QPointF pos = coordinatePlane()->translate( QPointF( j, value ) );
00584 paintDataValueText( painter, index, pos, value );
00585 }
00586 }
00587 }
00588
00589
00590 void AbstractDiagram::paintMarker( QPainter* painter,
00591 const QModelIndex& index,
00592 const QPointF& pos )
00593 {
00594
00595 if ( !checkInvariants() ) return;
00596 DataValueAttributes a = dataValueAttributes(index);
00597 if ( !a.isVisible() ) return;
00598 const MarkerAttributes &ma = a.markerAttributes();
00599 if ( !ma.isVisible() ) return;
00600
00601 PainterSaver painterSaver( painter );
00602 QSizeF maSize( ma.markerSize() );
00603 QBrush indexBrush( brush( index ) );
00604 QPen indexPen( ma.pen() );
00605 if ( ma.markerColor().isValid() )
00606 indexBrush.setColor( ma.markerColor() );
00607
00608 paintMarker( painter, ma, indexBrush, indexPen, pos, maSize );
00609 }
00610
00611
00612 void AbstractDiagram::paintMarker( QPainter* painter,
00613 const MarkerAttributes& markerAttributes,
00614 const QBrush& brush,
00615 const QPen& pen,
00616 const QPointF& pos,
00617 const QSizeF& maSize )
00618 {
00619
00620 const QPen oldPen( painter->pen() );
00621
00622
00623 const bool isFourPixels = (markerAttributes.markerStyle() == MarkerAttributes::Marker4Pixels);
00624 if( isFourPixels || (markerAttributes.markerStyle() == MarkerAttributes::Marker1Pixel) ){
00625
00626 painter->setPen( QPen( brush.color().light() ) );
00627 if( isFourPixels ){
00628 const qreal x = pos.x();
00629 const qreal y = pos.y();
00630 painter->drawLine( QPointF(x-1.0,y-1.0),
00631 QPointF(x+1.0,y-1.0) );
00632 painter->drawLine( QPointF(x-1.0,y),
00633 QPointF(x+1.0,y) );
00634 painter->drawLine( QPointF(x-1.0,y+1.0),
00635 QPointF(x+1.0,y+1.0) );
00636 }
00637 painter->drawPoint( pos );
00638 }else{
00639 PainterSaver painterSaver( painter );
00640
00641 QPen painterPen( pen );
00642 painterPen.setStyle( Qt::SolidLine );
00643 painter->setPen( painterPen );
00644 painter->setBrush( brush );
00645 painter->setRenderHint ( QPainter::Antialiasing );
00646 painter->translate( pos );
00647 switch ( markerAttributes.markerStyle() ) {
00648 case MarkerAttributes::MarkerCircle:
00649 painter->drawEllipse( QRectF( 0 - maSize.height()/2, 0 - maSize.width()/2,
00650 maSize.height(), maSize.width()) );
00651 break;
00652 case MarkerAttributes::MarkerSquare:
00653 {
00654 QRectF rect( 0 - maSize.width()/2, 0 - maSize.height()/2,
00655 maSize.width(), maSize.height() );
00656 painter->drawRect( rect );
00657 painter->fillRect( rect, brush.color() );
00658 break;
00659 }
00660 case MarkerAttributes::MarkerDiamond:
00661 {
00662 QVector <QPointF > diamondPoints;
00663 QPointF top, left, bottom, right;
00664 top = QPointF( 0, 0 - maSize.height()/2 );
00665 left = QPointF( 0 - maSize.width()/2, 0 );
00666 bottom = QPointF( 0, maSize.height()/2 );
00667 right = QPointF( maSize.width()/2, 0 );
00668 diamondPoints << top << left << bottom << right;
00669 painter->drawPolygon( diamondPoints );
00670 break;
00671 }
00672
00673 case MarkerAttributes::Marker1Pixel:
00674 case MarkerAttributes::Marker4Pixels:
00675 break;
00676 case MarkerAttributes::MarkerRing:
00677 {
00678 painter->setPen( QPen( brush.color() ) );
00679 painter->setBrush( Qt::NoBrush );
00680 painter->drawEllipse( QRectF( 0 - maSize.height()/2, 0 - maSize.width()/2,
00681 maSize.height(), maSize.width()) );
00682 break;
00683 }
00684 case MarkerAttributes::MarkerCross:
00685 {
00686 QRectF rect( maSize.width()*-0.5, maSize.height()*-0.2,
00687 maSize.width(), maSize.height()*0.4 );
00688 painter->drawRect( rect );
00689 rect.setTopLeft(QPointF( maSize.width()*-0.2, maSize.height()*-0.5 ));
00690 rect.setSize(QSizeF( maSize.width()*0.4, maSize.height() ));
00691 painter->drawRect( rect );
00692 break;
00693 }
00694 case MarkerAttributes::MarkerFastCross:
00695 {
00696 QPointF left, right, top, bottom;
00697 left = QPointF( -maSize.width()/2, 0 );
00698 right = QPointF( maSize.width()/2, 0 );
00699 top = QPointF( 0, -maSize.height()/2 );
00700 bottom= QPointF( 0, maSize.height()/2 );
00701 painter->setPen( QPen( brush.color() ) );
00702 painter->drawLine( left, right );
00703 painter->drawLine( top, bottom );
00704 break;
00705 }
00706 default:
00707 Q_ASSERT_X ( false, "paintMarkers()",
00708 "Type item does not match a defined Marker Type." );
00709 }
00710 }
00711 painter->setPen( oldPen );
00712 }
00713
00714 void AbstractDiagram::paintMarkers( QPainter* painter )
00715 {
00716 if ( !checkInvariants() ) return;
00717 const int rowCount = model()->rowCount(rootIndex());
00718 const int columnCount = model()->columnCount(rootIndex());
00719 for ( int i=datasetDimension()-1; i<columnCount; i += datasetDimension() ) {
00720 for ( int j=0; j< rowCount; ++j ) {
00721 const QModelIndex index = model()->index( j, i, rootIndex() );
00722 double value = model()->data( index ).toDouble();
00723 const QPointF pos = coordinatePlane()->translate( QPointF( j, value ) );
00724 paintMarker( painter, index, pos );
00725 }
00726 }
00727 }
00728
00729
00730 void AbstractDiagram::setPen( const QModelIndex& index, const QPen& pen )
00731 {
00732 attributesModel()->setData(
00733 attributesModel()->mapFromSource( index ),
00734 qVariantFromValue( pen ), DatasetPenRole );
00735 emit propertiesChanged();
00736 }
00737
00738 void AbstractDiagram::setPen( const QPen& pen )
00739 {
00740 attributesModel()->setModelData(
00741 qVariantFromValue( pen ), DatasetPenRole );
00742 emit propertiesChanged();
00743 }
00744
00745 void AbstractDiagram::setPen( int column,const QPen& pen )
00746 {
00747 attributesModel()->setHeaderData(
00748 column, Qt::Vertical,
00749 qVariantFromValue( pen ),
00750 DatasetPenRole );
00751 emit propertiesChanged();
00752 }
00753
00754 QPen AbstractDiagram::pen() const
00755 {
00756 return qVariantValue<QPen>(
00757 attributesModel()->data( DatasetPenRole ) );
00758 }
00759
00760 QPen AbstractDiagram::pen( int dataset ) const
00761 {
00762 return qVariantValue<QPen>(
00763 attributesModel()->data(
00764 attributesModel()->mapFromSource( columnToIndex( dataset ) ),
00765 DatasetPenRole ) );
00766 }
00767
00768 QPen AbstractDiagram::pen( const QModelIndex& index ) const
00769 {
00770 return qVariantValue<QPen>(
00771 attributesModel()->data(
00772 attributesModel()->mapFromSource( index ),
00773 DatasetPenRole ) );
00774 }
00775
00776 void AbstractDiagram::setBrush( const QModelIndex& index, const QBrush& brush )
00777 {
00778 attributesModel()->setData(
00779 attributesModel()->mapFromSource( index ),
00780 qVariantFromValue( brush ), DatasetBrushRole );
00781 emit propertiesChanged();
00782 }
00783
00784 void AbstractDiagram::setBrush( const QBrush& brush )
00785 {
00786 attributesModel()->setModelData(
00787 qVariantFromValue( brush ), DatasetBrushRole );
00788 emit propertiesChanged();
00789 }
00790
00791 void AbstractDiagram::setBrush( int column, const QBrush& brush )
00792 {
00793 attributesModel()->setHeaderData(
00794 column, Qt::Vertical,
00795 qVariantFromValue( brush ),
00796 DatasetBrushRole );
00797 emit propertiesChanged();
00798 }
00799
00800 QBrush AbstractDiagram::brush() const
00801 {
00802 return qVariantValue<QBrush>(
00803 attributesModel()->data( DatasetBrushRole ) );
00804 }
00805
00806 QBrush AbstractDiagram::brush( int dataset ) const
00807 {
00808 return qVariantValue<QBrush>(
00809 attributesModel()->data(
00810 attributesModel()->mapFromSource( columnToIndex( dataset ) ),
00811 DatasetBrushRole ) );
00812 }
00813
00814 QBrush AbstractDiagram::brush( const QModelIndex& index ) const
00815 {
00816 return qVariantValue<QBrush>(
00817 attributesModel()->data(
00818 attributesModel()->mapFromSource( index ),
00819 DatasetBrushRole ) );
00820 }
00821
00822
00823 QRect AbstractDiagram::visualRect(const QModelIndex &) const
00824 {
00825 return QRect();
00826 }
00827
00828 void AbstractDiagram::scrollTo(const QModelIndex &, ScrollHint )
00829 {}
00830
00831 QModelIndex AbstractDiagram::indexAt(const QPoint &) const
00832 { return QModelIndex(); }
00833
00834 QModelIndex AbstractDiagram::moveCursor(CursorAction, Qt::KeyboardModifiers )
00835 { return QModelIndex(); }
00836
00837 int AbstractDiagram::horizontalOffset() const
00838 { return 0; }
00839
00840 int AbstractDiagram::verticalOffset() const
00841 { return 0; }
00842
00843 bool AbstractDiagram::isIndexHidden(const QModelIndex &) const
00844 { return true; }
00845
00846 void AbstractDiagram::setSelection(const QRect &, QItemSelectionModel::SelectionFlags)
00847 {}
00848
00849 QRegion AbstractDiagram::visualRegionForSelection(const QItemSelection &) const
00850 { return QRegion(); }
00851
00852
00853 void KDChart::AbstractDiagram::useDefaultColors( )
00854 {
00855 d->attributesModel->setPaletteType( AttributesModel::PaletteTypeDefault );
00856 }
00857
00858 void KDChart::AbstractDiagram::useSubduedColors( )
00859 {
00860 d->attributesModel->setPaletteType( AttributesModel::PaletteTypeSubdued );
00861 }
00862
00863 void KDChart::AbstractDiagram::useRainbowColors( )
00864 {
00865 d->attributesModel->setPaletteType( AttributesModel::PaletteTypeRainbow );
00866 }
00867
00868 QStringList AbstractDiagram::itemRowLabels() const
00869 {
00870 QStringList ret;
00871
00872 const int rowCount = attributesModel()->rowCount(attributesModelRootIndex());
00873 for( int i = 0; i < rowCount; ++i ){
00874
00875 ret << attributesModel()->headerData( i, Qt::Vertical, Qt::DisplayRole ).toString();
00876 }
00877 return ret;
00878 }
00879
00880 QStringList AbstractDiagram::datasetLabels() const
00881 {
00882 QStringList ret;
00883
00884 const int columnCount = attributesModel()->columnCount(attributesModelRootIndex());
00885 for( int i = datasetDimension()-1; i < columnCount; i += datasetDimension() ){
00886
00887 ret << attributesModel()->headerData( i, Qt::Horizontal, Qt::DisplayRole ).toString();
00888 }
00889 return ret;
00890 }
00891
00892 QList<QBrush> AbstractDiagram::datasetBrushes() const
00893 {
00894 QList<QBrush> ret;
00895 const int columnCount = attributesModel()->columnCount(attributesModelRootIndex());
00896 for( int i = datasetDimension()-1; i < columnCount; i += datasetDimension() ) {
00897 QBrush brush = qVariantValue<QBrush>( attributesModel()->headerData( i, Qt::Vertical, DatasetBrushRole ) );
00898 ret << brush;
00899 }
00900
00901 return ret;
00902 }
00903
00904 QList<QPen> AbstractDiagram::datasetPens() const
00905 {
00906 QList<QPen> ret;
00907 const int columnCount = attributesModel()->columnCount(attributesModelRootIndex());
00908 for( int i = datasetDimension()-1; i < columnCount; i += datasetDimension() ) {
00909 QPen pen = qVariantValue<QPen>( attributesModel()->headerData( i, Qt::Vertical, DatasetPenRole ) );
00910 ret << pen;
00911 }
00912 return ret;
00913 }
00914
00915 QList<MarkerAttributes> AbstractDiagram::datasetMarkers() const
00916 {
00917 QList<MarkerAttributes> ret;
00918 const int columnCount = attributesModel()->columnCount(attributesModelRootIndex());
00919 for( int i = datasetDimension()-1; i < columnCount; i += datasetDimension() ) {
00920 DataValueAttributes a =
00921 qVariantValue<DataValueAttributes>( attributesModel()->headerData( i, Qt::Vertical, DataValueLabelAttributesRole ) );
00922 const MarkerAttributes &ma = a.markerAttributes();
00923 ret << ma;
00924 }
00925 return ret;
00926 }
00927
00928 bool AbstractDiagram::checkInvariants( bool justReturnTheStatus ) const
00929 {
00930 if( ! justReturnTheStatus ){
00931 Q_ASSERT_X ( model(), "AbstractDiagram::checkInvariants()",
00932 "There is no usable model set, for the diagram." );
00933
00934 Q_ASSERT_X ( coordinatePlane(), "AbstractDiagram::checkInvariants()",
00935 "There is no usable coordinate plane set, for the diagram." );
00936 }
00937 return model() && coordinatePlane();
00938 }
00939
00940 int AbstractDiagram::datasetDimension( ) const
00941 {
00942 return d->datasetDimension;
00943 }
00944
00945 void AbstractDiagram::setDatasetDimension( int dimension )
00946 {
00947 if ( d->datasetDimension == dimension ) return;
00948 d->datasetDimension = dimension;
00949 d->databoundariesDirty = true;
00950 emit layoutChanged( this );
00951 }
00952
00953 double AbstractDiagram::valueForCell( int row, int column ) const
00954 {
00955 return d->attributesModel->data(
00956 d->attributesModel->index( row, column, attributesModelRootIndex() ) ).toDouble();
00957 }
00958
00959 void AbstractDiagram::update() const
00960 {
00961
00962 if( d->plane )
00963 d->plane->update();
00964 }
00965
00966
00967 #include "KDChartAbstractDiagram.moc"