00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "KDChartPolarDiagram.h"
00024 #include "KDChartPolarDiagram_p.h"
00025
00026 #include <QPainter>
00027 #include "KDChartAttributesModel.h"
00028 #include "KDChartPaintContext.h"
00029 #include "KDChartPainterSaver_p.h"
00030 #include "KDChartDataValueAttributes.h"
00031
00032 #include <KDABLibFakes>
00033
00034 using namespace KDChart;
00035
00036 PolarDiagram::Private::Private() :
00037 rotateCircularLabels( false ),
00038 closeDatasets( false )
00039 {
00040 }
00041
00042 PolarDiagram::Private::~Private() {}
00043
00044 #define d d_func()
00045
00046 PolarDiagram::PolarDiagram( QWidget* parent, PolarCoordinatePlane* plane ) :
00047 AbstractPolarDiagram( new Private( ), parent, plane )
00048 {
00049
00050 }
00051
00052 PolarDiagram::~PolarDiagram()
00053 {
00054 }
00055
00056
00057 void PolarDiagram::init()
00058 {
00059 setShowDelimitersAtPosition( Position::Unknown, false );
00060 setShowDelimitersAtPosition( Position::Center, false );
00061 setShowDelimitersAtPosition( Position::NorthWest, false );
00062 setShowDelimitersAtPosition( Position::North, true );
00063 setShowDelimitersAtPosition( Position::NorthEast, false );
00064 setShowDelimitersAtPosition( Position::West, false );
00065 setShowDelimitersAtPosition( Position::East, false );
00066 setShowDelimitersAtPosition( Position::SouthWest, false );
00067 setShowDelimitersAtPosition( Position::South, true );
00068 setShowDelimitersAtPosition( Position::SouthEast, false );
00069 setShowDelimitersAtPosition( Position::Floating, false );
00070
00071 setShowLabelsAtPosition( Position::Unknown, false );
00072 setShowLabelsAtPosition( Position::Center, false );
00073 setShowLabelsAtPosition( Position::NorthWest, false );
00074 setShowLabelsAtPosition( Position::North, true );
00075 setShowLabelsAtPosition( Position::NorthEast, false );
00076 setShowLabelsAtPosition( Position::West, false );
00077 setShowLabelsAtPosition( Position::East, false );
00078 setShowLabelsAtPosition( Position::SouthWest, false );
00079 setShowLabelsAtPosition( Position::South, true );
00080 setShowLabelsAtPosition( Position::SouthEast, false );
00081 setShowLabelsAtPosition( Position::Floating, false );
00082 }
00083
00087 PolarDiagram * PolarDiagram::clone() const
00088 {
00089 PolarDiagram* newDiagram = new PolarDiagram( new Private( *d ) );
00090
00091 newDiagram->d->showDelimitersAtPosition = d->showDelimitersAtPosition;
00092 newDiagram->d->showLabelsAtPosition = d->showLabelsAtPosition;
00093 newDiagram->d->rotateCircularLabels = d->rotateCircularLabels;
00094 newDiagram->d->closeDatasets = d->closeDatasets;
00095 return newDiagram;
00096 }
00097
00098 const QPair<QPointF, QPointF> PolarDiagram::calculateDataBoundaries () const
00099 {
00100 if ( !checkInvariants(true) ) return QPair<QPointF, QPointF>( QPointF( 0, 0 ), QPointF( 0, 0 ) );
00101 const int rowCount = model()->rowCount(rootIndex());
00102 const int colCount = model()->columnCount(rootIndex());
00103 double xMin = 0.0;
00104 double xMax = colCount;
00105 double yMin = 0, yMax = 0;
00106 for ( int iCol=0; iCol<colCount; ++iCol ) {
00107 for ( int iRow=0; iRow< rowCount; ++iRow ) {
00108 double value = model()->data( model()->index( iRow, iCol, rootIndex() ) ).toDouble();
00109 yMax = qMax( yMax, value );
00110 yMin = qMin( yMin, value );
00111 }
00112 }
00113 QPointF bottomLeft ( QPointF( xMin, yMin ) );
00114 QPointF topRight ( QPointF( xMax, yMax ) );
00115 return QPair<QPointF, QPointF> ( bottomLeft, topRight );
00116 }
00117
00118
00119
00120 void PolarDiagram::paintEvent ( QPaintEvent*)
00121 {
00122 QPainter painter ( viewport() );
00123 PaintContext ctx;
00124 ctx.setPainter ( &painter );
00125 ctx.setRectangle( QRectF ( 0, 0, width(), height() ) );
00126 paint ( &ctx );
00127 }
00128
00129 void PolarDiagram::resizeEvent ( QResizeEvent*)
00130 {
00131 }
00132
00133 void PolarDiagram::paintPolarMarkers( PaintContext* ctx, const QPolygonF& polygon )
00134 {
00135 Q_UNUSED(ctx);
00136 Q_UNUSED(polygon);
00137
00138 }
00139
00140 void PolarDiagram::paint( PaintContext* ctx )
00141 {
00142 qreal dummy1, dummy2;
00143 paint( ctx, true, dummy1, dummy2 );
00144 paint( ctx, false, dummy1, dummy2 );
00145 }
00146
00147 void PolarDiagram::paint( PaintContext* ctx,
00148 bool calculateListAndReturnScale,
00149 qreal& newZoomX, qreal& newZoomY )
00150 {
00151
00152
00153 if ( !checkInvariants(true) )
00154 return;
00155 d->reverseMapper.clear();
00156
00157 const int rowCount = model()->rowCount( rootIndex() );
00158 const int colCount = model()->columnCount( rootIndex() );
00159
00160 int iRow, iCol;
00161
00162 if( calculateListAndReturnScale ){
00163
00164
00165
00166 d->dataValueInfoList.clear();
00167 for ( iCol=0; iCol < colCount; ++iCol ) {
00168 for ( iRow=0; iRow < rowCount; ++iRow ) {
00169 QModelIndex index = model()->index( iRow, iCol, rootIndex() );
00170 const double value = model()->data( index ).toDouble();
00171 QPointF point = coordinatePlane()->translate(
00172 QPointF( value, iRow ) ) + ctx->rectangle().topLeft();
00173
00174 d->appendDataValueTextInfoToList(
00175 this, d->dataValueInfoList, index, 0,
00176 PositionPoints( point ), Position::Center, Position::Center,
00177 value );
00178 }
00179 }
00180 const qreal oldZoomX = coordinatePlane()->zoomFactorX();
00181 const qreal oldZoomY = coordinatePlane()->zoomFactorY();
00182 newZoomX = oldZoomX;
00183 newZoomY = oldZoomY;
00184 if( d->dataValueInfoList.count() ){
00185 QRectF txtRectF;
00186 d->paintDataValueTextsAndMarkers( this, ctx, d->dataValueInfoList, true, true, &txtRectF );
00187 const QRect txtRect = txtRectF.toRect();
00188 const QRect curRect = coordinatePlane()->geometry();
00189 const qreal gapX = qMin( txtRect.left() - curRect.left(), curRect.right() - txtRect.right() );
00190 const qreal gapY = qMin( txtRect.top() - curRect.top(), curRect.bottom() - txtRect.bottom() );
00191 newZoomX = oldZoomX;
00192 newZoomY = oldZoomY;
00193 if( gapX < 0.0 )
00194 newZoomX *= 1.0 + (gapX-1.0) / curRect.width();
00195 if( gapY < 0.0 )
00196 newZoomY *= 1.0 + (gapY-1.0) / curRect.height();
00197 }
00198
00199 }else{
00200
00201 for ( iCol=0; iCol < colCount; ++iCol ) {
00202
00203
00204
00205
00206 QBrush brush = qVariantValue<QBrush>( d->datasetAttrs( iCol, KDChart::DatasetBrushRole ) );
00207 QPolygonF polygon;
00208 QPointF point0;
00209 for ( iRow=0; iRow < rowCount; ++iRow ) {
00210 QModelIndex index = model()->index( iRow, iCol, rootIndex() );
00211 const double value = model()->data( index ).toDouble();
00212 QPointF point = coordinatePlane()->translate(
00213 QPointF( value, iRow ) ) + ctx->rectangle().topLeft();
00214 polygon.append( point );
00215
00216 if( ! iRow )
00217 point0= point;
00218 }
00219 if( closeDatasets() && rowCount )
00220 polygon.append( point0 );
00221
00222 PainterSaver painterSaver( ctx->painter() );
00223 ctx->painter()->setRenderHint ( QPainter::Antialiasing );
00224 ctx->painter()->setBrush( brush );
00225 QPen p( ctx->painter()->pen() );
00226 p.setColor( brush.color() );
00227 p.setWidth( 2 );
00228 ctx->painter()->setPen( PrintingParameters::scalePen( p ) );
00229 ctx->painter()->drawPolyline( polygon );
00230 }
00231 d->paintDataValueTextsAndMarkers( this, ctx, d->dataValueInfoList, true );
00232 }
00233 }
00234
00235 void PolarDiagram::resize ( const QSizeF& )
00236 {
00237 }
00238
00239
00240 double PolarDiagram::valueTotals () const
00241 {
00242 return model()->rowCount(rootIndex());
00243 }
00244
00245
00246 double PolarDiagram::numberOfValuesPerDataset() const
00247 {
00248 return model() ? model()->rowCount(rootIndex()) : 0.0;
00249 }
00250
00251
00252 double PolarDiagram::numberOfGridRings() const
00253 {
00254 return 5;
00255 }
00256
00257 void PolarDiagram::setZeroDegreePosition( int degrees )
00258 {
00259 Q_UNUSED( degrees );
00260 qWarning() << "Deprecated PolarDiagram::setZeroDegreePosition() called, setting ignored.";
00261 }
00262
00263 int PolarDiagram::zeroDegreePosition() const
00264 {
00265 qWarning() << "Deprecated PolarDiagram::zeroDegreePosition() called.";
00266 return 0;
00267 }
00268
00269 void PolarDiagram::setRotateCircularLabels( bool rotateCircularLabels )
00270 {
00271 d->rotateCircularLabels = rotateCircularLabels;
00272 }
00273
00274 bool PolarDiagram::rotateCircularLabels() const
00275 {
00276 return d->rotateCircularLabels;
00277 }
00278
00279 void PolarDiagram::setCloseDatasets( bool closeDatasets )
00280 {
00281 d->closeDatasets = closeDatasets;
00282 }
00283
00284 bool PolarDiagram::closeDatasets() const
00285 {
00286 return d->closeDatasets;
00287 }
00288
00289 void PolarDiagram::setShowDelimitersAtPosition( Position position,
00290 bool showDelimiters )
00291 {
00292 d->showDelimitersAtPosition[position.value()] = showDelimiters;
00293 }
00294
00295 void PolarDiagram::setShowLabelsAtPosition( Position position,
00296 bool showLabels )
00297 {
00298 d->showLabelsAtPosition[position.value()] = showLabels;
00299 }
00300
00301 bool PolarDiagram::showDelimitersAtPosition( Position position ) const
00302 {
00303 return d->showDelimitersAtPosition[position.value()];
00304 }
00305
00306 bool PolarDiagram::showLabelsAtPosition( Position position ) const
00307 {
00308 return d->showLabelsAtPosition[position.value()];
00309 }
00310
00311
00312