QGIS API Documentation  master-6227475
src/core/diagram/qgspiediagram.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002     qgspiediagram.cpp
00003     ---------------------
00004     begin                : March 2011
00005     copyright            : (C) 2011 by Marco Hugentobler
00006     email                : marco dot hugentobler at sourcepole dot ch
00007  ***************************************************************************
00008  *                                                                         *
00009  *   This program is free software; you can redistribute it and/or modify  *
00010  *   it under the terms of the GNU General Public License as published by  *
00011  *   the Free Software Foundation; either version 2 of the License, or     *
00012  *   (at your option) any later version.                                   *
00013  *                                                                         *
00014  ***************************************************************************/
00015 #include "qgspiediagram.h"
00016 #include "qgsdiagramrendererv2.h"
00017 #include "qgsrendercontext.h"
00018 
00019 #include <QPainter>
00020 
00021 
00022 QgsPieDiagram::QgsPieDiagram()
00023 {
00024   mCategoryBrush.setStyle( Qt::SolidPattern );
00025   mPen.setStyle( Qt::SolidLine );
00026 }
00027 
00028 QgsPieDiagram::~QgsPieDiagram()
00029 {
00030 }
00031 
00032 QSizeF QgsPieDiagram::diagramSize( const QgsAttributes& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is )
00033 {
00034   Q_UNUSED( c );
00035   QVariant attrVal = attributes[is.classificationAttribute];
00036   if ( !attrVal.isValid() )
00037   {
00038     return QSizeF(); //zero size if attribute is missing
00039   }
00040 
00041   double scaledValue = attrVal.toDouble();
00042   double scaledLowerValue = is.lowerValue;
00043   double scaledUpperValue = is.upperValue;
00044   double scaledLowerSizeWidth = is.lowerSize.width();
00045   double scaledLowerSizeHeight = is.lowerSize.height();
00046   double scaledUpperSizeWidth = is.upperSize.width();
00047   double scaledUpperSizeHeight = is.upperSize.height();
00048 
00049   // interpolate the squared value if scale by area
00050   if ( s.scaleByArea )
00051   {
00052     scaledValue = sqrt( scaledValue );
00053     scaledLowerValue = sqrt( scaledLowerValue );
00054     scaledUpperValue = sqrt( scaledUpperValue );
00055     scaledLowerSizeWidth = sqrt( scaledLowerSizeWidth );
00056     scaledLowerSizeHeight = sqrt( scaledLowerSizeHeight );
00057     scaledUpperSizeWidth = sqrt( scaledUpperSizeWidth );
00058     scaledUpperSizeHeight = sqrt( scaledUpperSizeHeight );
00059   }
00060 
00061   //interpolate size
00062   double scaledRatio = ( scaledValue - scaledLowerValue ) / ( scaledUpperValue - scaledLowerValue );
00063 
00064   QSizeF size = QSizeF( is.upperSize.width() * scaledRatio + is.lowerSize.width() * ( 1 - scaledRatio ),
00065                         is.upperSize.height() * scaledRatio + is.lowerSize.height() * ( 1 - scaledRatio ) );
00066 
00067   // Scale, if extension is smaller than the specified minimum
00068   if ( size.width() <= s.minimumSize && size.height() <= s.minimumSize )
00069   {
00070     size.scale( s.minimumSize, s.minimumSize, Qt::KeepAspectRatio );
00071   }
00072 
00073   return size;
00074 }
00075 
00076 QSizeF QgsPieDiagram::diagramSize( const QgsAttributes& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s )
00077 {
00078   Q_UNUSED( c );
00079   Q_UNUSED( attributes );
00080   return s.size;
00081 }
00082 
00083 int  QgsPieDiagram::sCount = 0;
00084 
00085 void QgsPieDiagram::renderDiagram( const QgsAttributes& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position )
00086 {
00087   QPainter* p = c.painter();
00088   if ( !p )
00089   {
00090     return;
00091   }
00092 
00093   //get sum of values
00094   QList<double> values;
00095   double currentVal = 0;
00096   double valSum = 0;
00097   int valCount = 0;
00098 
00099   QList<int>::const_iterator catIt = s.categoryIndices.constBegin();
00100   for ( ; catIt != s.categoryIndices.constEnd(); ++catIt )
00101   {
00102     currentVal = att[*catIt].toDouble();
00103     values.push_back( currentVal );
00104     valSum += currentVal;
00105     if ( currentVal ) valCount++;
00106   }
00107 
00108   //draw the slices
00109   double totalAngle = 0;
00110   double currentAngle;
00111 
00112   //convert from mm / map units to painter units
00113   QSizeF spu = sizePainterUnits( s.size, s, c );
00114   double w = spu.width();
00115   double h = spu.height();
00116 
00117   double baseX = position.x();
00118   double baseY = position.y() - h;
00119 
00120   mPen.setColor( s.penColor );
00121   setPenWidth( mPen, s, c );
00122   p->setPen( mPen );
00123 
00124   // there are some values > 0 available
00125   if ( valSum > 0 )
00126   {
00127     QList<double>::const_iterator valIt = values.constBegin();
00128     QList< QColor >::const_iterator colIt = s.categoryColors.constBegin();
00129     for ( ; valIt != values.constEnd(); ++valIt, ++colIt )
00130     {
00131       currentAngle = *valIt / valSum * 360 * 16;
00132       mCategoryBrush.setColor( *colIt );
00133       p->setBrush( mCategoryBrush );
00134       // if only 1 value is > 0, draw a circle
00135       if ( valCount == 1 )
00136       {
00137         p->drawEllipse( baseX, baseY, w, h );
00138       }
00139       else
00140       {
00141         p->drawPie( baseX, baseY, w, h, totalAngle + s.angleOffset, currentAngle );
00142       }
00143       totalAngle += currentAngle;
00144     }
00145   }
00146   else // valSum > 0
00147   {
00148     // draw empty circle if no values are defined at all
00149     mCategoryBrush.setColor( Qt::transparent );
00150     p->setBrush( mCategoryBrush );
00151     p->drawEllipse( baseX, baseY, w, h );
00152   }
00153 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines