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 "KDChartBarDiagram.h"
00027 #include "KDChartBarDiagram_p.h"
00028
00029 #include "KDChartThreeDBarAttributes.h"
00030 #include "KDChartPosition.h"
00031 #include "KDChartAttributesModel.h"
00032 #include "KDChartAbstractGrid.h"
00033
00034 #include <QPainter>
00035 #include <QDebug>
00036
00037 #include <KDABLibFakes>
00038
00039 #include "KDChartNormalBarDiagram_p.h"
00040 #include "KDChartStackedBarDiagram_p.h"
00041 #include "KDChartPercentBarDiagram_p.h"
00042 #include "KDChartNormalLyingBarDiagram_p.h"
00043 #include "KDChartStackedLyingBarDiagram_p.h"
00044 #include "KDChartPercentLyingBarDiagram_p.h"
00045
00046
00047 using namespace KDChart;
00048
00049 BarDiagram::Private::Private()
00050 : orientation( Qt::Vertical )
00051 {
00052 }
00053
00054 BarDiagram::Private::~Private() {}
00055
00056 #define d d_func()
00057
00058
00059 BarDiagram::BarDiagram( QWidget* parent, CartesianCoordinatePlane* plane ) :
00060 AbstractCartesianDiagram( new Private(), parent, plane )
00061 {
00062 init();
00063 }
00064
00065 void BarDiagram::init()
00066 {
00067 d->diagram = this;
00068 d->normalDiagram = new NormalBarDiagram( this );
00069 d->stackedDiagram = new StackedBarDiagram( this );
00070 d->percentDiagram = new PercentBarDiagram( this );
00071 d->normalLyingDiagram = new NormalLyingBarDiagram( this );
00072 d->stackedLyingDiagram = new StackedLyingBarDiagram( this );
00073 d->percentLyingDiagram = new PercentLyingBarDiagram( this );
00074 d->implementor = d->normalDiagram;
00075 d->compressor.setModel( attributesModel() );
00076 }
00077
00078 BarDiagram::~BarDiagram()
00079 {
00080 }
00081
00085 BarDiagram * BarDiagram::clone() const
00086 {
00087
00088 BarDiagram* newDiagram = new BarDiagram( new Private( *d ) );
00089 newDiagram->setType( type() );
00090 return newDiagram;
00091 }
00092
00093 bool BarDiagram::compare( const BarDiagram* other )const
00094 {
00095 if( other == this ) return true;
00096 if( ! other ){
00097 return false;
00098 }
00099
00100 return
00101 ( static_cast<const AbstractCartesianDiagram*>(this)->compare( other ) ) &&
00102
00103 (type() == other->type());
00104 }
00105
00110 void BarDiagram::setType( const BarType type )
00111 {
00112
00113 if ( d->implementor->type() == type ) return;
00114
00115 if ( d->orientation == Qt::Vertical ) {
00116 switch( type ) {
00117 case Normal:
00118 d->implementor = d->normalDiagram;
00119 break;
00120 case Stacked:
00121 d->implementor = d->stackedDiagram;
00122 break;
00123 case Percent:
00124 d->implementor = d->percentDiagram;
00125 break;
00126 default:
00127 Q_ASSERT_X( false, "BarDiagram::setType", "unknown diagram subtype" );
00128 }
00129 } else {
00130 switch( type ) {
00131 case Normal:
00132 d->implementor = d->normalLyingDiagram;
00133 break;
00134 case Stacked:
00135 d->implementor = d->stackedLyingDiagram;
00136 break;
00137 case Percent:
00138 d->implementor = d->percentLyingDiagram;
00139 break;
00140 default:
00141 Q_ASSERT_X( false, "BarDiagram::setType", "unknown diagram subtype" );
00142 }
00143 }
00144
00145 Q_ASSERT( d->implementor->type() == type );
00146
00147
00148
00149 setPercentMode( type == BarDiagram::Percent );
00150 setDataBoundariesDirty();
00151 emit layoutChanged( this );
00152 emit propertiesChanged();
00153 }
00154
00158 BarDiagram::BarType BarDiagram::type() const
00159 {
00160 return d->implementor->type();
00161 }
00162
00166 void BarDiagram::setOrientation( Qt::Orientation orientation )
00167 {
00168 if ( d->orientation == orientation )
00169 return;
00170 d->orientation = orientation;
00171
00172 if ( d->orientation == Qt::Vertical ) {
00173 switch( type() ) {
00174 case Normal:
00175 d->implementor = d->normalDiagram;
00176 break;
00177 case Stacked:
00178 d->implementor = d->stackedDiagram;
00179 break;
00180 case Percent:
00181 d->implementor = d->percentDiagram;
00182 break;
00183 default:
00184 Q_ASSERT_X( false, "BarDiagram::setType", "unknown diagram subtype" );
00185 }
00186 } else {
00187 switch( type() ) {
00188 case Normal:
00189 d->implementor = d->normalLyingDiagram;
00190 break;
00191 case Stacked:
00192 d->implementor = d->stackedLyingDiagram;
00193 break;
00194 case Percent:
00195 d->implementor = d->percentLyingDiagram;
00196 break;
00197 default:
00198 Q_ASSERT_X( false, "BarDiagram::setType", "unknown diagram subtype" );
00199 }
00200 }
00201
00202
00203 setPercentMode( type() == BarDiagram::Percent );
00204 setDataBoundariesDirty();
00205 emit layoutChanged( this );
00206 emit propertiesChanged();
00207 }
00208
00212 Qt::Orientation BarDiagram::orientation() const
00213 {
00214 return d->orientation;
00215 }
00216
00220 void BarDiagram::setBarAttributes( const BarAttributes& ba )
00221 {
00222 d->attributesModel->setModelData( qVariantFromValue( ba ), BarAttributesRole );
00223 emit propertiesChanged();
00224 }
00225
00229 void BarDiagram::setBarAttributes( int column, const BarAttributes& ba )
00230 {
00231 d->attributesModel->setHeaderData(
00232 column, Qt::Vertical,
00233 qVariantFromValue( ba ),
00234 BarAttributesRole );
00235 emit propertiesChanged();
00236 }
00237
00241 void BarDiagram::setBarAttributes( const QModelIndex& index, const BarAttributes& ba )
00242 {
00243 attributesModel()->setData(
00244 d->attributesModel->mapFromSource( index ),
00245 qVariantFromValue( ba ),
00246 BarAttributesRole );
00247 emit propertiesChanged();
00248 }
00249
00253 BarAttributes BarDiagram::barAttributes() const
00254 {
00255 return qVariantValue<BarAttributes>(
00256 d->attributesModel->data( KDChart::BarAttributesRole ) );
00257 }
00258
00262 BarAttributes BarDiagram::barAttributes( int column ) const
00263 {
00264 const QVariant attrs(
00265 d->attributesModel->headerData( column, Qt::Vertical,
00266 KDChart::BarAttributesRole ) );
00267 if( attrs.isValid() )
00268 return qVariantValue< BarAttributes >( attrs );
00269 return barAttributes();
00270 }
00271
00275 BarAttributes BarDiagram::barAttributes( const QModelIndex& index ) const
00276 {
00277 return qVariantValue<BarAttributes>(
00278 d->attributesModel->data(
00279 d->attributesModel->mapFromSource( index ),
00280 KDChart::BarAttributesRole ) );
00281 }
00282
00286 void BarDiagram::setThreeDBarAttributes( const ThreeDBarAttributes& threeDAttrs )
00287 {
00288 setDataBoundariesDirty();
00289 d->attributesModel->setModelData( qVariantFromValue( threeDAttrs ), ThreeDBarAttributesRole );
00290
00291 emit propertiesChanged();
00292 }
00293
00297 void BarDiagram::setThreeDBarAttributes( int column, const ThreeDBarAttributes& threeDAttrs )
00298 {
00299 setDataBoundariesDirty();
00300 d->attributesModel->setHeaderData(
00301 column, Qt::Vertical,
00302 qVariantFromValue( threeDAttrs ),
00303 ThreeDBarAttributesRole );
00304
00305 emit propertiesChanged();
00306
00307 }
00308
00312 void BarDiagram::setThreeDBarAttributes( const QModelIndex& index, const ThreeDBarAttributes& threeDAttrs )
00313 {
00314 setDataBoundariesDirty();
00315 d->attributesModel->setData(
00316 d->attributesModel->mapFromSource(index),
00317 qVariantFromValue( threeDAttrs ),
00318 ThreeDBarAttributesRole );
00319
00320 emit propertiesChanged();
00321 }
00322
00326 ThreeDBarAttributes BarDiagram::threeDBarAttributes() const
00327 {
00328 return qVariantValue<ThreeDBarAttributes>(
00329 d->attributesModel->data( KDChart::ThreeDBarAttributesRole ) );
00330 }
00331
00335 ThreeDBarAttributes BarDiagram::threeDBarAttributes( int column ) const
00336 {
00337 const QVariant attrs(
00338 d->attributesModel->headerData( column, Qt::Vertical,
00339 KDChart::ThreeDBarAttributesRole ) );
00340 if( attrs.isValid() )
00341 return qVariantValue< ThreeDBarAttributes >( attrs );
00342 return threeDBarAttributes();
00343 }
00344
00348 ThreeDBarAttributes BarDiagram::threeDBarAttributes( const QModelIndex& index ) const
00349 {
00350 return qVariantValue<ThreeDBarAttributes>(
00351 d->attributesModel->data(
00352 d->attributesModel->mapFromSource(index),
00353 KDChart::ThreeDBarAttributesRole ) );
00354 }
00355
00356 double BarDiagram::threeDItemDepth( const QModelIndex& index ) const
00357 {
00358 return threeDBarAttributes( index ).validDepth();
00359 }
00360
00361 double BarDiagram::threeDItemDepth( int column ) const
00362 {
00363 return qVariantValue<ThreeDBarAttributes>(
00364 d->attributesModel->headerData (
00365 column,
00366 Qt::Vertical,
00367 KDChart::ThreeDBarAttributesRole ) ).validDepth();
00368 }
00369
00370 void BarDiagram::resizeEvent ( QResizeEvent*)
00371 {
00372
00373 }
00374
00375 const QPair<QPointF, QPointF> BarDiagram::calculateDataBoundaries() const
00376 {
00377 if ( !checkInvariants(true) ) return QPair<QPointF, QPointF>( QPointF( 0, 0 ), QPointF( 0, 0 ) );
00378
00379
00380
00381
00382
00383 return d->implementor->calculateDataBoundaries();
00384 }
00385
00386 void BarDiagram::paintEvent ( QPaintEvent*)
00387 {
00388 QPainter painter ( viewport() );
00389 PaintContext ctx;
00390 ctx.setPainter ( &painter );
00391 ctx.setRectangle( QRectF ( 0, 0, width(), height() ) );
00392 paint ( &ctx );
00393 }
00394
00395 void BarDiagram::paint( PaintContext* ctx )
00396 {
00397 if ( !checkInvariants( true ) ) return;
00398 if ( !AbstractGrid::isBoundariesValid(dataBoundaries()) ) return;
00399 const PainterSaver p( ctx->painter() );
00400 if( model()->rowCount( rootIndex() ) == 0 || model()->columnCount( rootIndex() ) == 0 )
00401 return;
00402
00403 AbstractCoordinatePlane* const plane = ctx->coordinatePlane();
00404 ctx->setCoordinatePlane( plane->sharedAxisMasterPlane( ctx->painter() ) );
00405
00406
00407
00408 ctx->painter()->setClipping( true );
00409 ctx->painter()->setClipRect( ctx->rectangle() );
00410
00411
00412 d->implementor->paint( ctx );
00413
00414 ctx->setCoordinatePlane( plane );
00415 }
00416
00417 void BarDiagram::resize( const QSizeF& size )
00418 {
00419 d->compressor.setResolution( static_cast< int >( size.width() * coordinatePlane()->zoomFactorX() ),
00420 static_cast< int >( size.height() * coordinatePlane()->zoomFactorY() ) );
00421 setDataBoundariesDirty();
00422 }
00423
00424 #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
00425 const
00426 #endif
00427 int BarDiagram::numberOfAbscissaSegments () const
00428 {
00429 return d->attributesModel->rowCount(attributesModelRootIndex());
00430 }
00431
00432 #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
00433 const
00434 #endif
00435 int BarDiagram::numberOfOrdinateSegments () const
00436 {
00437 return d->attributesModel->columnCount(attributesModelRootIndex());
00438 }
00439
00440