QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
17#include "qgsdiagramrenderer.h"
18#include "qgsexpression.h"
19#include "qgsrendercontext.h"
20
21#include <QPainter>
22
23const QString QgsPieDiagram::DIAGRAM_NAME_PIE = QStringLiteral( "Pie" );
24
26{
27 mCategoryBrush.setStyle( Qt::SolidPattern );
28 mPen.setStyle( Qt::SolidLine );
29}
30
32{
33 return new QgsPieDiagram( *this );
34}
35
37{
38 Q_UNUSED( c )
39
40 QVariant attrVal;
42 {
43 QgsExpressionContext expressionContext = c.expressionContext();
44 if ( !feature.fields().isEmpty() )
45 expressionContext.setFields( feature.fields() );
46 expressionContext.setFeature( feature );
47
48 QgsExpression *expression = getExpression( is.classificationAttributeExpression, expressionContext );
49 attrVal = expression->evaluate( &expressionContext );
50 }
51 else
52 {
53 attrVal = feature.attribute( is.classificationField );
54 }
55
56 bool ok = false;
57 const double value = attrVal.toDouble( &ok );
58 if ( !ok )
59 {
60 return QSizeF(); //zero size if attribute is missing
61 }
62
63 return sizeForValue( value, s, is );
64}
65
66double QgsPieDiagram::legendSize( double value, const QgsDiagramSettings &s, const QgsDiagramInterpolationSettings &is ) const
67{
68 const QSizeF size = sizeForValue( value, s, is );
69 return std::max( size.width(), size.height() );
70}
71
76
78{
79 Q_UNUSED( c )
80 Q_UNUSED( attributes )
81 return s.size;
82}
83
84void QgsPieDiagram::renderDiagram( const QgsFeature &feature, QgsRenderContext &c, const QgsDiagramSettings &s, QPointF position )
85{
86 QPainter *p = c.painter();
87 if ( !p )
88 {
89 return;
90 }
91
92 //get sum of values
93 QList<double> values;
94 double currentVal = 0;
95 double valSum = 0;
96 int valCount = 0;
97
98 QgsExpressionContext expressionContext = c.expressionContext();
99 expressionContext.setFeature( feature );
100 if ( !feature.fields().isEmpty() )
101 expressionContext.setFields( feature.fields() );
102
103 QList<QString>::const_iterator catIt = s.categoryAttributes.constBegin();
104 for ( ; catIt != s.categoryAttributes.constEnd(); ++catIt )
105 {
106 QgsExpression *expression = getExpression( *catIt, expressionContext );
107 currentVal = expression->evaluate( &expressionContext ).toDouble();
108 values.push_back( currentVal );
109 valSum += currentVal;
110 if ( currentVal ) valCount++;
111 }
112
113 //draw the slices
114 double totalAngle = 0;
115 double currentAngle;
116
117 //convert from mm / map units to painter units
118 const QSizeF spu = sizePainterUnits( s.size, s, c );
119 const double w = spu.width();
120 const double h = spu.height();
121
122 const double baseX = position.x();
123 const double baseY = position.y() - h;
124
125 mPen.setColor( s.penColor );
126 setPenWidth( mPen, s, c );
127 p->setPen( mPen );
128
129 // there are some values > 0 available
130 if ( valSum > 0 )
131 {
132 QList<double>::const_iterator valIt = values.constBegin();
133 QList< QColor >::const_iterator colIt = s.categoryColors.constBegin();
134 for ( ; valIt != values.constEnd(); ++valIt, ++colIt )
135 {
136 if ( *valIt )
137 {
138 currentAngle = ( *valIt / valSum * 360 * 16 ) * ( s.direction() == QgsDiagramSettings::Clockwise ? -1 : 1 );
139 QColor brushColor( *colIt );
140 brushColor.setAlphaF( brushColor.alphaF() * s.opacity );
141 mCategoryBrush.setColor( brushColor );
142 p->setBrush( mCategoryBrush );
143 // if only 1 value is > 0, draw a circle
144 if ( valCount == 1 )
145 {
146 p->drawEllipse( QRectF( baseX, baseY, w, h ) );
147 }
148 else
149 {
150 p->drawPie( QRectF( baseX, baseY, w, h ), totalAngle - s.rotationOffset * 16.0, currentAngle );
151 }
152 totalAngle += currentAngle;
153 }
154 }
155 }
156 else // valSum > 0
157 {
158 // draw empty circle if no values are defined at all
159 mCategoryBrush.setColor( Qt::transparent );
160 p->setBrush( mCategoryBrush );
161 p->drawEllipse( QRectF( baseX, baseY, w, h ) );
162 }
163}
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.
Handles 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
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