KD Chart 2 [rev.2.4]
|
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 "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 }