# KDChartPolarDiagram.cpp

Go to the documentation of this file.

    00001 /****************************************************************************
    00002  ** Copyright (C) 2006 Klar�vdalens Datakonsult AB.  All rights reserved.
    00003  **
    00004  ** This file is part of the KD Chart library.
    00005  **
    00006  ** This file may be distributed and/or modified under the terms of the
    00007  ** GNU General Public License version 2 as published by the Free Software
    00008  ** Foundation and appearing in the file LICENSE.GPL included in the
    00009  ** packaging of this file.
    00010  **
    00011  ** Licensees holding valid commercial KD Chart licenses may use this file in
    00012  ** accordance with the KD Chart Commercial License Agreement provided with
    00013  ** the Software.
    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  ** See http://www.kdab.net/kdchart for
    00019  **   information about KDChart Commercial License Agreements.
    00020  **
    00021  ** Contact info@kdab.net if any conditions of this
    00022  ** licensing are not clear to you.
    00023  **
    00024  **********************************************************************/
    00025
    00026
    00027 #include <QPainter>
    00028 #include "KDChartAttributesModel.h"
    00029 #include "KDChartPaintContext.h"
    00030 #include "KDChartPolarDiagram.h"
    00031 #include "KDChartPolarDiagram_p.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 PolarDiagram::~PolarDiagram()
    00055 {
    00056 }
    00057
    00058
    00059 void PolarDiagram::init()
    00060 {
    00061     setShowDelimitersAtPosition( Position::Unknown, false );
    00062     setShowDelimitersAtPosition( Position::Center, false );
    00063     setShowDelimitersAtPosition( Position::NorthWest, false );
    00064     setShowDelimitersAtPosition( Position::North, true );
    00065     setShowDelimitersAtPosition( Position::NorthEast, false );
    00066     setShowDelimitersAtPosition( Position::West, false );
    00067     setShowDelimitersAtPosition( Position::East, false );
    00068     setShowDelimitersAtPosition( Position::SouthWest, false );
    00069     setShowDelimitersAtPosition( Position::South, true );
    00070     setShowDelimitersAtPosition( Position::SouthEast, false );
    00071     setShowDelimitersAtPosition( Position::Floating, false );
    00072
    00073     setShowLabelsAtPosition( Position::Unknown, false );
    00074     setShowLabelsAtPosition( Position::Center, false );
    00075     setShowLabelsAtPosition( Position::NorthWest, false );
    00076     setShowLabelsAtPosition( Position::North, true );
    00077     setShowLabelsAtPosition( Position::NorthEast, false );
    00078     setShowLabelsAtPosition( Position::West, false );
    00079     setShowLabelsAtPosition( Position::East, false );
    00080     setShowLabelsAtPosition( Position::SouthWest, false );
    00081     setShowLabelsAtPosition( Position::South, true );
    00082     setShowLabelsAtPosition( Position::SouthEast, false );
    00083     setShowLabelsAtPosition( Position::Floating, false );
    00084 }
    00085
    00086
    00087
    00088
    00089 PolarDiagram * PolarDiagram::clone() const
    00090 {
    00091     PolarDiagram* newDiagram = new PolarDiagram( new Private( *d ) );
    00092     // This needs to be copied after the fact
    00093     newDiagram->d->showDelimitersAtPosition = d->showDelimitersAtPosition;
    00094     newDiagram->d->showLabelsAtPosition = d->showLabelsAtPosition;
    00095     newDiagram->d->rotateCircularLabels = d->rotateCircularLabels;
    00096     newDiagram->d->closeDatasets = d->closeDatasets;
    00097     return newDiagram;
    00098 }
    00099
    00100 const QPair<QPointF, QPointF> PolarDiagram::calculateDataBoundaries () const
    00101 {
    00102     if ( !checkInvariants(true) ) return QPair<QPointF, QPointF>( QPointF( 0, 0 ), QPointF( 0, 0 ) );
    00103     const int rowCount = model()->rowCount(rootIndex());
    00104     const int colCount = model()->columnCount(rootIndex());
    00105     double xMin = 0.0;
    00106     double xMax = colCount;
    00107     double yMin = 0, yMax = 0;
    00108     for ( int j=0; j<colCount; ++j ) {
    00109         for ( int i=0; i< rowCount; ++i ) {
    00110             double value = model()->data( model()->index( i, j, rootIndex() ) ).toDouble();
    00111             yMax = qMax( yMax, value );
    00112         }
    00113     }
    00114     QPointF bottomLeft ( QPointF( xMin, yMin ) );
    00115     QPointF topRight ( QPointF( xMax, yMax ) );
    00116     return QPair<QPointF, QPointF> ( bottomLeft,  topRight );
    00117 }
    00118
    00119
    00120
    00121 void PolarDiagram::paintEvent ( QPaintEvent*)
    00122 {
    00123     QPainter painter ( viewport() );
    00124     PaintContext ctx;
    00125     ctx.setPainter ( &painter );
    00126     ctx.setRectangle( QRectF ( 0, 0, width(), height() ) );
    00127     paint ( &ctx );
    00128 }
    00129
    00130 void PolarDiagram::resizeEvent ( QResizeEvent*)
    00131 {
    00132 }
    00133
    00134 void PolarDiagram::paintPolarMarkers( PaintContext* ctx, const QPolygonF& polygon )
    00135 {
    00136     const double markerSize = 4; // FIXME use real markers
    00137     for ( int i=0; i<polygon.size(); ++i ) {
    00138         QPointF p = polygon.at( i );
    00139         p.setX( p.x() - markerSize/2 );
    00140         p.setY( p.y() - markerSize/2 );
    00141         ctx->painter()->drawRect( QRectF( p, QSizeF( markerSize, markerSize ) ) );
    00142     }
    00143 }
    00144
    00145 void PolarDiagram::paint( PaintContext* ctx )
    00146 {
    00147     // note: Not having any data model assigned is no bug
    00148     //       but we can not draw a diagram then either.
    00149     if ( !checkInvariants(true) )
    00150         return;
    00151
    00152     const int rowCount = model()->rowCount( rootIndex() );
    00153     const int colCount = model()->columnCount( rootIndex() );
    00154     DataValueTextInfoList list;
    00155
    00156     for ( int j=0; j < colCount; ++j ) {
    00157         QBrush brush = qVariantValue<QBrush>( attributesModel()->headerData( j, Qt::Vertical, KDChart::DatasetBrushRole ) );
    00158         QPolygonF polygon;
    00159         QPointF point0;
    00160         for ( int i=0; i < rowCount; ++i ) {
    00161             QModelIndex index = model()->index( i, j, rootIndex() );
    00162             const double value = model()->data( index ).toDouble();
    00163             QPointF point = coordinatePlane()->translate( QPointF( value, i ) );
    00164             polygon.append( point );
    00165             const DataValueTextInfo info( index, point, point, value );
    00166             list.append( info );
    00167             if( ! i )
    00168                 point0= point;
    00169         }
    00170         if( closeDatasets() && rowCount )
    00171             polygon.append( point0 );
    00172
    00173         PainterSaver painterSaver( ctx->painter() );
    00174         ctx->painter()->setRenderHint ( QPainter::Antialiasing );
    00175         ctx->painter()->setBrush( brush );
    00176         QPen p( ctx->painter()->pen() );
    00177         p.setColor( brush.color() ); // FIXME use DatasetPenRole
    00178         p.setWidth( 2 );// FIXME properties
    00179         ctx->painter()->setPen( p );
    00180         polygon.translate( ctx->rectangle().topLeft() );
    00181         ctx->painter()->drawPolyline( polygon );
    00182         paintPolarMarkers( ctx, polygon );
    00183     }
    00184     DataValueTextInfoListIterator it( list );
    00185     while ( it.hasNext() ) {
    00186         const DataValueTextInfo& info = it.next();
    00187         paintDataValueText( ctx->painter(), info.index, info.pos, info.value );
    00188     }
    00189 }
    00190
    00191 void PolarDiagram::resize ( const QSizeF& )
    00192 {
    00193 }
    00194
    00195 /*virtual*/
    00196 double PolarDiagram::valueTotals () const
    00197 {
    00198     return model()->rowCount(rootIndex());
    00199 }
    00200
    00201 /*virtual*/
    00202 double PolarDiagram::numberOfValuesPerDataset() const
    00203 {
    00204     return model() ? model()->rowCount(rootIndex()) : 0.0;
    00205 }
    00206
    00207 /*virtual*/
    00208 double PolarDiagram::numberOfGridRings() const
    00209 {
    00210     return 5; // FIXME
    00211 }
    00212
    00213 void PolarDiagram::setZeroDegreePosition( int degrees )
    00214 {
    00215     qWarning() << "Deprecated PolarDiagram::setZeroDegreePosition() called, setting ignored.";
    00216 }
    00217
    00218 int PolarDiagram::zeroDegreePosition() const
    00219 {
    00220     qWarning() << "Deprecated PolarDiagram::zeroDegreePosition() called.";
    00221     return 0;
    00222 }
    00223
    00224 void PolarDiagram::setRotateCircularLabels( bool rotateCircularLabels )
    00225 {
    00226     d->rotateCircularLabels = rotateCircularLabels;
    00227 }
    00228
    00229 bool PolarDiagram::rotateCircularLabels() const
    00230 {
    00231     return d->rotateCircularLabels;
    00232 }
    00233
    00234 void PolarDiagram::setCloseDatasets( bool closeDatasets )
    00235 {
    00236     d->closeDatasets = closeDatasets;
    00237 }
    00238
    00239 bool PolarDiagram::closeDatasets() const
    00240 {
    00241     return d->closeDatasets;
    00242 }
    00243
    00244 void PolarDiagram::setShowDelimitersAtPosition( Position position,
    00245                                                        bool showDelimiters )
    00246 {
    00247     d->showDelimitersAtPosition[position.value()] = showDelimiters;
    00248 }
    00249
    00250 void PolarDiagram::setShowLabelsAtPosition( Position position,
    00251                                                    bool showLabels )
    00252 {
    00253     d->showLabelsAtPosition[position.value()] = showLabels;
    00254 }
    00255
    00256 bool PolarDiagram::showDelimitersAtPosition( Position position ) const
    00257 {
    00258     return d->showDelimitersAtPosition[position.value()];
    00259 }
    00260
    00261 bool PolarDiagram::showLabelsAtPosition( Position position ) const
    00262 {
    00263     return d->showLabelsAtPosition[position.value()];
    00264 }
    00265
    00266
    00267