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 <math.h>
00027
00028 #include <QFont>
00029 #include <QList>
00030 #include <QtDebug>
00031 #include <QPainter>
00032
00033 #include "KDChartChart.h"
00034 #include "KDChartPaintContext.h"
00035 #include "KDChartAbstractDiagram.h"
00036 #include "KDChartAbstractPolarDiagram.h"
00037 #include "KDChartPolarCoordinatePlane.h"
00038 #include "KDChartPolarCoordinatePlane_p.h"
00039 #include "KDChartPainterSaver_p.h"
00040
00041 #include <KDABLibFakes>
00042
00043 using namespace KDChart;
00044
00045 #define d d_func()
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 PolarCoordinatePlane::PolarCoordinatePlane ( Chart* parent )
00115 : AbstractCoordinatePlane ( new Private(), parent )
00116 {
00117
00118 }
00119
00120 PolarCoordinatePlane::~PolarCoordinatePlane()
00121 {
00122
00123 }
00124
00125 void PolarCoordinatePlane::init()
00126 {
00127
00128 }
00129
00130 void PolarCoordinatePlane::addDiagram ( AbstractDiagram* diagram )
00131 {
00132 Q_ASSERT_X ( dynamic_cast<AbstractPolarDiagram*> ( diagram ),
00133 "PolarCoordinatePlane::addDiagram", "Only polar"
00134 "diagrams can be added to a polar coordinate plane!" );
00135 AbstractCoordinatePlane::addDiagram ( diagram );
00136 connect ( diagram, SIGNAL ( layoutChanged ( AbstractDiagram* ) ),
00137 SLOT ( slotLayoutChanged ( AbstractDiagram* ) ) );
00138
00139 }
00140
00141 void PolarCoordinatePlane::paint ( QPainter* painter )
00142 {
00143 AbstractDiagramList diags = diagrams();
00144 if ( d->coordinateTransformations.size() == diags.size() )
00145 {
00146 PaintContext ctx;
00147 ctx.setPainter ( painter );
00148 ctx.setCoordinatePlane ( this );
00149 ctx.setRectangle ( geometry() );
00150
00151
00152 d->currentTransformation = & ( d->coordinateTransformations[0] );
00153 d->grid->drawGrid( &ctx );
00154
00155
00156 for ( int i = 0; i < diags.size(); i++ )
00157 {
00158 d->currentTransformation = & ( d->coordinateTransformations[i] );
00159 PainterSaver painterSaver( painter );
00160 diags[i]->paint ( &ctx );
00161 }
00162 d->currentTransformation = 0;
00163 }
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 void PolarCoordinatePlane::resizeEvent ( QResizeEvent* )
00233 {
00234 d->initialResizeEventReceived = true;
00235 layoutDiagrams();
00236 }
00237
00238 void PolarCoordinatePlane::layoutDiagrams()
00239 {
00240
00241
00242
00243
00244
00245
00246 const QRect rect( areaGeometry() );
00247 d->contentRect = QRectF ( 1, 1, rect.width() - 3, rect.height() - 3 );
00248
00249
00250 const qreal oldStartPosition = startPosition();
00251 d->coordinateTransformations.clear();
00252 Q_FOREACH( AbstractDiagram* diagram, diagrams() )
00253 {
00254 AbstractPolarDiagram *polarDiagram = dynamic_cast<AbstractPolarDiagram*>( diagram );
00255 Q_ASSERT( polarDiagram );
00256 QPair<QPointF, QPointF> dataBoundariesPair = polarDiagram->dataBoundaries();
00257
00258 const double angleUnit = 360 / polarDiagram->valueTotals();
00259
00260 const double radius = dataBoundariesPair.second.y();
00261
00262 const double diagramWidth = radius * 2;
00263 const double planeWidth = d->contentRect.width();
00264 const double planeHeight = d->contentRect.height();
00265 const double radiusUnit = qMin( planeWidth, planeHeight ) / diagramWidth;
00266
00267 QPointF coordinateOrigin = QPointF ( planeWidth / 2, planeHeight / 2 );
00268 coordinateOrigin += d->contentRect.topLeft();
00269
00270 CoordinateTransformation diagramTransposition;
00271 diagramTransposition.originTranslation = coordinateOrigin;
00272 diagramTransposition.radiusUnit = radiusUnit;
00273 diagramTransposition.angleUnit = angleUnit;
00274 diagramTransposition.startPosition = oldStartPosition;
00275 diagramTransposition.zoom = ZoomParameters();
00276 d->coordinateTransformations.append( diagramTransposition );
00277 }
00278 }
00279
00280 const QPointF PolarCoordinatePlane::translate( const QPointF& diagramPoint ) const
00281 {
00282 Q_ASSERT_X ( d->currentTransformation != 0, "PolarCoordinatePlane::translate",
00283 "Only call translate() from within paint()." );
00284 return d->currentTransformation->translate ( diagramPoint );
00285 }
00286
00287 const QPointF PolarCoordinatePlane::translatePolar( const QPointF& diagramPoint ) const
00288 {
00289 Q_ASSERT_X ( d->currentTransformation != 0, "PolarCoordinatePlane::translate",
00290 "Only call translate() from within paint()." );
00291 return d->currentTransformation->translatePolar ( diagramPoint );
00292 }
00293
00294 qreal PolarCoordinatePlane::angleUnit() const
00295 {
00296 Q_ASSERT_X ( d->currentTransformation != 0, "PolarCoordinatePlane::angleUnit",
00297 "Only call angleUnit() from within paint()." );
00298 return d->currentTransformation->angleUnit;
00299 }
00300
00301 qreal PolarCoordinatePlane::radiusUnit() const
00302 {
00303 Q_ASSERT_X ( d->currentTransformation != 0, "PolarCoordinatePlane::radiusUnit",
00304 "Only call radiusUnit() from within paint()." );
00305 return d->currentTransformation->radiusUnit;
00306 }
00307
00308 void PolarCoordinatePlane::slotLayoutChanged ( AbstractDiagram* )
00309 {
00310 if ( d->initialResizeEventReceived ) layoutDiagrams();
00311 }
00312
00313 void PolarCoordinatePlane::setStartPosition( qreal degrees )
00314 {
00315 Q_ASSERT_X ( diagram(), "PolarCoordinatePlane::setStartPosition",
00316 "setStartPosition() needs a diagram to be associated to the plane." );
00317 d->coordinateTransformations[0].startPosition = degrees;
00318 }
00319
00320 qreal PolarCoordinatePlane::startPosition() const
00321 {
00322 return d->coordinateTransformations.size()
00323 ? d->coordinateTransformations[0].startPosition
00324 : 0.0;
00325 }
00326
00327 double PolarCoordinatePlane::zoomFactorX() const
00328 {
00329 return d->coordinateTransformations[0].zoom.xFactor;
00330 }
00331
00332 double PolarCoordinatePlane::zoomFactorY() const
00333 {
00334 return d->coordinateTransformations[0].zoom.yFactor;
00335 }
00336
00337 void PolarCoordinatePlane::setZoomFactorX( double factor )
00338 {
00339 d->coordinateTransformations[0].zoom.xFactor = factor;
00340 }
00341
00342 void PolarCoordinatePlane::setZoomFactorY( double factor )
00343 {
00344 d->coordinateTransformations[0].zoom.yFactor = factor;
00345 }
00346
00347 QPointF PolarCoordinatePlane::zoomCenter() const
00348 {
00349 return QPointF( d->coordinateTransformations[0].zoom.xCenter, d->coordinateTransformations[0].zoom.yCenter );
00350 }
00351
00352 void PolarCoordinatePlane::setZoomCenter( QPointF center )
00353 {
00354 d->coordinateTransformations[0].zoom.xCenter = center.x();
00355 d->coordinateTransformations[0].zoom.yCenter = center.y();
00356 }
00357
00358 DataDimensionsList PolarCoordinatePlane::getDataDimensionsList() const
00359 {
00360 DataDimensionsList l;
00361
00362
00363
00364 return l;
00365 }
00366
00367 void KDChart::PolarCoordinatePlane::setGridAttributes(
00368 bool circular,
00369 const GridAttributes& a )
00370 {
00371 if( circular )
00372 d->gridAttributesCircular = a;
00373 else
00374 d->gridAttributesSagittal = a;
00375 setHasOwnGridAttributes( circular, true );
00376 update();
00377 emit propertiesChanged();
00378 }
00379
00380 void KDChart::PolarCoordinatePlane::resetGridAttributes(
00381 bool circular )
00382 {
00383 setHasOwnGridAttributes( circular, false );
00384 update();
00385 }
00386
00387 const GridAttributes KDChart::PolarCoordinatePlane::gridAttributes(
00388 bool circular ) const
00389 {
00390 if( hasOwnGridAttributes( circular ) ){
00391 if( circular )
00392 return d->gridAttributesCircular;
00393 else
00394 return d->gridAttributesSagittal;
00395 }else{
00396 return globalGridAttributes();
00397 }
00398 }
00399
00400 void KDChart::PolarCoordinatePlane::setHasOwnGridAttributes(
00401 bool circular, bool on )
00402 {
00403 if( circular )
00404 d->hasOwnGridAttributesCircular = on;
00405 else
00406 d->hasOwnGridAttributesSagittal = on;
00407 emit propertiesChanged();
00408 }
00409
00410 bool KDChart::PolarCoordinatePlane::hasOwnGridAttributes(
00411 bool circular ) const
00412 {
00413 return
00414 ( circular )
00415 ? d->hasOwnGridAttributesCircular
00416 : d->hasOwnGridAttributesSagittal;
00417 }