KDChartPlotter.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 ** Copyright (C) 2001-2010 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 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 "KDChartPlotter.h"
00024 #include "KDChartPlotter_p.h"
00025 
00026 #include "KDChartAbstractGrid.h"
00027 
00028 #include <KDABLibFakes>
00029 
00030 #include "KDChartNormalPlotter_p.h"
00031 #include "KDChartPercentPlotter_p.h"
00032 
00033 using namespace KDChart;
00034 
00035 Plotter::Private::Private()
00036 {
00037 }
00038 
00039 Plotter::Private::~Private() {}
00040 
00041 
00042 #define d d_func()
00043 
00044 
00045 Plotter::Plotter( QWidget* parent, CartesianCoordinatePlane* plane ) :
00046     AbstractCartesianDiagram( new Private(), parent, plane )
00047 {
00048     init();
00049 }
00050 
00051 void Plotter::init()
00052 {
00053     d->diagram = this;
00054     d->normalPlotter = new NormalPlotter( this );
00055     d->percentPlotter = new PercentPlotter( this );
00056     d->implementor = d->normalPlotter;
00057 
00058     setDatasetDimensionInternal( 2 );
00059 }
00060 
00061 Plotter::~Plotter()
00062 {
00063 }
00064 
00068 Plotter* Plotter::clone() const
00069 {
00070     Plotter* newDiagram = new Plotter( new Private( *d ) );
00071     newDiagram->setType( type() );
00072     return newDiagram;
00073 }
00074 
00075 bool Plotter::compare( const Plotter* other )const
00076 {
00077     if( other == this )
00078         return true;
00079     if( other == 0 )
00080         return false;
00081     return  // compare the base class
00082             ( static_cast< const AbstractCartesianDiagram* >( this )->compare( other ) ) &&
00083             // compare own properties
00084             ( type() == other->type() );
00085 }
00086 
00090 void Plotter::setType( const PlotType type )
00091 {
00092     if( d->implementor->type() == type )
00093         return;
00094     if( datasetDimension() != 2 )
00095     {
00096        Q_ASSERT_X ( false, "setType()",
00097                     "This line chart type can only be used with two-dimensional data." );
00098        return;
00099     }
00100     switch( type ) {
00101     case Normal:
00102         d->implementor = d->normalPlotter;
00103         break;
00104     case Percent:
00105         d->implementor = d->percentPlotter;
00106         break;
00107     default:
00108         Q_ASSERT_X( false, "Plotter::setType", "unknown plotter subtype" );
00109     };
00110 
00111     // d->lineType = type;
00112     Q_ASSERT( d->implementor->type() == type );
00113 
00114     setDataBoundariesDirty();
00115     emit layoutChanged( this );
00116     emit propertiesChanged();
00117 }
00118 
00122 Plotter::PlotType Plotter::type() const
00123 {
00124     return d->implementor->type();
00125 }
00126 
00130 void Plotter::setLineAttributes( const LineAttributes& la )
00131 {
00132     d->attributesModel->setModelData(
00133         qVariantFromValue( la ),
00134         LineAttributesRole );
00135     emit propertiesChanged();
00136 }
00137 
00141 void Plotter::setLineAttributes(
00142         int column,
00143     const LineAttributes& la )
00144 {
00145     d->setDatasetAttrs( column, qVariantFromValue( la ),
00146             LineAttributesRole );
00147     emit propertiesChanged();
00148 }
00149 
00153 void Plotter::resetLineAttributes( int column )
00154 {
00155     d->resetDatasetAttrs( column, LineAttributesRole );
00156     emit propertiesChanged();
00157 }
00158 
00162 void Plotter::setLineAttributes(
00163         const QModelIndex & index,
00164     const LineAttributes& la )
00165 {
00166     d->attributesModel->setData(
00167             d->attributesModel->mapFromSource(index),
00168     qVariantFromValue( la ),
00169     LineAttributesRole );
00170     emit propertiesChanged();
00171 }
00172 
00176 void Plotter::resetLineAttributes( const QModelIndex & index )
00177 {
00178     d->attributesModel->resetData(
00179             d->attributesModel->mapFromSource(index), LineAttributesRole );
00180     emit propertiesChanged();
00181 }
00182 
00186 LineAttributes Plotter::lineAttributes() const
00187 {
00188     return qVariantValue<LineAttributes>(
00189         d->attributesModel->data( KDChart::LineAttributesRole ) );
00190 }
00191 
00195 LineAttributes Plotter::lineAttributes( int column ) const
00196 {
00197     const QVariant attrs( d->datasetAttrs( column, LineAttributesRole ) );
00198     if( attrs.isValid() )
00199         return qVariantValue< LineAttributes >( attrs );
00200     return lineAttributes();
00201 }
00202 
00206 LineAttributes Plotter::lineAttributes(
00207     const QModelIndex& index ) const
00208 {
00209     return qVariantValue<LineAttributes>(
00210         d->attributesModel->data(
00211             d->attributesModel->mapFromSource(index),
00212             KDChart::LineAttributesRole ) );
00213 }
00214 
00218 void Plotter::setThreeDLineAttributes(
00219     const ThreeDLineAttributes& la )
00220 {
00221     setDataBoundariesDirty();
00222     d->attributesModel->setModelData(
00223         qVariantFromValue( la ),
00224         ThreeDLineAttributesRole );
00225    emit propertiesChanged();
00226 }
00227 
00231 void Plotter::setThreeDLineAttributes(
00232     int column,
00233     const ThreeDLineAttributes& la )
00234 {
00235     setDataBoundariesDirty();
00236     d->setDatasetAttrs( column, qVariantFromValue( la ), ThreeDLineAttributesRole );
00237    emit propertiesChanged();
00238 }
00239 
00243 void Plotter::setThreeDLineAttributes(
00244     const QModelIndex& index,
00245     const ThreeDLineAttributes& la )
00246 {
00247     setDataBoundariesDirty();
00248     d->attributesModel->setData(
00249         d->attributesModel->mapFromSource(index),
00250         qVariantFromValue( la ),
00251         ThreeDLineAttributesRole );
00252    emit propertiesChanged();
00253 }
00254 
00258 ThreeDLineAttributes Plotter::threeDLineAttributes() const
00259 {
00260     return qVariantValue<ThreeDLineAttributes>(
00261         d->attributesModel->data( KDChart::ThreeDLineAttributesRole ) );
00262 }
00263 
00267 ThreeDLineAttributes Plotter::threeDLineAttributes( int column ) const
00268 {
00269     const QVariant attrs( d->datasetAttrs( column, ThreeDLineAttributesRole ) );
00270     if( attrs.isValid() )
00271         return qVariantValue< ThreeDLineAttributes >( attrs );
00272     return threeDLineAttributes();
00273 }
00274 
00278 ThreeDLineAttributes Plotter::threeDLineAttributes(
00279     const QModelIndex& index ) const
00280 {
00281     return qVariantValue<ThreeDLineAttributes>(
00282         d->attributesModel->data(
00283             d->attributesModel->mapFromSource( index ),
00284             KDChart::ThreeDLineAttributesRole ) );
00285 }
00286 
00287 double Plotter::threeDItemDepth( const QModelIndex & index ) const
00288 {
00289     return threeDLineAttributes( index ).validDepth();
00290 }
00291 
00292 double Plotter::threeDItemDepth( int column ) const
00293 {
00294     return qVariantValue<ThreeDLineAttributes>(
00295         d->datasetAttrs( column, KDChart::ThreeDLineAttributesRole ) ).validDepth();
00296 }
00297 
00301 void Plotter::setValueTrackerAttributes( const QModelIndex & index,
00302                                              const ValueTrackerAttributes & va )
00303 {
00304     d->attributesModel->setData( d->attributesModel->mapFromSource(index),
00305                                  qVariantFromValue( va ),
00306                                  KDChart::ValueTrackerAttributesRole );
00307     emit propertiesChanged();
00308 }
00309 
00313 ValueTrackerAttributes Plotter::valueTrackerAttributes(
00314         const QModelIndex & index ) const
00315 {
00316     return qVariantValue<ValueTrackerAttributes>( d->attributesModel->data(
00317             d->attributesModel->mapFromSource( index ),
00318             KDChart::ValueTrackerAttributesRole ) );
00319 }
00320 
00321 void Plotter::resizeEvent ( QResizeEvent* )
00322 {
00323 }
00324 
00325 const QPair< QPointF, QPointF > Plotter::calculateDataBoundaries() const
00326 {
00327     if ( !checkInvariants( true ) )
00328         return QPair< QPointF, QPointF >( QPointF( 0, 0 ), QPointF( 0, 0 ) );
00329 
00330     // note: calculateDataBoundaries() is ignoring the hidden flags.
00331     //       That's not a bug but a feature: Hiding data does not mean removing them.
00332     // For totally removing data from KD Chart's view people can use e.g. a proxy model ...
00333 
00334     // calculate boundaries for different line types Normal - Stacked - Percent - Default Normal
00335     return d->implementor->calculateDataBoundaries();
00336 }
00337 
00338 
00339 void Plotter::paintEvent ( QPaintEvent*)
00340 {
00341     QPainter painter ( viewport() );
00342     PaintContext ctx;
00343     ctx.setPainter ( &painter );
00344     ctx.setRectangle ( QRectF ( 0, 0, width(), height() ) );
00345     paint ( &ctx );
00346 }
00347 
00348 void Plotter::paint( PaintContext* ctx )
00349 {
00350     // note: Not having any data model assigned is no bug
00351     //       but we can not draw a diagram then either.
00352     if ( !checkInvariants( true ) ) return;
00353 
00354     AbstractCoordinatePlane* const plane = ctx->coordinatePlane();
00355     if( ! plane ) return;
00356     d->setCompressorResolution( size(), plane );
00357 
00358     if ( !AbstractGrid::isBoundariesValid(dataBoundaries()) ) return;
00359 
00360     const PainterSaver p( ctx->painter() );
00361     if( model()->rowCount( rootIndex() ) == 0 || model()->columnCount( rootIndex() ) == 0 )
00362         return; // nothing to paint for us
00363 
00364     ctx->setCoordinatePlane( plane->sharedAxisMasterPlane( ctx->painter() ) );
00365 
00366     // paint different line types Normal - Stacked - Percent - Default Normal
00367     d->implementor->paint( ctx );
00368 
00369     ctx->setCoordinatePlane( plane );
00370 }
00371 
00372 void Plotter::resize ( const QSizeF& size )
00373 {
00374     d->setCompressorResolution( size, coordinatePlane() );
00375     setDataBoundariesDirty();
00376 }
00377 
00378 #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
00379 const
00380 #endif
00381 int Plotter::numberOfAbscissaSegments () const
00382 {
00383     return d->attributesModel->rowCount( attributesModelRootIndex() );
00384 }
00385 
00386 #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
00387 const
00388 #endif
00389 int Plotter::numberOfOrdinateSegments () const
00390 {
00391     return d->attributesModel->columnCount( attributesModelRootIndex() );
00392 }