QGIS API Documentation 3.39.0-Master (0c9320c8adc)
Loading...
Searching...
No Matches
qgspiediagram.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgspiediagram.cpp
3 ---------------------
4 begin : March 2011
5 copyright : (C) 2011 by Marco Hugentobler
6 email : marco dot hugentobler at sourcepole dot ch
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15#include "qgspiediagram.h"
16#include "qgsdiagramrenderer.h"
17#include "qgsrendercontext.h"
18#include "qgsexpression.h"
19
20#include <QPainter>
21
22const QString QgsPieDiagram::DIAGRAM_NAME_PIE = QStringLiteral( "Pie" );
23
25{
26 mCategoryBrush.setStyle( Qt::SolidPattern );
27 mPen.setStyle( Qt::SolidLine );
28}
29
31{
32 return new QgsPieDiagram( *this );
33}
34
36{
37 Q_UNUSED( c )
38
39 QVariant attrVal;
41 {
42 QgsExpressionContext expressionContext = c.expressionContext();
43 if ( !feature.fields().isEmpty() )
44 expressionContext.setFields( feature.fields() );
45 expressionContext.setFeature( feature );
46
47 QgsExpression *expression = getExpression( is.classificationAttributeExpression, expressionContext );
48 attrVal = expression->evaluate( &expressionContext );
49 }
50 else
51 {
52 attrVal = feature.attribute( is.classificationField );
53 }
54
55 bool ok = false;
56 const double value = attrVal.toDouble( &ok );
57 if ( !ok )
58 {
59 return QSizeF(); //zero size if attribute is missing
60 }
61
62 return sizeForValue( value, s, is );
63}
64
65double QgsPieDiagram::legendSize( double value, const QgsDiagramSettings &s, const QgsDiagramInterpolationSettings &is ) const
66{
67 const QSizeF size = sizeForValue( value, s, is );
68 return std::max( size.width(), size.height() );
69}
70
75
77{
78 Q_UNUSED( c )
79 Q_UNUSED( attributes )
80 return s.size;
81}
82
83void QgsPieDiagram::renderDiagram( const QgsFeature &feature, QgsRenderContext &c, const QgsDiagramSettings &s, QPointF position )
84{
85 QPainter *p = c.painter();
86 if ( !p )
87 {
88 return;
89 }
90
91 //get sum of values
92 QList<double> values;
93 double currentVal = 0;
94 double valSum = 0;
95 int valCount = 0;
96
97 QgsExpressionContext expressionContext = c.expressionContext();
98 expressionContext.setFeature( feature );
99 if ( !feature.fields().isEmpty() )
100 expressionContext.setFields( feature.fields() );
101
102 QList<QString>::const_iterator catIt = s.categoryAttributes.constBegin();
103 for ( ; catIt != s.categoryAttributes.constEnd(); ++catIt )
104 {
105 QgsExpression *expression = getExpression( *catIt, expressionContext );
106 currentVal = expression->evaluate( &expressionContext ).toDouble();
107 values.push_back( currentVal );
108 valSum += currentVal;
109 if ( currentVal ) valCount++;
110 }
111
112 //draw the slices
113 double totalAngle = 0;
114 double currentAngle;
115
116 //convert from mm / map units to painter units
117 const QSizeF spu = sizePainterUnits( s.size, s, c );
118 const double w = spu.width();
119 const double h = spu.height();
120
121 const double baseX = position.x();
122 const double baseY = position.y() - h;
123
124 mPen.setColor( s.penColor );
125 setPenWidth( mPen, s, c );
126 p->setPen( mPen );
127
128 // there are some values > 0 available
129 if ( valSum > 0 )
130 {
131 QList<double>::const_iterator valIt = values.constBegin();
132 QList< QColor >::const_iterator colIt = s.categoryColors.constBegin();
133 for ( ; valIt != values.constEnd(); ++valIt, ++colIt )
134 {
135 if ( *valIt )
136 {
137 currentAngle = ( *valIt / valSum * 360 * 16 ) * ( s.direction() == QgsDiagramSettings::Clockwise ? -1 : 1 );
138 QColor brushColor( *colIt );
139 brushColor.setAlphaF( brushColor.alphaF() * s.opacity );
140 mCategoryBrush.setColor( brushColor );
141 p->setBrush( mCategoryBrush );
142 // if only 1 value is > 0, draw a circle
143 if ( valCount == 1 )
144 {
145 p->drawEllipse( QRectF( baseX, baseY, w, h ) );
146 }
147 else
148 {
149 p->drawPie( QRectF( baseX, baseY, w, h ), totalAngle - s.rotationOffset * 16.0, currentAngle );
150 }
151 totalAngle += currentAngle;
152 }
153 }
154 }
155 else // valSum > 0
156 {
157 // draw empty circle if no values are defined at all
158 mCategoryBrush.setColor( Qt::transparent );
159 p->setBrush( mCategoryBrush );
160 p->drawEllipse( QRectF( baseX, baseY, w, h ) );
161 }
162}
A vector of attributes.
Additional diagram settings for interpolated size rendering.
QString classificationField
Name of the field for classification.
Stores the settings for rendering a single diagram.
Direction direction() const
Returns the chart's angular direction.
double opacity
Opacity, from 0 (transparent) to 1.0 (opaque)
QList< QString > categoryAttributes
QList< QColor > categoryColors
double rotationOffset
Rotation offset, in degrees clockwise from horizontal.
@ Clockwise
Clockwise orientation.
void setPenWidth(QPen &pen, const QgsDiagramSettings &s, const QgsRenderContext &c)
Changes the pen width to match the current settings and rendering context.
QSizeF sizePainterUnits(QSizeF size, const QgsDiagramSettings &s, const QgsRenderContext &c)
Calculates a size to match the current settings and rendering context.
QgsExpression * getExpression(const QString &expression, const QgsExpressionContext &context)
Returns a prepared expression for the specified context.
QSizeF sizeForValue(double value, const QgsDiagramSettings &s, const QgsDiagramInterpolationSettings &interpolationSettings) const
Returns the scaled size of a diagram for a value, respecting the specified diagram interpolation sett...
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
void setFields(const QgsFields &fields)
Convenience function for setting a fields for the context.
Class for parsing and evaluation of expressions (formerly called "search strings").
QVariant evaluate()
Evaluate the feature and return the result.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
QgsFields fields
Definition qgsfeature.h:68
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
bool isEmpty
Definition qgsfields.h:49
A pie chart diagram.
QSizeF diagramSize(const QgsAttributes &attributes, const QgsRenderContext &c, const QgsDiagramSettings &s) override
Returns the size in map units the diagram will use to render.
static const QString DIAGRAM_NAME_PIE
QgsPieDiagram * clone() const override
Returns an instance that is equivalent to this one.
void renderDiagram(const QgsFeature &feature, QgsRenderContext &c, const QgsDiagramSettings &s, QPointF position) override
Draws the diagram at the given position (in pixel coordinates)
QString diagramName() const override
Gets a descriptive name for this diagram type.
double legendSize(double value, const QgsDiagramSettings &s, const QgsDiagramInterpolationSettings &interpolationSettings) const override
Returns the size of the legend item for the diagram corresponding to a specified value.
Contains information about the context of a rendering operation.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c