KD Chart 2  [rev.2.5]
KDChartBarDiagram.cpp
Go to the documentation of this file.
00001 /****************************************************************************
00002 ** Copyright (C) 2001-2012 Klaralvdalens Datakonsult AB.  All rights reserved.
00003 **
00004 ** This file is part of the KD Chart library.
00005 **
00006 ** Licensees holding valid commercial KD Chart licenses may use this file in
00007 ** accordance with the KD Chart Commercial License Agreement provided with
00008 ** the Software.
00009 **
00010 **
00011 ** This file may be distributed and/or modified under the terms of the
00012 ** GNU General Public License version 2 and version 3 as published by the
00013 ** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
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 ** Contact info@kdab.com if any conditions of this licensing are not
00019 ** clear to you.
00020 **
00021 **********************************************************************/
00022 
00023 #include "KDChartBarDiagram.h"
00024 #include "KDChartBarDiagram_p.h"
00025 
00026 #include "KDChartThreeDBarAttributes.h"
00027 #include "KDChartPosition.h"
00028 #include "KDChartAttributesModel.h"
00029 #include "KDChartAbstractGrid.h"
00030 #include "KDChartPainterSaver_p.h"
00031 
00032 #include <QPainter>
00033 #include <QDebug>
00034 
00035 #include <KDABLibFakes>
00036 
00037 #include "KDChartNormalBarDiagram_p.h"
00038 #include "KDChartStackedBarDiagram_p.h"
00039 #include "KDChartPercentBarDiagram_p.h"
00040 #include "KDChartNormalLyingBarDiagram_p.h"
00041 #include "KDChartStackedLyingBarDiagram_p.h"
00042 #include "KDChartPercentLyingBarDiagram_p.h"
00043 
00044 
00045 using namespace KDChart;
00046 
00047 BarDiagram::Private::Private()
00048     : orientation( Qt::Vertical )
00049     , implementor( 0 )
00050     , normalDiagram( 0 )
00051     , stackedDiagram( 0 )
00052     , percentDiagram( 0 )
00053     , normalLyingDiagram( 0 )
00054     , stackedLyingDiagram( 0 )
00055     , percentLyingDiagram( 0 )
00056 {    
00057 }
00058 
00059 BarDiagram::Private::~Private()
00060 {
00061     delete normalDiagram;
00062     delete stackedDiagram;
00063     delete percentDiagram;
00064     delete normalLyingDiagram;
00065     delete stackedLyingDiagram;
00066     delete percentLyingDiagram;
00067 }
00068 
00069 #define d d_func()
00070 
00071 
00072 BarDiagram::BarDiagram( QWidget* parent, CartesianCoordinatePlane* plane ) :
00073     AbstractCartesianDiagram( new Private(), parent, plane )
00074 {
00075     init();
00076 }
00077 
00078 void BarDiagram::init()
00079 {
00080     d->normalDiagram = new NormalBarDiagram( this );
00081     d->stackedDiagram = new StackedBarDiagram( this );
00082     d->percentDiagram = new PercentBarDiagram( this );
00083     d->normalLyingDiagram = new NormalLyingBarDiagram( this );
00084     d->stackedLyingDiagram = new StackedLyingBarDiagram( this );
00085     d->percentLyingDiagram = new PercentLyingBarDiagram( this );
00086     d->implementor = d->normalDiagram;
00087     d->compressor.setModel( attributesModel() );
00088 }
00089 
00090 BarDiagram::~BarDiagram()
00091 {
00092 }
00093 
00097 BarDiagram * BarDiagram::clone() const
00098 {
00099 
00100     BarDiagram* newDiagram = new BarDiagram( new Private( *d ) );
00101     newDiagram->setType( type() );
00102     return newDiagram;
00103 }
00104 
00105 bool BarDiagram::compare( const BarDiagram* other ) const
00106 {
00107     if( other == this ) return true;
00108     if( ! other ){
00109         return false;
00110     }
00111 
00112     return  // compare the base class
00113             ( static_cast<const AbstractCartesianDiagram*>(this)->compare( other ) ) &&
00114             // compare own properties
00115             (type() == other->type());
00116 }
00117 
00122 void BarDiagram::setType( const BarType type )
00123 {
00124     //if ( type == d->barType ) return;
00125      if ( d->implementor->type() == type ) return;
00126 
00127      if ( d->orientation == Qt::Vertical ) {
00128          switch( type ) {
00129          case Normal:
00130              d->implementor = d->normalDiagram;
00131              break;
00132          case Stacked:
00133              d->implementor = d->stackedDiagram;
00134              break;
00135          case Percent:
00136              d->implementor = d->percentDiagram;
00137              break;
00138          default:
00139              Q_ASSERT_X( false, "BarDiagram::setType", "unknown diagram subtype" );
00140          }
00141      } else {
00142          switch( type ) {
00143          case Normal:
00144              d->implementor = d->normalLyingDiagram;
00145              break;
00146          case Stacked:
00147              d->implementor = d->stackedLyingDiagram;
00148              break;
00149          case Percent:
00150              d->implementor = d->percentLyingDiagram;
00151              break;
00152          default:
00153              Q_ASSERT_X( false, "BarDiagram::setType", "unknown diagram subtype" );
00154          }
00155      }
00156 
00157    Q_ASSERT( d->implementor->type() == type );
00158 
00159    //d->barType = type;
00160     // AbstractAxis settings - see AbstractDiagram and CartesianAxis
00161     setPercentMode( type == BarDiagram::Percent );
00162     setDataBoundariesDirty();
00163     emit layoutChanged( this );
00164     emit propertiesChanged();
00165 }
00166 
00170 BarDiagram::BarType BarDiagram::type() const
00171 {
00172     return d->implementor->type();
00173 }
00174 
00178 void BarDiagram::setOrientation( Qt::Orientation orientation )
00179 {
00180     if ( d->orientation == orientation )
00181         return;
00182     d->orientation = orientation;
00183 
00184      if ( d->orientation == Qt::Vertical ) {
00185          switch( type() ) {
00186          case Normal:
00187              d->implementor = d->normalDiagram;
00188              break;
00189          case Stacked:
00190              d->implementor = d->stackedDiagram;
00191              break;
00192          case Percent:
00193              d->implementor = d->percentDiagram;
00194              break;
00195          default:
00196              Q_ASSERT_X( false, "BarDiagram::setType", "unknown diagram subtype" );
00197          }
00198      } else {
00199          switch( type() ) {
00200          case Normal:
00201              d->implementor = d->normalLyingDiagram;
00202              break;
00203          case Stacked:
00204              d->implementor = d->stackedLyingDiagram;
00205              break;
00206          case Percent:
00207              d->implementor = d->percentLyingDiagram;
00208              break;
00209          default:
00210              Q_ASSERT_X( false, "BarDiagram::setType", "unknown diagram subtype" );
00211          }
00212      }
00213 
00214     // AbstractAxis settings - see AbstractDiagram and CartesianAxis
00215     setPercentMode( type() == BarDiagram::Percent );
00216     setDataBoundariesDirty();
00217     emit layoutChanged( this );
00218     emit propertiesChanged();
00219 }
00220 
00224 Qt::Orientation BarDiagram::orientation() const
00225 {
00226     return d->orientation;
00227 }
00228 
00232 void BarDiagram::setBarAttributes( const BarAttributes& ba )
00233 {
00234     d->attributesModel->setModelData( qVariantFromValue( ba ), BarAttributesRole );
00235     emit propertiesChanged();
00236 }
00237 
00241 void BarDiagram::setBarAttributes( int column, const BarAttributes& ba )
00242 {
00243     d->setDatasetAttrs( column, qVariantFromValue( ba ), BarAttributesRole );
00244     emit propertiesChanged();
00245 }
00246 
00250 void BarDiagram::setBarAttributes( const QModelIndex& index, const BarAttributes& ba )
00251 {
00252     attributesModel()->setData(
00253         d->attributesModel->mapFromSource( index ),
00254         qVariantFromValue( ba ),
00255         BarAttributesRole );
00256     emit propertiesChanged();
00257 }
00258 
00262 BarAttributes BarDiagram::barAttributes() const
00263 {
00264     return qVariantValue<BarAttributes>(
00265         d->attributesModel->data( KDChart::BarAttributesRole ) );
00266 }
00267 
00271 BarAttributes BarDiagram::barAttributes( int column ) const
00272 {
00273     const QVariant attrs( d->datasetAttrs( column, KDChart::BarAttributesRole ) );
00274     if( attrs.isValid() )
00275         return qVariantValue< BarAttributes >( attrs );
00276     return barAttributes();
00277 }
00278 
00282 BarAttributes BarDiagram::barAttributes( const QModelIndex& index ) const
00283 {
00284     return qVariantValue<BarAttributes>(
00285         d->attributesModel->data(
00286             d->attributesModel->mapFromSource( index ),
00287             KDChart::BarAttributesRole ) );
00288 }
00289 
00293 void BarDiagram::setThreeDBarAttributes( const ThreeDBarAttributes& threeDAttrs )
00294 {
00295     setDataBoundariesDirty();
00296     d->attributesModel->setModelData( qVariantFromValue( threeDAttrs ), ThreeDBarAttributesRole );
00297     emit layoutChanged( this );
00298      emit propertiesChanged();
00299 }
00300 
00304 void BarDiagram::setThreeDBarAttributes( int column, const ThreeDBarAttributes& threeDAttrs )
00305 {
00306     setDataBoundariesDirty();
00307     d->setDatasetAttrs( column,  qVariantFromValue( threeDAttrs ), ThreeDBarAttributesRole );
00308     //emit layoutChanged( this );
00309     emit propertiesChanged();
00310 
00311 }
00312 
00316 void BarDiagram::setThreeDBarAttributes( const QModelIndex& index, const ThreeDBarAttributes& threeDAttrs )
00317 {
00318     setDataBoundariesDirty();
00319     d->attributesModel->setData(
00320         d->attributesModel->mapFromSource(index),
00321         qVariantFromValue( threeDAttrs ),
00322         ThreeDBarAttributesRole );
00323     //emit layoutChanged( this );
00324     emit propertiesChanged();
00325 }
00326 
00330 ThreeDBarAttributes BarDiagram::threeDBarAttributes() const
00331 {
00332     return qVariantValue<ThreeDBarAttributes>(
00333         d->attributesModel->data( KDChart::ThreeDBarAttributesRole ) );
00334 }
00335 
00339 ThreeDBarAttributes BarDiagram::threeDBarAttributes( int column ) const
00340 {
00341     const QVariant attrs( d->datasetAttrs( column, KDChart::ThreeDBarAttributesRole ) );
00342     if( attrs.isValid() )
00343         return qVariantValue< ThreeDBarAttributes >( attrs );
00344     return threeDBarAttributes();
00345 }
00346 
00350 ThreeDBarAttributes BarDiagram::threeDBarAttributes( const QModelIndex& index ) const
00351 {
00352     return qVariantValue<ThreeDBarAttributes>(
00353         d->attributesModel->data(
00354             d->attributesModel->mapFromSource(index),
00355             KDChart::ThreeDBarAttributesRole ) );
00356 }
00357 
00358 qreal BarDiagram::threeDItemDepth( const QModelIndex& index ) const
00359 {
00360     return threeDBarAttributes( index ).validDepth();
00361 }
00362 
00363 qreal BarDiagram::threeDItemDepth( int column ) const
00364 {
00365     return threeDBarAttributes( column ).validDepth();
00366 }
00367 
00368 void BarDiagram::resizeEvent ( QResizeEvent*)
00369 {
00370 
00371 }
00372 
00373 const QPair<QPointF, QPointF> BarDiagram::calculateDataBoundaries() const
00374 {
00375     d->compressor.setResolution( static_cast<int>( this->size().width() * coordinatePlane()->zoomFactorX() ),
00376                                  static_cast<int>( this->size().height() * coordinatePlane()->zoomFactorY() ) );
00377 
00378     if ( !checkInvariants( true ) ) {
00379         return QPair< QPointF, QPointF >( QPointF( 0, 0 ), QPointF( 0, 0 ) );
00380     }
00381 
00382     // note: calculateDataBoundaries() is ignoring the hidden flags.
00383     // That's not a bug but a feature: Hiding data does not mean removing them.
00384     // For totally removing data from KD Chart's view people can use e.g. a proxy model
00385     // calculate boundaries for different line types Normal - Stacked - Percent - Default Normal
00386     return d->implementor->calculateDataBoundaries();
00387 }
00388 
00389 void BarDiagram::paintEvent ( QPaintEvent*)
00390 {
00391     QPainter painter ( viewport() );
00392     PaintContext ctx;
00393     ctx.setPainter ( &painter );
00394     ctx.setRectangle( QRectF ( 0, 0, width(), height() ) );
00395     paint ( &ctx );
00396 }
00397 
00398 void BarDiagram::paint( PaintContext* ctx )
00399 {
00400     if ( !checkInvariants( true ) ) return;
00401     if ( !AbstractGrid::isBoundariesValid(dataBoundaries()) ) return;
00402     const PainterSaver p( ctx->painter() );
00403     if( model()->rowCount( rootIndex() ) == 0 || model()->columnCount( rootIndex() ) == 0 )
00404         return; // nothing to paint for us
00405 
00406     AbstractCoordinatePlane* const plane = ctx->coordinatePlane();
00407     ctx->setCoordinatePlane( plane->sharedAxisMasterPlane( ctx->painter() ) );
00408 
00409     // This was intended as a fix for KDCH-515, however it caused KDCH-816
00410     // and the original problem in KDCH-515 had by then been fixed in another way.
00411     // Bottom line is, this code is wrong because the above call to
00412     // plane->sharedAxisMasterPlane() performs a translation of the painter, which
00413     // also translates the clip rect, so if we set the old clip rect again afterwards,
00414     // we get a wrong clipping.
00415     // Also, this code is unnecessary because CartesianCoordinatePlane::paint()
00416     // already sets the clipping properly before calling this method.
00417     // ctx->painter()->setClipping( true );
00418     // ctx->painter()->setClipRect( ctx->rectangle() );
00419 
00420     // paint different bar types Normal - Stacked - Percent - Default Normal
00421     d->implementor->paint( ctx );
00422 
00423     ctx->setCoordinatePlane( plane );
00424 }
00425 
00426 void BarDiagram::resize( const QSizeF& size )
00427 {
00428     d->compressor.setResolution( static_cast< int >( size.width() * coordinatePlane()->zoomFactorX() ),
00429                                  static_cast< int >( size.height() * coordinatePlane()->zoomFactorY() ) );
00430     setDataBoundariesDirty();
00431 }
00432 
00433 #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
00434 const
00435 #endif
00436 int BarDiagram::numberOfAbscissaSegments () const
00437 {
00438     return d->attributesModel->rowCount(attributesModelRootIndex());
00439 }
00440 
00441 #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
00442 const
00443 #endif
00444 int BarDiagram::numberOfOrdinateSegments () const
00445 {
00446     return d->attributesModel->columnCount(attributesModelRootIndex());
00447 }
00448 
00449 //#undef d
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines

Klarälvdalens Datakonsult AB (KDAB)
Qt-related services and products
http://www.kdab.com/
http://www.kdab.com/products/kd-chart/