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