QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
qgsdiagramrenderer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsdiagramrenderer.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 "qgsdiagramrenderer.h"
16 
18 #include "qgsvectorlayer.h"
19 #include "diagram/qgstextdiagram.h"
20 #include "diagram/qgspiediagram.h"
23 #include "qgsrendercontext.h"
25 #include "qgsfontutils.h"
26 #include "qgssymbollayerutils.h"
27 #include "qgspainteffectregistry.h"
28 #include "qgspainteffect.h"
29 #include "qgsapplication.h"
30 
31 #include <QDomElement>
32 #include <QPainter>
33 
34 QgsPropertiesDefinition QgsDiagramLayerSettings::sPropertyDefinitions;
35 
36 void QgsDiagramLayerSettings::initPropertyDefinitions()
37 {
38  if ( !sPropertyDefinitions.isEmpty() )
39  return;
40 
41  const QString origin = QStringLiteral( "diagram" );
42 
43  sPropertyDefinitions = QgsPropertiesDefinition
44  {
45  { QgsDiagramLayerSettings::BackgroundColor, QgsPropertyDefinition( "backgroundColor", QObject::tr( "Background color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
46  { QgsDiagramLayerSettings::StrokeColor, QgsPropertyDefinition( "strokeColor", QObject::tr( "Stroke color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
47  { QgsDiagramLayerSettings::StrokeWidth, QgsPropertyDefinition( "strokeWidth", QObject::tr( "Stroke width" ), QgsPropertyDefinition::StrokeWidth, origin ) },
48  { QgsDiagramLayerSettings::PositionX, QgsPropertyDefinition( "positionX", QObject::tr( "Position (X)" ), QgsPropertyDefinition::Double, origin ) },
49  { QgsDiagramLayerSettings::PositionY, QgsPropertyDefinition( "positionY", QObject::tr( "Position (Y)" ), QgsPropertyDefinition::Double, origin ) },
50  { QgsDiagramLayerSettings::Distance, QgsPropertyDefinition( "distance", QObject::tr( "Placement distance" ), QgsPropertyDefinition::DoublePositive, origin ) },
51  { QgsDiagramLayerSettings::Priority, QgsPropertyDefinition( "priority", QObject::tr( "Placement priority" ), QgsPropertyDefinition::DoublePositive, origin ) },
52  { QgsDiagramLayerSettings::ZIndex, QgsPropertyDefinition( "zIndex", QObject::tr( "Placement z-index" ), QgsPropertyDefinition::Double, origin ) },
53  { QgsDiagramLayerSettings::IsObstacle, QgsPropertyDefinition( "isObstacle", QObject::tr( "Diagram is an obstacle" ), QgsPropertyDefinition::Boolean, origin ) },
54  { QgsDiagramLayerSettings::Show, QgsPropertyDefinition( "show", QObject::tr( "Show diagram" ), QgsPropertyDefinition::Boolean, origin ) },
55  { QgsDiagramLayerSettings::AlwaysShow, QgsPropertyDefinition( "alwaysShow", QObject::tr( "Always show diagram" ), QgsPropertyDefinition::Boolean, origin ) },
56  { QgsDiagramLayerSettings::StartAngle, QgsPropertyDefinition( "startAngle", QObject::tr( "Pie chart start angle" ), QgsPropertyDefinition::Rotation, origin ) },
57  };
58 }
59 
61 {
62  initPropertyDefinitions();
63  return sPropertyDefinitions;
64 }
65 
67 {
68  initPropertyDefinitions();
69 }
70 
72  : mCt( rh.mCt )
73  , mPlacement( rh.mPlacement )
74  , mPlacementFlags( rh.mPlacementFlags )
75  , mPriority( rh.mPriority )
76  , mZIndex( rh.mZIndex )
77  , mObstacle( rh.mObstacle )
78  , mDistance( rh.mDistance )
79  , mRenderer( rh.mRenderer ? rh.mRenderer->clone() : nullptr )
80  , mShowAll( rh.mShowAll )
81  , mDataDefinedProperties( rh.mDataDefinedProperties )
82 {
83  initPropertyDefinitions();
84 }
85 
87 {
88  mPlacement = rh.mPlacement;
89  mPlacementFlags = rh.mPlacementFlags;
90  mPriority = rh.mPriority;
91  mZIndex = rh.mZIndex;
92  mObstacle = rh.mObstacle;
93  mDistance = rh.mDistance;
94  mRenderer = rh.mRenderer ? rh.mRenderer->clone() : nullptr;
95  mCt = rh.mCt;
96  mShowAll = rh.mShowAll;
97  mDataDefinedProperties = rh.mDataDefinedProperties;
98  return *this;
99 }
100 
102 {
103  delete mRenderer;
104 }
105 
107 {
108  if ( diagramRenderer == mRenderer )
109  return;
110 
111  delete mRenderer;
112  mRenderer = diagramRenderer;
113 }
114 
116 {
117  mCt = transform;
118 }
119 
120 void QgsDiagramLayerSettings::readXml( const QDomElement &elem )
121 {
122  QDomNodeList propertyElems = elem.elementsByTagName( QStringLiteral( "properties" ) );
123  if ( !propertyElems.isEmpty() )
124  {
125  ( void )mDataDefinedProperties.readXml( propertyElems.at( 0 ).toElement(), sPropertyDefinitions );
126  }
127  else
128  {
129  mDataDefinedProperties.clear();
130  }
131 
132  mPlacement = static_cast< Placement >( elem.attribute( QStringLiteral( "placement" ) ).toInt() );
133  mPlacementFlags = static_cast< LinePlacementFlag >( elem.attribute( QStringLiteral( "linePlacementFlags" ) ).toInt() );
134  mPriority = elem.attribute( QStringLiteral( "priority" ) ).toInt();
135  mZIndex = elem.attribute( QStringLiteral( "zIndex" ) ).toDouble();
136  mObstacle = elem.attribute( QStringLiteral( "obstacle" ) ).toInt();
137  mDistance = elem.attribute( QStringLiteral( "dist" ) ).toDouble();
138  mShowAll = ( elem.attribute( QStringLiteral( "showAll" ), QStringLiteral( "0" ) ) != QLatin1String( "0" ) );
139 }
140 
141 void QgsDiagramLayerSettings::writeXml( QDomElement &layerElem, QDomDocument &doc ) const
142 {
143  QDomElement diagramLayerElem = doc.createElement( QStringLiteral( "DiagramLayerSettings" ) );
144  QDomElement propertiesElem = doc.createElement( QStringLiteral( "properties" ) );
145  ( void )mDataDefinedProperties.writeXml( propertiesElem, sPropertyDefinitions );
146  diagramLayerElem.appendChild( propertiesElem );
147  diagramLayerElem.setAttribute( QStringLiteral( "placement" ), mPlacement );
148  diagramLayerElem.setAttribute( QStringLiteral( "linePlacementFlags" ), mPlacementFlags );
149  diagramLayerElem.setAttribute( QStringLiteral( "priority" ), mPriority );
150  diagramLayerElem.setAttribute( QStringLiteral( "zIndex" ), mZIndex );
151  diagramLayerElem.setAttribute( QStringLiteral( "obstacle" ), mObstacle );
152  diagramLayerElem.setAttribute( QStringLiteral( "dist" ), QString::number( mDistance ) );
153  diagramLayerElem.setAttribute( QStringLiteral( "showAll" ), mShowAll );
154  layerElem.appendChild( diagramLayerElem );
155 }
156 
158 {
159  return mDataDefinedProperties.prepare( context );
160 }
161 
163 {
164  QSet< QString > referenced;
165  if ( mRenderer )
166  referenced = mRenderer->referencedFields( context );
167 
168  //add the ones needed for data defined settings
169  referenced.unite( mDataDefinedProperties.referencedFields( context ) );
170 
171  return referenced;
172 }
173 
174 void QgsDiagramSettings::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
175 {
176  enabled = ( elem.attribute( QStringLiteral( "enabled" ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
177  if ( !QgsFontUtils::setFromXmlChildNode( font, elem, QStringLiteral( "fontProperties" ) ) )
178  {
179  font.fromString( elem.attribute( QStringLiteral( "font" ) ) );
180  }
181  backgroundColor.setNamedColor( elem.attribute( QStringLiteral( "backgroundColor" ) ) );
182  backgroundColor.setAlpha( elem.attribute( QStringLiteral( "backgroundAlpha" ) ).toInt() );
183  size.setWidth( elem.attribute( QStringLiteral( "width" ) ).toDouble() );
184  size.setHeight( elem.attribute( QStringLiteral( "height" ) ).toDouble() );
185  if ( elem.hasAttribute( QStringLiteral( "transparency" ) ) )
186  {
187  opacity = 1 - elem.attribute( QStringLiteral( "transparency" ), QStringLiteral( "0" ) ).toInt() / 255.0;
188  }
189  else
190  {
191  opacity = elem.attribute( QStringLiteral( "opacity" ), QStringLiteral( "1.00" ) ).toDouble();
192  }
193 
194  penColor.setNamedColor( elem.attribute( QStringLiteral( "penColor" ) ) );
195  int penAlpha = elem.attribute( QStringLiteral( "penAlpha" ), QStringLiteral( "255" ) ).toInt();
196  penColor.setAlpha( penAlpha );
197  penWidth = elem.attribute( QStringLiteral( "penWidth" ) ).toDouble();
198 
199  mDirection = static_cast< Direction >( elem.attribute( QStringLiteral( "direction" ), QStringLiteral( "1" ) ).toInt() );
200 
201  maximumScale = elem.attribute( QStringLiteral( "minScaleDenominator" ), QStringLiteral( "-1" ) ).toDouble();
202  minimumScale = elem.attribute( QStringLiteral( "maxScaleDenominator" ), QStringLiteral( "-1" ) ).toDouble();
203  if ( elem.hasAttribute( QStringLiteral( "scaleBasedVisibility" ) ) )
204  {
205  scaleBasedVisibility = ( elem.attribute( QStringLiteral( "scaleBasedVisibility" ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
206  }
207  else
208  {
210  }
211 
212  //diagram size unit type and scale
213  if ( elem.attribute( QStringLiteral( "sizeType" ) ) == QLatin1String( "MapUnits" ) )
214  {
215  //compatibility with pre-2.16 project files
217  }
218  else
219  {
220  sizeType = QgsUnitTypes::decodeRenderUnit( elem.attribute( QStringLiteral( "sizeType" ) ) );
221  }
222  sizeScale = QgsSymbolLayerUtils::decodeMapUnitScale( elem.attribute( QStringLiteral( "sizeScale" ) ) );
223 
224  //line width unit type and scale
225  lineSizeUnit = QgsUnitTypes::decodeRenderUnit( elem.attribute( QStringLiteral( "lineSizeType" ) ) );
226  lineSizeScale = QgsSymbolLayerUtils::decodeMapUnitScale( elem.attribute( QStringLiteral( "lineSizeScale" ) ) );
227 
228  mSpacing = elem.attribute( QStringLiteral( "spacing" ) ).toDouble();
229  mSpacingUnit = QgsUnitTypes::decodeRenderUnit( elem.attribute( QStringLiteral( "spacingUnit" ) ) );
230  mSpacingMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( elem.attribute( QStringLiteral( "spacingUnitScale" ) ) );
231 
232  //label placement method
233  if ( elem.attribute( QStringLiteral( "labelPlacementMethod" ) ) == QLatin1String( "Height" ) )
234  {
236  }
237  else
238  {
240  }
241 
242  // orientation
243  if ( elem.attribute( QStringLiteral( "diagramOrientation" ) ) == QLatin1String( "Left" ) )
244  {
246  }
247  else if ( elem.attribute( QStringLiteral( "diagramOrientation" ) ) == QLatin1String( "Right" ) )
248  {
250  }
251  else if ( elem.attribute( QStringLiteral( "diagramOrientation" ) ) == QLatin1String( "Down" ) )
252  {
254  }
255  else
256  {
258  }
259 
260  // scale dependency
261  if ( elem.attribute( QStringLiteral( "scaleDependency" ) ) == QLatin1String( "Diameter" ) )
262  {
263  scaleByArea = false;
264  }
265  else
266  {
267  scaleByArea = true;
268  }
269 
270  barWidth = elem.attribute( QStringLiteral( "barWidth" ) ).toDouble();
271 
272  if ( elem.hasAttribute( QStringLiteral( "angleOffset" ) ) )
273  rotationOffset = std::fmod( 360.0 - elem.attribute( QStringLiteral( "angleOffset" ) ).toInt() / 16.0, 360.0 );
274  else
275  rotationOffset = elem.attribute( QStringLiteral( "rotationOffset" ) ).toDouble();
276 
277  minimumSize = elem.attribute( QStringLiteral( "minimumSize" ) ).toDouble();
278 
279  QDomNodeList axisSymbolNodes = elem.elementsByTagName( QStringLiteral( "axisSymbol" ) );
280  if ( axisSymbolNodes.count() > 0 )
281  {
282  QDomElement axisSymbolElem = axisSymbolNodes.at( 0 ).toElement().firstChildElement();
283  mAxisLineSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( axisSymbolElem, context ) );
284  }
285  else
286  {
287  mAxisLineSymbol = qgis::make_unique< QgsLineSymbol >();
288  }
289 
290  mShowAxis = elem.attribute( QStringLiteral( "showAxis" ), QStringLiteral( "0" ) ).toInt();
291 
292  //colors
293  categoryColors.clear();
294  QDomNodeList attributes = elem.elementsByTagName( QStringLiteral( "attribute" ) );
295 
296 
297  if ( attributes.length() > 0 )
298  {
299  for ( int i = 0; i < attributes.size(); i++ )
300  {
301  QDomElement attrElem = attributes.at( i ).toElement();
302  QColor newColor( attrElem.attribute( QStringLiteral( "color" ) ) );
303  newColor.setAlphaF( opacity );
304  categoryColors.append( newColor );
305  categoryAttributes.append( attrElem.attribute( QStringLiteral( "field" ) ) );
306  categoryLabels.append( attrElem.attribute( QStringLiteral( "label" ) ) );
307  if ( categoryLabels.constLast().isEmpty() )
308  {
309  categoryLabels.back() = categoryAttributes.back();
310  }
311  }
312  }
313  else
314  {
315  // Restore old format attributes and colors
316 
317  QStringList colorList = elem.attribute( QStringLiteral( "colors" ) ).split( '/' );
318  QStringList::const_iterator colorIt = colorList.constBegin();
319  for ( ; colorIt != colorList.constEnd(); ++colorIt )
320  {
321  QColor newColor( *colorIt );
322  newColor.setAlphaF( opacity );
323  categoryColors.append( QColor( newColor ) );
324  }
325 
326  //attribute indices
327  categoryAttributes.clear();
328  QStringList catList = elem.attribute( QStringLiteral( "categories" ) ).split( '/' );
329  QStringList::const_iterator catIt = catList.constBegin();
330  for ( ; catIt != catList.constEnd(); ++catIt )
331  {
332  categoryAttributes.append( *catIt );
333  categoryLabels.append( *catIt );
334  }
335  }
336 
337  QDomElement effectElem = elem.firstChildElement( QStringLiteral( "effect" ) );
338  if ( !effectElem.isNull() )
339  setPaintEffect( QgsApplication::paintEffectRegistry()->createEffect( effectElem ) );
340  else
342 }
343 
344 void QgsDiagramSettings::writeXml( QDomElement &rendererElem, QDomDocument &doc, const QgsReadWriteContext &context ) const
345 {
346  QDomElement categoryElem = doc.createElement( QStringLiteral( "DiagramCategory" ) );
347  categoryElem.setAttribute( QStringLiteral( "enabled" ), enabled );
348  categoryElem.appendChild( QgsFontUtils::toXmlElement( font, doc, QStringLiteral( "fontProperties" ) ) );
349  categoryElem.setAttribute( QStringLiteral( "backgroundColor" ), backgroundColor.name() );
350  categoryElem.setAttribute( QStringLiteral( "backgroundAlpha" ), backgroundColor.alpha() );
351  categoryElem.setAttribute( QStringLiteral( "width" ), QString::number( size.width() ) );
352  categoryElem.setAttribute( QStringLiteral( "height" ), QString::number( size.height() ) );
353  categoryElem.setAttribute( QStringLiteral( "penColor" ), penColor.name() );
354  categoryElem.setAttribute( QStringLiteral( "penAlpha" ), penColor.alpha() );
355  categoryElem.setAttribute( QStringLiteral( "penWidth" ), QString::number( penWidth ) );
356  categoryElem.setAttribute( QStringLiteral( "scaleBasedVisibility" ), scaleBasedVisibility );
357  categoryElem.setAttribute( QStringLiteral( "minScaleDenominator" ), QString::number( maximumScale ) );
358  categoryElem.setAttribute( QStringLiteral( "maxScaleDenominator" ), QString::number( minimumScale ) );
359  categoryElem.setAttribute( QStringLiteral( "opacity" ), QString::number( opacity ) );
360  categoryElem.setAttribute( QStringLiteral( "spacing" ), QString::number( mSpacing ) );
361  categoryElem.setAttribute( QStringLiteral( "spacingUnit" ), QgsUnitTypes::encodeUnit( mSpacingUnit ) );
362  categoryElem.setAttribute( QStringLiteral( "spacingUnitScale" ), QgsSymbolLayerUtils::encodeMapUnitScale( mSpacingMapUnitScale ) );
363  categoryElem.setAttribute( QStringLiteral( "direction" ), QString::number( mDirection ) );
364 
365  //diagram size unit type and scale
366  categoryElem.setAttribute( QStringLiteral( "sizeType" ), QgsUnitTypes::encodeUnit( sizeType ) );
367  categoryElem.setAttribute( QStringLiteral( "sizeScale" ), QgsSymbolLayerUtils::encodeMapUnitScale( sizeScale ) );
368 
369  //line width unit type and scale
370  categoryElem.setAttribute( QStringLiteral( "lineSizeType" ), QgsUnitTypes::encodeUnit( lineSizeUnit ) );
371  categoryElem.setAttribute( QStringLiteral( "lineSizeScale" ), QgsSymbolLayerUtils::encodeMapUnitScale( lineSizeScale ) );
372 
373  // label placement method (text diagram)
374  if ( labelPlacementMethod == Height )
375  {
376  categoryElem.setAttribute( QStringLiteral( "labelPlacementMethod" ), QStringLiteral( "Height" ) );
377  }
378  else
379  {
380  categoryElem.setAttribute( QStringLiteral( "labelPlacementMethod" ), QStringLiteral( "XHeight" ) );
381  }
382 
383  if ( scaleByArea )
384  {
385  categoryElem.setAttribute( QStringLiteral( "scaleDependency" ), QStringLiteral( "Area" ) );
386  }
387  else
388  {
389  categoryElem.setAttribute( QStringLiteral( "scaleDependency" ), QStringLiteral( "Diameter" ) );
390  }
391 
392  // orientation (histogram)
393  switch ( diagramOrientation )
394  {
395  case Left:
396  categoryElem.setAttribute( QStringLiteral( "diagramOrientation" ), QStringLiteral( "Left" ) );
397  break;
398 
399  case Right:
400  categoryElem.setAttribute( QStringLiteral( "diagramOrientation" ), QStringLiteral( "Right" ) );
401  break;
402 
403  case Down:
404  categoryElem.setAttribute( QStringLiteral( "diagramOrientation" ), QStringLiteral( "Down" ) );
405  break;
406 
407  case Up:
408  categoryElem.setAttribute( QStringLiteral( "diagramOrientation" ), QStringLiteral( "Up" ) );
409  break;
410  }
411 
412  categoryElem.setAttribute( QStringLiteral( "barWidth" ), QString::number( barWidth ) );
413  categoryElem.setAttribute( QStringLiteral( "minimumSize" ), QString::number( minimumSize ) );
414  categoryElem.setAttribute( QStringLiteral( "rotationOffset" ), QString::number( rotationOffset ) );
415 
416  int nCats = std::min( categoryColors.size(), categoryAttributes.size() );
417  for ( int i = 0; i < nCats; ++i )
418  {
419  QDomElement attributeElem = doc.createElement( QStringLiteral( "attribute" ) );
420 
421  attributeElem.setAttribute( QStringLiteral( "field" ), categoryAttributes.at( i ) );
422  attributeElem.setAttribute( QStringLiteral( "color" ), categoryColors.at( i ).name() );
423  attributeElem.setAttribute( QStringLiteral( "label" ), categoryLabels.at( i ) );
424  categoryElem.appendChild( attributeElem );
425  }
426 
427  categoryElem.setAttribute( QStringLiteral( "showAxis" ), mShowAxis ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
428  QDomElement axisSymbolElem = doc.createElement( QStringLiteral( "axisSymbol" ) );
429  QDomElement symbolElem = QgsSymbolLayerUtils::saveSymbol( QString(), mAxisLineSymbol.get(), doc, context );
430  axisSymbolElem.appendChild( symbolElem );
431  categoryElem.appendChild( axisSymbolElem );
432 
433  if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect.get() ) )
434  mPaintEffect->saveProperties( doc, categoryElem );
435 
436  rendererElem.appendChild( categoryElem );
437 }
438 
440 {
441  if ( mDiagram.get() == d )
442  return;
443 
444  mDiagram.reset( d );
445 }
446 
448  : mDiagram( other.mDiagram ? other.mDiagram->clone() : nullptr )
449  , mShowAttributeLegend( other.mShowAttributeLegend )
450 {
451 }
452 
454 {
455  mDiagram.reset( other.mDiagram ? other.mDiagram->clone() : nullptr );
457  return *this;
458 }
459 
460 void QgsDiagramRenderer::renderDiagram( const QgsFeature &feature, QgsRenderContext &c, QPointF pos, const QgsPropertyCollection &properties ) const
461 {
462  if ( !mDiagram )
463  {
464  return;
465  }
466 
468  if ( !diagramSettings( feature, c, s ) )
469  {
470  return;
471  }
472 
473  if ( properties.hasActiveProperties() )
474  {
475  c.expressionContext().setOriginalValueVariable( QgsSymbolLayerUtils::encodeColor( s.backgroundColor ) );
477  c.expressionContext().setOriginalValueVariable( QgsSymbolLayerUtils::encodeColor( s.penColor ) );
478  s.penColor = properties.valueAsColor( QgsDiagramLayerSettings::StrokeColor, c.expressionContext(), s.penColor );
479  c.expressionContext().setOriginalValueVariable( s.penWidth );
480  s.penWidth = properties.valueAsDouble( QgsDiagramLayerSettings::StrokeWidth, c.expressionContext(), s.penWidth );
481  c.expressionContext().setOriginalValueVariable( s.rotationOffset );
482  s.rotationOffset = properties.valueAsDouble( QgsDiagramLayerSettings::StartAngle, c.expressionContext(), s.rotationOffset );
483  }
484 
485  QgsPaintEffect *effect = s.paintEffect();
486  std::unique_ptr< QgsEffectPainter > effectPainter;
487  if ( effect && effect->enabled() )
488  {
489  effectPainter = qgis::make_unique< QgsEffectPainter >( c, effect );
490  }
491 
492  mDiagram->renderDiagram( feature, c, s, pos );
493 }
494 
495 QSizeF QgsDiagramRenderer::sizeMapUnits( const QgsFeature &feature, const QgsRenderContext &c ) const
496 {
498  if ( !diagramSettings( feature, c, s ) )
499  {
500  return QSizeF();
501  }
502 
503  QSizeF size = diagramSize( feature, c );
504  if ( size.isValid() )
505  {
506  double width = c.convertToMapUnits( size.width(), s.sizeType, s.sizeScale );
507  size.rheight() *= width / size.width();
508  size.setWidth( width );
509  }
510  return size;
511 }
512 
513 QSet<QString> QgsDiagramRenderer::referencedFields( const QgsExpressionContext &context ) const
514 {
515  QSet< QString > referenced;
516 
517  if ( !mDiagram )
518  return referenced;
519 
520  const auto constDiagramAttributes = diagramAttributes();
521  for ( const QString &att : constDiagramAttributes )
522  {
523  QgsExpression *expression = mDiagram->getExpression( att, context );
524  const auto constReferencedColumns = expression->referencedColumns();
525  for ( const QString &field : constReferencedColumns )
526  {
527  referenced << field;
528  }
529  }
530  return referenced;
531 }
532 
533 void QgsDiagramRenderer::convertSizeToMapUnits( QSizeF &size, const QgsRenderContext &context ) const
534 {
535  if ( !size.isValid() )
536  {
537  return;
538  }
539 
540  double pixelToMap = context.scaleFactor() * context.mapToPixel().mapUnitsPerPixel();
541  size.rwidth() *= pixelToMap;
542  size.rheight() *= pixelToMap;
543 }
544 
545 int QgsDiagramRenderer::dpiPaintDevice( const QPainter *painter )
546 {
547  if ( painter )
548  {
549  QPaintDevice *device = painter->device();
550  if ( device )
551  {
552  return device->logicalDpiX();
553  }
554  }
555  return -1;
556 }
557 
558 void QgsDiagramRenderer::_readXml( const QDomElement &elem, const QgsReadWriteContext &context )
559 {
560  Q_UNUSED( context )
561  mDiagram.reset();
562  QString diagramType = elem.attribute( QStringLiteral( "diagramType" ) );
563  if ( diagramType == QLatin1String( "Pie" ) )
564  {
565  mDiagram.reset( new QgsPieDiagram() );
566  }
567  else if ( diagramType == QLatin1String( "Text" ) )
568  {
569  mDiagram.reset( new QgsTextDiagram() );
570  }
571  else if ( diagramType == QLatin1String( "Histogram" ) )
572  {
573  mDiagram.reset( new QgsHistogramDiagram() );
574  }
575  else if ( diagramType == QLatin1String( "Stacked" ) )
576  {
577  mDiagram.reset( new QgsStackedBarDiagram() );
578  }
579  else
580  {
581  // unknown diagram type -- default to histograms
582  mDiagram.reset( new QgsHistogramDiagram() );
583  }
584  mShowAttributeLegend = ( elem.attribute( QStringLiteral( "attributeLegend" ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
585 }
586 
587 void QgsDiagramRenderer::_writeXml( QDomElement &rendererElem, QDomDocument &doc, const QgsReadWriteContext &context ) const
588 {
589  Q_UNUSED( doc )
590  Q_UNUSED( context )
591 
592  if ( mDiagram )
593  {
594  rendererElem.setAttribute( QStringLiteral( "diagramType" ), mDiagram->diagramName() );
595  }
596  rendererElem.setAttribute( QStringLiteral( "attributeLegend" ), mShowAttributeLegend );
597 }
598 
600 {
601  return new QgsSingleCategoryDiagramRenderer( *this );
602 }
603 
605 {
606  Q_UNUSED( c )
607  s = mSettings;
608  return true;
609 }
610 
612 {
613  return mDiagram->diagramSize( feature.attributes(), c, mSettings );
614 }
615 
616 QList<QgsDiagramSettings> QgsSingleCategoryDiagramRenderer::diagramSettings() const
617 {
618  QList<QgsDiagramSettings> settingsList;
619  settingsList.push_back( mSettings );
620  return settingsList;
621 }
622 
623 void QgsSingleCategoryDiagramRenderer::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
624 {
625  QDomElement categoryElem = elem.firstChildElement( QStringLiteral( "DiagramCategory" ) );
626  if ( categoryElem.isNull() )
627  {
628  return;
629  }
630 
631  mSettings.readXml( categoryElem, context );
632  _readXml( elem, context );
633 }
634 
635 void QgsSingleCategoryDiagramRenderer::writeXml( QDomElement &layerElem, QDomDocument &doc, const QgsReadWriteContext &context ) const
636 {
637  QDomElement rendererElem = doc.createElement( QStringLiteral( "SingleCategoryDiagramRenderer" ) );
638  mSettings.writeXml( rendererElem, doc, context );
639  _writeXml( rendererElem, doc, context );
640  layerElem.appendChild( rendererElem );
641 }
642 
643 
645 {
646  mInterpolationSettings.classificationAttributeIsExpression = false;
647 }
648 
650  : QgsDiagramRenderer( other )
651  , mSettings( other.mSettings )
652  , mInterpolationSettings( other.mInterpolationSettings )
653  , mDataDefinedSizeLegend( other.mDataDefinedSizeLegend ? new QgsDataDefinedSizeLegend( *other.mDataDefinedSizeLegend ) : nullptr )
654 {
655 }
656 
658 {
659  delete mDataDefinedSizeLegend;
660 }
661 
663 {
664  return new QgsLinearlyInterpolatedDiagramRenderer( *this );
665 }
666 
668 {
669  QList<QgsDiagramSettings> settingsList;
670  settingsList.push_back( mSettings );
671  return settingsList;
672 }
673 
675 {
676  s = mSettings;
677  s.size = diagramSize( feature, c );
678  return true;
679 }
680 
682 {
683  return mSettings.categoryAttributes;
684 }
685 
687 {
688  QSet< QString > referenced = QgsDiagramRenderer::referencedFields( context );
689  if ( mInterpolationSettings.classificationAttributeIsExpression )
690  {
691  QgsExpression *expression = mDiagram->getExpression( mInterpolationSettings.classificationAttributeExpression, context );
692  const auto constReferencedColumns = expression->referencedColumns();
693  for ( const QString &field : constReferencedColumns )
694  {
695  referenced << field;
696  }
697  }
698  else
699  {
700  referenced << mInterpolationSettings.classificationField;
701  }
702  return referenced;
703 }
704 
706 {
707  return mDiagram->diagramSize( feature, c, mSettings, mInterpolationSettings );
708 }
709 
710 void QgsLinearlyInterpolatedDiagramRenderer::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
711 {
712  mInterpolationSettings.lowerValue = elem.attribute( QStringLiteral( "lowerValue" ) ).toDouble();
713  mInterpolationSettings.upperValue = elem.attribute( QStringLiteral( "upperValue" ) ).toDouble();
714  mInterpolationSettings.lowerSize.setWidth( elem.attribute( QStringLiteral( "lowerWidth" ) ).toDouble() );
715  mInterpolationSettings.lowerSize.setHeight( elem.attribute( QStringLiteral( "lowerHeight" ) ).toDouble() );
716  mInterpolationSettings.upperSize.setWidth( elem.attribute( QStringLiteral( "upperWidth" ) ).toDouble() );
717  mInterpolationSettings.upperSize.setHeight( elem.attribute( QStringLiteral( "upperHeight" ) ).toDouble() );
718  mInterpolationSettings.classificationAttributeIsExpression = elem.hasAttribute( QStringLiteral( "classificationAttributeExpression" ) );
719  if ( mInterpolationSettings.classificationAttributeIsExpression )
720  {
721  mInterpolationSettings.classificationAttributeExpression = elem.attribute( QStringLiteral( "classificationAttributeExpression" ) );
722  }
723  else
724  {
725  mInterpolationSettings.classificationField = elem.attribute( QStringLiteral( "classificationField" ) );
726  }
727  QDomElement settingsElem = elem.firstChildElement( QStringLiteral( "DiagramCategory" ) );
728  if ( !settingsElem.isNull() )
729  {
730  mSettings.readXml( settingsElem );
731  }
732 
733  delete mDataDefinedSizeLegend;
734 
735  QDomElement ddsLegendSizeElem = elem.firstChildElement( QStringLiteral( "data-defined-size-legend" ) );
736  if ( !ddsLegendSizeElem.isNull() )
737  {
738  mDataDefinedSizeLegend = QgsDataDefinedSizeLegend::readXml( ddsLegendSizeElem, context );
739  }
740  else
741  {
742  // pre-3.0 projects
743  if ( elem.attribute( QStringLiteral( "sizeLegend" ), QStringLiteral( "0" ) ) != QLatin1String( "0" ) )
744  {
745  mDataDefinedSizeLegend = new QgsDataDefinedSizeLegend();
746  QDomElement sizeLegendSymbolElem = elem.firstChildElement( QStringLiteral( "symbol" ) );
747  if ( !sizeLegendSymbolElem.isNull() && sizeLegendSymbolElem.attribute( QStringLiteral( "name" ) ) == QLatin1String( "sizeSymbol" ) )
748  {
749  mDataDefinedSizeLegend->setSymbol( QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( sizeLegendSymbolElem, context ) );
750  }
751  }
752  else
753  {
754  mDataDefinedSizeLegend = nullptr;
755  }
756  }
757 
758  _readXml( elem, context );
759 }
760 
761 void QgsLinearlyInterpolatedDiagramRenderer::writeXml( QDomElement &layerElem, QDomDocument &doc, const QgsReadWriteContext &context ) const
762 {
763  QDomElement rendererElem = doc.createElement( QStringLiteral( "LinearlyInterpolatedDiagramRenderer" ) );
764  rendererElem.setAttribute( QStringLiteral( "lowerValue" ), QString::number( mInterpolationSettings.lowerValue ) );
765  rendererElem.setAttribute( QStringLiteral( "upperValue" ), QString::number( mInterpolationSettings.upperValue ) );
766  rendererElem.setAttribute( QStringLiteral( "lowerWidth" ), QString::number( mInterpolationSettings.lowerSize.width() ) );
767  rendererElem.setAttribute( QStringLiteral( "lowerHeight" ), QString::number( mInterpolationSettings.lowerSize.height() ) );
768  rendererElem.setAttribute( QStringLiteral( "upperWidth" ), QString::number( mInterpolationSettings.upperSize.width() ) );
769  rendererElem.setAttribute( QStringLiteral( "upperHeight" ), QString::number( mInterpolationSettings.upperSize.height() ) );
770  if ( mInterpolationSettings.classificationAttributeIsExpression )
771  {
772  rendererElem.setAttribute( QStringLiteral( "classificationAttributeExpression" ), mInterpolationSettings.classificationAttributeExpression );
773  }
774  else
775  {
776  rendererElem.setAttribute( QStringLiteral( "classificationField" ), mInterpolationSettings.classificationField );
777  }
778  mSettings.writeXml( rendererElem, doc );
779 
780  if ( mDataDefinedSizeLegend )
781  {
782  QDomElement ddsLegendElem = doc.createElement( QStringLiteral( "data-defined-size-legend" ) );
783  mDataDefinedSizeLegend->writeXml( ddsLegendElem, context );
784  rendererElem.appendChild( ddsLegendElem );
785  }
786 
787  _writeXml( rendererElem, doc, context );
788  layerElem.appendChild( rendererElem );
789 }
790 
791 QList< QgsLayerTreeModelLegendNode * > QgsDiagramSettings::legendItems( QgsLayerTreeLayer *nodeLayer ) const
792 {
793  QList< QgsLayerTreeModelLegendNode * > list;
794  list.reserve( categoryLabels.size() );
795  for ( int i = 0; i < categoryLabels.size(); ++i )
796  {
797  QPixmap pix( 16, 16 );
798  pix.fill( categoryColors[i] );
799  list << new QgsSimpleLegendNode( nodeLayer, categoryLabels[i], QIcon( pix ), nullptr, QStringLiteral( "diagram_%1" ).arg( QString::number( i ) ) );
800  }
801  return list;
802 }
803 
805 {
806  return mAxisLineSymbol.get();
807 }
808 
810 {
811  if ( axisLineSymbol != mAxisLineSymbol.get() )
812  mAxisLineSymbol.reset( axisLineSymbol );
813 }
814 
816 {
817  return mShowAxis;
818 }
819 
820 void QgsDiagramSettings::setShowAxis( bool showAxis )
821 {
822  mShowAxis = showAxis;
823 }
824 
826 {
827  return mPaintEffect.get();
828 }
829 
831 {
832  if ( effect != mPaintEffect.get() )
833  mPaintEffect.reset( effect );
834 }
835 
837  : mAxisLineSymbol( qgis::make_unique< QgsLineSymbol >() )
838 {
839 }
840 
842 
844  : enabled( other.enabled )
845  , font( other.font )
846  , categoryColors( other.categoryColors )
847  , categoryAttributes( other.categoryAttributes )
848  , categoryLabels( other.categoryLabels )
849  , size( other.size )
850  , sizeType( other.sizeType )
851  , sizeScale( other.sizeScale )
852  , lineSizeUnit( other.lineSizeUnit )
853  , lineSizeScale( other.lineSizeScale )
854  , backgroundColor( other.backgroundColor )
855  , penColor( other.penColor )
856  , penWidth( other.penWidth )
857  , labelPlacementMethod( other.labelPlacementMethod )
858  , diagramOrientation( other.diagramOrientation )
859  , barWidth( other.barWidth )
860  , opacity( other.opacity )
861  , scaleByArea( other.scaleByArea )
862  , rotationOffset( other.rotationOffset )
863  , scaleBasedVisibility( other.scaleBasedVisibility )
864  , maximumScale( other.maximumScale )
865  , minimumScale( other.minimumScale )
866  , minimumSize( other.minimumSize )
867  , mSpacing( other.mSpacing )
868  , mSpacingUnit( other.mSpacingUnit )
869  , mSpacingMapUnitScale( other.mSpacingMapUnitScale )
870  , mDirection( other.mDirection )
871  , mShowAxis( other.mShowAxis )
872  , mAxisLineSymbol( other.mAxisLineSymbol ? other.mAxisLineSymbol->clone() : nullptr )
873  , mPaintEffect( other.mPaintEffect ? other.mPaintEffect->clone() : nullptr )
874 {
875 
876 }
877 
879 {
880  enabled = other.enabled;
881  font = other.font;
885  size = other.size;
886  sizeType = other.sizeType;
887  sizeScale = other.sizeScale;
888  lineSizeUnit = other.lineSizeUnit;
891  penColor = other.penColor;
892  penWidth = other.penWidth;
895  barWidth = other.barWidth;
896  opacity = other.opacity;
897  scaleByArea = other.scaleByArea;
900  maximumScale = other.maximumScale;
901  minimumScale = other.minimumScale;
902  minimumSize = other.minimumSize;
903  mSpacing = other.mSpacing;
904  mSpacingUnit = other.mSpacingUnit;
905  mSpacingMapUnitScale = other.mSpacingMapUnitScale;
906  mDirection = other.mDirection;
907  mAxisLineSymbol.reset( other.mAxisLineSymbol ? other.mAxisLineSymbol->clone() : nullptr );
908  mShowAxis = other.mShowAxis;
909  mPaintEffect.reset( other.mPaintEffect ? other.mPaintEffect->clone() : nullptr );
910  return *this;
911 }
912 
914 {
915  return mDirection;
916 }
917 
919 {
920  mDirection = direction;
921 }
922 
923 QList< QgsLayerTreeModelLegendNode * > QgsDiagramRenderer::legendItems( QgsLayerTreeLayer * ) const
924 {
925  return QList< QgsLayerTreeModelLegendNode * >();
926 }
927 
928 QList< QgsLayerTreeModelLegendNode * > QgsSingleCategoryDiagramRenderer::legendItems( QgsLayerTreeLayer *nodeLayer ) const
929 {
930  QList< QgsLayerTreeModelLegendNode * > nodes;
931  if ( mShowAttributeLegend )
932  nodes = mSettings.legendItems( nodeLayer );
933 
934  return nodes;
935 }
936 
937 QList< QgsLayerTreeModelLegendNode * > QgsLinearlyInterpolatedDiagramRenderer::legendItems( QgsLayerTreeLayer *nodeLayer ) const
938 {
939  QList< QgsLayerTreeModelLegendNode * > nodes;
940  if ( mShowAttributeLegend )
941  nodes = mSettings.legendItems( nodeLayer );
942 
943  if ( mDataDefinedSizeLegend && mDiagram )
944  {
945  // add size legend
946  QgsMarkerSymbol *legendSymbol = mDataDefinedSizeLegend->symbol() ? mDataDefinedSizeLegend->symbol()->clone() : QgsMarkerSymbol::createSimple( QVariantMap() );
947  legendSymbol->setSizeUnit( mSettings.sizeType );
948  legendSymbol->setSizeMapUnitScale( mSettings.sizeScale );
949 
950  QgsDataDefinedSizeLegend ddSizeLegend( *mDataDefinedSizeLegend );
951  ddSizeLegend.setSymbol( legendSymbol ); // transfers ownership
952 
953  QList<QgsDataDefinedSizeLegend::SizeClass> sizeClasses;
954  if ( ddSizeLegend.classes().isEmpty() )
955  {
956  // automatic class creation if the classes are not defined manually
957  const auto prettyBreaks { QgsSymbolLayerUtils::prettyBreaks( mInterpolationSettings.lowerValue, mInterpolationSettings.upperValue, 4 ) };
958  for ( double v : prettyBreaks )
959  {
960  double size = mDiagram->legendSize( v, mSettings, mInterpolationSettings );
961  sizeClasses << QgsDataDefinedSizeLegend::SizeClass( size, QString::number( v ) );
962  }
963  }
964  else
965  {
966  // manual classes need to get size scaled because the QgsSizeScaleTransformer is not used in diagrams :-(
967  const auto constClasses = ddSizeLegend.classes();
968  for ( const QgsDataDefinedSizeLegend::SizeClass &sc : constClasses )
969  {
970  double size = mDiagram->legendSize( sc.size, mSettings, mInterpolationSettings );
971  sizeClasses << QgsDataDefinedSizeLegend::SizeClass( size, sc.label );
972  }
973  }
974  ddSizeLegend.setClasses( sizeClasses );
975 
976  const auto constLegendSymbolList = ddSizeLegend.legendSymbolList();
977  for ( const QgsLegendSymbolItem &si : constLegendSymbolList )
978  {
979  if ( auto *lDataDefinedSizeLegendSettings = si.dataDefinedSizeLegendSettings() )
980  nodes << new QgsDataDefinedSizeLegendNode( nodeLayer, *lDataDefinedSizeLegendSettings );
981  else
982  nodes << new QgsSymbolLegendNode( nodeLayer, si );
983  }
984  }
985 
986  return nodes;
987 }
988 
990 {
991  delete mDataDefinedSizeLegend;
992  mDataDefinedSizeLegend = settings;
993 }
994 
996 {
997  return mDataDefinedSizeLegend;
998 }
QColor valueAsColor(int key, const QgsExpressionContext &context, const QColor &defaultColor=QColor(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a color.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double.
virtual bool readXml(const QDomElement &collectionElem, const QgsPropertiesDefinition &definitions)
Reads property collection state from an XML element.
virtual bool writeXml(QDomElement &collectionElem, const QgsPropertiesDefinition &definitions) const
Writes the current state of the property collection into an XML element.
static QgsPaintEffectRegistry * paintEffectRegistry()
Returns the application's paint effect registry, used for managing paint effects.
Class for doing transforms between two map coordinate systems.
Produces legend node with a marker symbol.
Object that keeps configuration of appearance of marker symbol's data-defined size in legend.
QList< QgsDataDefinedSizeLegend::SizeClass > classes() const
Returns list of classes: each class is a pair of symbol size (in units used by the symbol) and label.
void setSymbol(QgsMarkerSymbol *symbol SIP_TRANSFER)
Sets marker symbol that will be used to draw markers in legend.
QgsMarkerSymbol * symbol() const
Returns marker symbol that will be used to draw markers in legend.
void setClasses(const QList< QgsDataDefinedSizeLegend::SizeClass > &classes)
Sets list of classes: each class is a pair of symbol size (in units used by the symbol) and label.
static QgsDataDefinedSizeLegend * readXml(const QDomElement &elem, const QgsReadWriteContext &context) SIP_FACTORY
Creates instance from given element and returns it (caller takes ownership). Returns nullptr on error...
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const
Writes configuration to the given XML element.
QgsLegendSymbolList legendSymbolList() const
Generates legend symbol items according to the configuration.
QString classificationField
Name of the field for classification.
Stores the settings for rendering of all diagrams for a layer.
LinePlacementFlag
Line placement flags for controlling line based placements.
QgsDiagramLayerSettings & operator=(const QgsDiagramLayerSettings &rh)
@ StartAngle
Angle offset for pie diagram.
@ Distance
Distance to diagram from feature.
@ IsObstacle
Whether diagram features act as obstacles for other diagrams/labels.
@ PositionX
X-coordinate data defined diagram position.
@ Priority
Diagram priority (between 0 and 10)
@ AlwaysShow
Whether the diagram should always be shown, even if it overlaps other diagrams/labels.
@ Show
Whether to show the diagram.
@ ZIndex
Z-index for diagram ordering.
@ BackgroundColor
Diagram background color.
@ PositionY
Y-coordinate data defined diagram position.
void setRenderer(QgsDiagramRenderer *diagramRenderer)
Sets the diagram renderer associated with the layer.
void readXml(const QDomElement &elem)
Reads the diagram settings from a DOM element.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the diagram property definitions.
QgsDiagramLayerSettings()
Constructor for QgsDiagramLayerSettings.
QSet< QString > referencedFields(const QgsExpressionContext &context=QgsExpressionContext()) const
Returns the set of any fields referenced by the layer's diagrams.
void writeXml(QDomElement &layerElem, QDomDocument &doc) const
Writes the diagram settings to a DOM element.
bool prepare(const QgsExpressionContext &context=QgsExpressionContext()) const
Prepares the diagrams for a specified expression context.
void setCoordinateTransform(const QgsCoordinateTransform &transform)
Sets the coordinate transform associated with the layer.
Evaluates and returns the diagram settings relating to a diagram for a specific feature.
virtual QList< QgsLayerTreeModelLegendNode * > legendItems(QgsLayerTreeLayer *nodeLayer) const
Returns list of legend nodes for the diagram.
virtual QgsDiagramRenderer * clone() const =0
Returns new instance that is equivalent to this one.
virtual QList< QString > diagramAttributes() const =0
Returns attribute indices needed for diagram rendering.
virtual QSizeF diagramSize(const QgsFeature &features, const QgsRenderContext &c) const =0
Returns size of the diagram (in painter units) or an invalid size in case of error.
void _writeXml(QDomElement &rendererElem, QDomDocument &doc, const QgsReadWriteContext &context) const
Writes internal QgsDiagramRenderer diagram state to a DOM element.
virtual QSet< QString > referencedFields(const QgsExpressionContext &context=QgsExpressionContext()) const
Returns the set of any fields required for diagram rendering.
void renderDiagram(const QgsFeature &feature, QgsRenderContext &c, QPointF pos, const QgsPropertyCollection &properties=QgsPropertyCollection()) const
Renders the diagram for a specified feature at a specific position in the passed render context.
void _readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Reads internal QgsDiagramRenderer state from a DOM element.
QgsDiagramRenderer & operator=(const QgsDiagramRenderer &other)
virtual QSizeF sizeMapUnits(const QgsFeature &feature, const QgsRenderContext &c) const
Returns size of the diagram for a feature in map units. Returns an invalid QSizeF in case of error.
std::unique_ptr< QgsDiagram > mDiagram
Reference to the object that does the real diagram rendering.
void convertSizeToMapUnits(QSizeF &size, const QgsRenderContext &context) const
Converts size from mm to map units.
virtual QList< QgsDiagramSettings > diagramSettings() const =0
Returns list with all diagram settings in the renderer.
bool mShowAttributeLegend
Whether to show an attribute legend for the diagrams.
QgsDiagramRenderer()=default
Constructor for QgsDiagramRenderer.
void setDiagram(QgsDiagram *d)
static int dpiPaintDevice(const QPainter *)
Returns the paint device dpi (or -1 in case of error.
Stores the settings for rendering a single diagram.
QgsUnitTypes::RenderUnit sizeType
Diagram size unit.
Direction direction() const
Returns the chart's angular direction.
void setDirection(Direction direction)
Sets the chart's angular direction.
bool showAxis() const
Returns true if the diagram axis should be shown.
LabelPlacementMethod labelPlacementMethod
void readXml(const QDomElement &elem, const QgsReadWriteContext &context=QgsReadWriteContext())
Reads diagram settings from XML.
double opacity
Opacity, from 0 (transparent) to 1.0 (opaque)
QgsDiagramSettings & operator=(const QgsDiagramSettings &other)
QgsLineSymbol * axisLineSymbol() const
Returns the line symbol to use for rendering axis in diagrams.
QList< QString > categoryAttributes
QList< QString > categoryLabels
QgsDiagramSettings()
Constructor for QgsDiagramSettings.
DiagramOrientation diagramOrientation
QList< QgsLayerTreeModelLegendNode * > legendItems(QgsLayerTreeLayer *nodeLayer) const
Returns list of legend nodes for the diagram.
QgsMapUnitScale lineSizeScale
Line unit scale.
void writeXml(QDomElement &rendererElem, QDomDocument &doc, const QgsReadWriteContext &context=QgsReadWriteContext()) const
Writes diagram settings to XML.
QList< QColor > categoryColors
double rotationOffset
Rotation offset, in degrees clockwise from horizontal.
QgsMapUnitScale sizeScale
Diagram size unit scale.
double minimumScale
The minimum map scale (i.e.
double maximumScale
The maximum map scale (i.e.
void setAxisLineSymbol(QgsLineSymbol *symbol)
Sets the line symbol to use for rendering axis in diagrams.
QgsUnitTypes::RenderUnit lineSizeUnit
Line unit index.
double minimumSize
Scale diagrams smaller than mMinimumSize to mMinimumSize.
Direction
Angular directions.
void setShowAxis(bool showAxis)
Sets whether the diagram axis should be shown.
void setPaintEffect(QgsPaintEffect *effect)
Sets the paint effect to use while rendering diagrams.
QgsPaintEffect * paintEffect() const
Returns the paint effect to use while rendering diagrams.
Base class for all diagram types.
Definition: qgsdiagram.h:40
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Class for parsing and evaluation of expressions (formerly called "search strings").
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsAttributes attributes
Definition: qgsfeature.h:65
static bool setFromXmlChildNode(QFont &font, const QDomElement &element, const QString &childNode)
Sets the properties of a font to match the properties stored in an XML child node.
static QDomElement toXmlElement(const QFont &font, QDomDocument &document, const QString &elementName)
Returns a DOM element containing the properties of the font.
A histogram style diagram.
Layer tree node points to a map layer.
The class stores information about one class/rule of a vector layer renderer in a unified way that ca...
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgssymbol.h:1204
void setDataDefinedSizeLegend(QgsDataDefinedSizeLegend *settings)
Configures appearance of legend.
QSizeF diagramSize(const QgsFeature &, const QgsRenderContext &c) const override
Returns size of the diagram (in painter units) or an invalid size in case of error.
QList< QString > diagramAttributes() const override
Returns attribute indices needed for diagram rendering.
QSet< QString > referencedFields(const QgsExpressionContext &context=QgsExpressionContext()) const override
Returns the set of any fields required for diagram rendering.
QList< QgsDiagramSettings > diagramSettings() const override
Returns list with all diagram settings in the renderer.
void writeXml(QDomElement &layerElem, QDomDocument &doc, const QgsReadWriteContext &context) const override
Writes diagram state to a DOM element.
QgsLinearlyInterpolatedDiagramRenderer * clone() const override
Returns new instance that is equivalent to this one.
QList< QgsLayerTreeModelLegendNode * > legendItems(QgsLayerTreeLayer *nodeLayer) const override
Returns list of legend nodes for the diagram.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
Reads diagram state from a DOM element.
QgsDataDefinedSizeLegend * dataDefinedSizeLegend() const
Returns configuration of appearance of legend.
double mapUnitsPerPixel() const
Returns current map units per pixel.
A marker symbol type, for rendering Point and MultiPoint geometries.
Definition: qgssymbol.h:1004
static QgsMarkerSymbol * createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
Definition: qgssymbol.cpp:1556
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the size units for the whole symbol (including all symbol layers).
Definition: qgssymbol.cpp:1767
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the size map unit scale for the whole symbol (including all symbol layers).
Definition: qgssymbol.cpp:1805
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
Definition: qgssymbol.cpp:2036
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
Base class for visual effects which can be applied to QPicture drawings.
bool enabled() const
Returns whether the effect is enabled.
A pie chart diagram.
Definition: qgspiediagram.h:39
A grouped map of multiple QgsProperty objects, each referenced by a integer key value.
QSet< QString > referencedFields(const QgsExpressionContext &context=QgsExpressionContext(), bool ignoreContext=false) const override
Returns the set of any fields referenced by the active properties from the collection.
void clear() override
Removes all properties from the collection.
bool hasActiveProperties() const override
Returns true if the collection has any active properties, or false if all properties within the colle...
bool prepare(const QgsExpressionContext &context=QgsExpressionContext()) const override
Prepares the collection against a specified expression context.
Definition for a property.
Definition: qgsproperty.h:48
@ Double
Double value (including negative values)
Definition: qgsproperty.h:58
@ StrokeWidth
Line stroke width.
Definition: qgsproperty.h:73
@ Boolean
Boolean value.
Definition: qgsproperty.h:54
@ Rotation
Rotation (value between 0-360 degrees)
Definition: qgsproperty.h:61
@ ColorWithAlpha
Color with alpha channel.
Definition: qgsproperty.h:65
@ DoublePositive
Positive double value (including 0)
Definition: qgsproperty.h:59
The class is used as a container of context for various read/write operations on other objects.
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
Implementation of legend node interface for displaying arbitrary label with icon.
Renders the diagrams for all features with the same settings.
QSizeF diagramSize(const QgsFeature &, const QgsRenderContext &c) const override
Returns size of the diagram (in painter units) or an invalid size in case of error.
void writeXml(QDomElement &layerElem, QDomDocument &doc, const QgsReadWriteContext &context) const override
Writes diagram state to a DOM element.
QgsSingleCategoryDiagramRenderer * clone() const override
Returns new instance that is equivalent to this one.
QgsSingleCategoryDiagramRenderer()=default
Constructor for QgsSingleCategoryDiagramRenderer.
QList< QgsLayerTreeModelLegendNode * > legendItems(QgsLayerTreeLayer *nodeLayer) const override
Returns list of legend nodes for the diagram.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context) override
Reads diagram state from a DOM element.
QList< QgsDiagramSettings > diagramSettings() const override
Returns list with all diagram settings in the renderer.
A stacked bar chart diagram.
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static QList< double > prettyBreaks(double minimum, double maximum, int classes)
Computes a sequence of about 'classes' equally spaced round values which cover the range of values fr...
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static QString encodeColor(const QColor &color)
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
Implementation of legend node interface for displaying preview of vector symbols and their labels and...
A text based diagram.
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
@ RenderMapUnits
Map units.
Definition: qgsunittypes.h:169
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
const QgsField & field
Definition: qgsfield.h:472
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
Definition of one class for the legend.