KDChartBarDiagram.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002  ** Copyright (C) 2007 Klaralvdalens Datakonsult AB.  All rights reserved.
00003  **
00004  ** This file is part of the KD Chart library.
00005  **
00006  ** This file may be distributed and/or modified under the terms of the
00007  ** GNU General Public License version 2 as published by the Free Software
00008  ** Foundation and appearing in the file LICENSE.GPL included in the
00009  ** packaging of this file.
00010  **
00011  ** Licensees holding valid commercial KD Chart licenses may use this file in
00012  ** accordance with the KD Chart Commercial License Agreement provided with
00013  ** the Software.
00014  **
00015  ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00016  ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00017  **
00018  ** See http://www.kdab.net/kdchart for
00019  **   information about KDChart Commercial License Agreements.
00020  **
00021  ** Contact info@kdab.net if any conditions of this
00022  ** licensing are not clear to you.
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  // compare the base class
00101             ( static_cast<const AbstractCartesianDiagram*>(this)->compare( other ) ) &&
00102             // compare own properties
00103             (type() == other->type());
00104 }
00105 
00110 void BarDiagram::setType( const BarType type )
00111 {
00112     //if ( type == d->barType ) return;
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    //d->barType = type;
00148     // AbstractAxis settings - see AbstractDiagram and CartesianAxis
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     // AbstractAxis settings - see AbstractDiagram and CartesianAxis
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     //emit layoutChanged( this );
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     //emit layoutChanged( this );
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     //emit layoutChanged( this );
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     // note: calculateDataBoundaries() is ignoring the hidden flags.
00380     // That's not a bug but a feature: Hiding data does not mean removing them.
00381     // For totally removing data from KD Chart's view people can use e.g. a proxy model
00382     // calculate boundaries for different line types Normal - Stacked - Percent - Default Normal
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; // nothing to paint for us
00402 
00403     AbstractCoordinatePlane* const plane = ctx->coordinatePlane();
00404     ctx->setCoordinatePlane( plane->sharedAxisMasterPlane( ctx->painter() ) );
00405 
00406     // Only paint elements that are in the paint context's rectangle
00407     // (in this case boundaries of the diagram, see paintEvent())
00408     ctx->painter()->setClipping( true );
00409     ctx->painter()->setClipRect( ctx->rectangle() );
00410 
00411     // paint different bar types Normal - Stacked - Percent - Default Normal
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 //#undef d

Generated on Thu Mar 4 23:19:10 2010 for KD Chart 2 by  doxygen 1.5.4