QGIS API Documentation  2.7.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
qgshistogramdiagram.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgshistogramdiagram.cpp
3  ---------------------
4  begin : August 2012
5  copyright : (C) 2012 by Matthias Kuhn
6  email : matthias dot kuhn at gmx 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 "qgshistogramdiagram.h"
16 #include "qgsdiagramrendererv2.h"
17 #include "qgsrendercontext.h"
18 #include "qgsexpression.h"
19 
20 #include <QPainter>
21 
23 {
24  mCategoryBrush.setStyle( Qt::SolidPattern );
25  mPen.setStyle( Qt::SolidLine );
26  mScaleFactor = 0;
27 }
28 
30 {
31 }
32 
34 {
35  return new QgsHistogramDiagram( *this );
36 }
37 
39 {
40  Q_UNUSED( c );
41  QSizeF size;
42  if ( feature.attributes().count() == 0 )
43  {
44  return size; //zero size if no attributes
45  }
46 
47  if ( is.upperValue - is.lowerValue == 0 )
48  return size; // invalid value range => zero size
49 
50  double maxValue = 0;
51 
52  foreach ( QString cat, s.categoryAttributes )
53  {
54  QgsExpression* expression = getExpression( cat, feature.fields() );
55  maxValue = qMax( expression->evaluate( feature ).toDouble(), maxValue );
56  }
57 
58  // Scale, if extension is smaller than the specified minimum
59  if ( maxValue < s.minimumSize )
60  {
61  maxValue = s.minimumSize;
62  }
63 
64  switch ( s.diagramOrientation )
65  {
68  mScaleFactor = (( is.upperSize.width() - is.lowerSize.height() ) / ( is.upperValue - is.lowerValue ) );
69  size.scale( s.barWidth * s.categoryAttributes.size(), maxValue * mScaleFactor, Qt::IgnoreAspectRatio );
70  break;
71 
74  mScaleFactor = (( is.upperSize.width() - is.lowerSize.width() ) / ( is.upperValue - is.lowerValue ) );
75  size.scale( maxValue * mScaleFactor, s.barWidth * s.categoryAttributes.size(), Qt::IgnoreAspectRatio );
76  break;
77  }
78 
79  return size;
80 }
81 
83 {
84  Q_UNUSED( c );
85  QSizeF size;
86 
87  if ( attributes.count() == 0 )
88  {
89  return QSizeF(); //zero size if no attributes
90  }
91 
92  double maxValue = attributes[0].toDouble();
93 
94  for ( int i = 0; i < attributes.count(); ++i )
95  {
96  maxValue = qMax( attributes[i].toDouble(), maxValue );
97  }
98 
99  switch ( s.diagramOrientation )
100  {
103  mScaleFactor = maxValue / s.size.height();
104  size.scale( s.barWidth * s.categoryColors.size(), s.size.height(), Qt::IgnoreAspectRatio );
105  break;
106 
109  default: // just in case...
110  mScaleFactor = maxValue / s.size.width();
111  size.scale( s.size.width(), s.barWidth * s.categoryColors.size(), Qt::IgnoreAspectRatio );
112  break;
113  }
114 
115  return size;
116 }
117 
118 void QgsHistogramDiagram::renderDiagram( const QgsFeature& feature, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position )
119 {
120  QPainter* p = c.painter();
121  if ( !p )
122  {
123  return;
124  }
125 
126  QList<double> values;
127  double maxValue = 0;
128 
129  foreach ( QString cat, s.categoryAttributes )
130  {
131  QgsExpression* expression = getExpression( cat, feature.fields() );
132  double currentVal = expression->evaluate( feature ).toDouble();
133  values.push_back( currentVal );
134  maxValue = qMax( currentVal, maxValue );
135  }
136 
137  double scaledMaxVal = sizePainterUnits( maxValue * mScaleFactor, s, c );
138 
139  double currentOffset = 0;
140  double scaledWidth = sizePainterUnits( s.barWidth, s, c );
141 
142  double baseX = position.x();
143  double baseY = position.y();
144 
145  mPen.setColor( s.penColor );
146  setPenWidth( mPen, s, c );
147  p->setPen( mPen );
148 
149  QList<double>::const_iterator valIt = values.constBegin();
150  QList< QColor >::const_iterator colIt = s.categoryColors.constBegin();
151  for ( ; valIt != values.constEnd(); ++valIt, ++colIt )
152  {
153  double length = sizePainterUnits( *valIt * mScaleFactor, s, c );
154 
155  mCategoryBrush.setColor( *colIt );
156  p->setBrush( mCategoryBrush );
157 
158  switch ( s.diagramOrientation )
159  {
161  p->drawRect( baseX + currentOffset, baseY, scaledWidth, length * -1 );
162  break;
163 
165  p->drawRect( baseX + currentOffset, baseY - scaledMaxVal, scaledWidth, length );
166  break;
167 
169  p->drawRect( baseX, baseY - currentOffset, length, scaledWidth * -1 );
170  break;
171 
173  p->drawRect( baseX + scaledMaxVal, baseY - currentOffset, 0 - length, scaledWidth * -1 );
174  break;
175  }
176 
177  currentOffset += scaledWidth;
178  }
179 }
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:87
double minimumSize
Scale diagrams smaller than mMinimumSize to mMinimumSize.
virtual QgsDiagram * clone() const
Returns an instance that is equivalent to this one.
QVariant evaluate(const QgsFeature *f=NULL)
Evaluate the feature and return the result.
QList< QString > categoryAttributes
QgsExpression * getExpression(const QString &expression, const QgsFields *fields)
Definition: qgsdiagram.cpp:47
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:113
QSizeF sizePainterUnits(const QSizeF &size, const QgsDiagramSettings &s, const QgsRenderContext &c)
Calculates a size to match the current settings and rendering context.
Definition: qgsdiagram.cpp:71
QSizeF diagramSize(const QgsAttributes &attributes, const QgsRenderContext &c, const QgsDiagramSettings &s)
Returns the size in map units the diagram will use to render.
void renderDiagram(const QgsFeature &feature, QgsRenderContext &c, const QgsDiagramSettings &s, const QPointF &position)
Draws the diagram at the given position (in pixel coordinates)
DiagramOrientation diagramOrientation
const QgsFields * fields() const
Get associated field map.
Definition: qgsfeature.h:231
const QgsAttributes & attributes() const
Definition: qgsfeature.h:142
Base class for all diagram types.
Definition: qgsdiagram.h:34
Contains information about the context of a rendering operation.
QPainter * painter()
QVector< QVariant > QgsAttributes
Definition: qgsfeature.h:100
void setPenWidth(QPen &pen, const QgsDiagramSettings &s, const QgsRenderContext &c)
Changes the pen width to match the current settings and rendering context.
Definition: qgsdiagram.cpp:58
double size
Definition: qgssvgcache.cpp:77
QList< QColor > categoryColors