QGIS API Documentation 3.36.0-Maidenhead (09951dc0acf)
Loading...
Searching...
No Matches
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
17#include "qgscolorutils.h"
23#include "qgsrendercontext.h"
25#include "qgsfontutils.h"
26#include "qgssymbollayerutils.h"
28#include "qgspainteffect.h"
29#include "qgsapplication.h"
30#include "qgslinesymbol.h"
31#include "qgsmarkersymbol.h"
32#include "qgsunittypes.h"
33
34#include <QDomElement>
35#include <QPainter>
36
37QgsPropertiesDefinition QgsDiagramLayerSettings::sPropertyDefinitions;
38
39void QgsDiagramLayerSettings::initPropertyDefinitions()
40{
41 if ( !sPropertyDefinitions.isEmpty() )
42 return;
43
44 const QString origin = QStringLiteral( "diagram" );
45
46 sPropertyDefinitions = QgsPropertiesDefinition
47 {
48 { static_cast< int >( QgsDiagramLayerSettings::Property::BackgroundColor ), QgsPropertyDefinition( "backgroundColor", QObject::tr( "Background color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
49 { static_cast< int >( QgsDiagramLayerSettings::Property::StrokeColor ), QgsPropertyDefinition( "strokeColor", QObject::tr( "Stroke color" ), QgsPropertyDefinition::ColorWithAlpha, origin ) },
50 { static_cast< int >( QgsDiagramLayerSettings::Property::StrokeWidth ), QgsPropertyDefinition( "strokeWidth", QObject::tr( "Stroke width" ), QgsPropertyDefinition::StrokeWidth, origin ) },
51 { static_cast< int >( QgsDiagramLayerSettings::Property::PositionX ), QgsPropertyDefinition( "positionX", QObject::tr( "Position (X)" ), QgsPropertyDefinition::Double, origin ) },
52 { static_cast< int >( QgsDiagramLayerSettings::Property::PositionY ), QgsPropertyDefinition( "positionY", QObject::tr( "Position (Y)" ), QgsPropertyDefinition::Double, origin ) },
53 { static_cast< int >( QgsDiagramLayerSettings::Property::Distance ), QgsPropertyDefinition( "distance", QObject::tr( "Placement distance" ), QgsPropertyDefinition::DoublePositive, origin ) },
54 { static_cast< int >( QgsDiagramLayerSettings::Property::Priority ), QgsPropertyDefinition( "priority", QObject::tr( "Placement priority" ), QgsPropertyDefinition::DoublePositive, origin ) },
55 { static_cast< int >( QgsDiagramLayerSettings::Property::ZIndex ), QgsPropertyDefinition( "zIndex", QObject::tr( "Placement z-index" ), QgsPropertyDefinition::Double, origin ) },
56 { static_cast< int >( QgsDiagramLayerSettings::Property::IsObstacle ), QgsPropertyDefinition( "isObstacle", QObject::tr( "Diagram is an obstacle" ), QgsPropertyDefinition::Boolean, origin ) },
57 { static_cast< int >( QgsDiagramLayerSettings::Property::Show ), QgsPropertyDefinition( "show", QObject::tr( "Show diagram" ), QgsPropertyDefinition::Boolean, origin ) },
58 { static_cast< int >( QgsDiagramLayerSettings::Property::AlwaysShow ), QgsPropertyDefinition( "alwaysShow", QObject::tr( "Always show diagram" ), QgsPropertyDefinition::Boolean, origin ) },
59 { static_cast< int >( QgsDiagramLayerSettings::Property::StartAngle ), QgsPropertyDefinition( "startAngle", QObject::tr( "Pie chart start angle" ), QgsPropertyDefinition::Rotation, origin ) },
60 };
61}
62
64{
65 initPropertyDefinitions();
66 return sPropertyDefinitions;
67}
68
70{
71 initPropertyDefinitions();
72}
73
75 : mCt( rh.mCt )
76 , mPlacement( rh.mPlacement )
77 , mPlacementFlags( rh.mPlacementFlags )
78 , mPriority( rh.mPriority )
79 , mZIndex( rh.mZIndex )
80 , mObstacle( rh.mObstacle )
81 , mDistance( rh.mDistance )
82 , mRenderer( rh.mRenderer ? rh.mRenderer->clone() : nullptr )
83 , mShowAll( rh.mShowAll )
84 , mDataDefinedProperties( rh.mDataDefinedProperties )
85{
86 initPropertyDefinitions();
87}
88
90{
91 mPlacement = rh.mPlacement;
92 mPlacementFlags = rh.mPlacementFlags;
93 mPriority = rh.mPriority;
94 mZIndex = rh.mZIndex;
95 mObstacle = rh.mObstacle;
96 mDistance = rh.mDistance;
97 mRenderer = rh.mRenderer ? rh.mRenderer->clone() : nullptr;
98 mCt = rh.mCt;
99 mShowAll = rh.mShowAll;
100 mDataDefinedProperties = rh.mDataDefinedProperties;
101 return *this;
102}
103
108
110{
111 if ( diagramRenderer == mRenderer )
112 return;
113
114 delete mRenderer;
115 mRenderer = diagramRenderer;
116}
117
119{
120 mCt = transform;
121}
122
123void QgsDiagramLayerSettings::readXml( const QDomElement &elem )
124{
125 const QDomNodeList propertyElems = elem.elementsByTagName( QStringLiteral( "properties" ) );
126 if ( !propertyElems.isEmpty() )
127 {
128 ( void )mDataDefinedProperties.readXml( propertyElems.at( 0 ).toElement(), sPropertyDefinitions );
129 }
130 else
131 {
132 mDataDefinedProperties.clear();
133 }
134
135 mPlacement = static_cast< Placement >( elem.attribute( QStringLiteral( "placement" ) ).toInt() );
136 mPlacementFlags = static_cast< LinePlacementFlag >( elem.attribute( QStringLiteral( "linePlacementFlags" ) ).toInt() );
137 mPriority = elem.attribute( QStringLiteral( "priority" ) ).toInt();
138 mZIndex = elem.attribute( QStringLiteral( "zIndex" ) ).toDouble();
139 mObstacle = elem.attribute( QStringLiteral( "obstacle" ) ).toInt();
140 mDistance = elem.attribute( QStringLiteral( "dist" ) ).toDouble();
141 mShowAll = ( elem.attribute( QStringLiteral( "showAll" ), QStringLiteral( "0" ) ) != QLatin1String( "0" ) );
142}
143
144void QgsDiagramLayerSettings::writeXml( QDomElement &layerElem, QDomDocument &doc ) const
145{
146 QDomElement diagramLayerElem = doc.createElement( QStringLiteral( "DiagramLayerSettings" ) );
147 QDomElement propertiesElem = doc.createElement( QStringLiteral( "properties" ) );
148 ( void )mDataDefinedProperties.writeXml( propertiesElem, sPropertyDefinitions );
149 diagramLayerElem.appendChild( propertiesElem );
150 diagramLayerElem.setAttribute( QStringLiteral( "placement" ), mPlacement );
151 diagramLayerElem.setAttribute( QStringLiteral( "linePlacementFlags" ), mPlacementFlags );
152 diagramLayerElem.setAttribute( QStringLiteral( "priority" ), mPriority );
153 diagramLayerElem.setAttribute( QStringLiteral( "zIndex" ), mZIndex );
154 diagramLayerElem.setAttribute( QStringLiteral( "obstacle" ), mObstacle );
155 diagramLayerElem.setAttribute( QStringLiteral( "dist" ), QString::number( mDistance ) );
156 diagramLayerElem.setAttribute( QStringLiteral( "showAll" ), mShowAll );
157 layerElem.appendChild( diagramLayerElem );
158}
159
161{
162 return mDataDefinedProperties.prepare( context );
163}
164
166{
167 QSet< QString > referenced;
168 if ( mRenderer )
169 referenced = mRenderer->referencedFields( context );
170
171 //add the ones needed for data defined settings
172 referenced.unite( mDataDefinedProperties.referencedFields( context ) );
173
174 return referenced;
175}
176
177void QgsDiagramSettings::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
178{
179 enabled = ( elem.attribute( QStringLiteral( "enabled" ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
180 if ( !QgsFontUtils::setFromXmlChildNode( font, elem, QStringLiteral( "fontProperties" ) ) )
181 {
182 font.fromString( elem.attribute( QStringLiteral( "font" ) ) );
183 }
184 backgroundColor.setNamedColor( elem.attribute( QStringLiteral( "backgroundColor" ) ) );
185 backgroundColor.setAlpha( elem.attribute( QStringLiteral( "backgroundAlpha" ) ).toInt() );
186 size.setWidth( elem.attribute( QStringLiteral( "width" ) ).toDouble() );
187 size.setHeight( elem.attribute( QStringLiteral( "height" ) ).toDouble() );
188 if ( elem.hasAttribute( QStringLiteral( "transparency" ) ) )
189 {
190 opacity = 1 - elem.attribute( QStringLiteral( "transparency" ), QStringLiteral( "0" ) ).toInt() / 255.0;
191 }
192 else
193 {
194 opacity = elem.attribute( QStringLiteral( "opacity" ), QStringLiteral( "1.00" ) ).toDouble();
195 }
196
197 penColor.setNamedColor( elem.attribute( QStringLiteral( "penColor" ) ) );
198 const int penAlpha = elem.attribute( QStringLiteral( "penAlpha" ), QStringLiteral( "255" ) ).toInt();
199 penColor.setAlpha( penAlpha );
200 penWidth = elem.attribute( QStringLiteral( "penWidth" ) ).toDouble();
201
202 mDirection = static_cast< Direction >( elem.attribute( QStringLiteral( "direction" ), QStringLiteral( "1" ) ).toInt() );
203
204 maximumScale = elem.attribute( QStringLiteral( "minScaleDenominator" ), QStringLiteral( "-1" ) ).toDouble();
205 minimumScale = elem.attribute( QStringLiteral( "maxScaleDenominator" ), QStringLiteral( "-1" ) ).toDouble();
206 if ( elem.hasAttribute( QStringLiteral( "scaleBasedVisibility" ) ) )
207 {
208 scaleBasedVisibility = ( elem.attribute( QStringLiteral( "scaleBasedVisibility" ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
209 }
210 else
211 {
213 }
214
215 //diagram size unit type and scale
216 if ( elem.attribute( QStringLiteral( "sizeType" ) ) == QLatin1String( "MapUnits" ) )
217 {
218 //compatibility with pre-2.16 project files
220 }
221 else
222 {
223 sizeType = QgsUnitTypes::decodeRenderUnit( elem.attribute( QStringLiteral( "sizeType" ) ) );
224 }
225 sizeScale = QgsSymbolLayerUtils::decodeMapUnitScale( elem.attribute( QStringLiteral( "sizeScale" ) ) );
226
227 //line width unit type and scale
228 lineSizeUnit = QgsUnitTypes::decodeRenderUnit( elem.attribute( QStringLiteral( "lineSizeType" ) ) );
229 lineSizeScale = QgsSymbolLayerUtils::decodeMapUnitScale( elem.attribute( QStringLiteral( "lineSizeScale" ) ) );
230
231 mSpacing = elem.attribute( QStringLiteral( "spacing" ) ).toDouble();
232 mSpacingUnit = QgsUnitTypes::decodeRenderUnit( elem.attribute( QStringLiteral( "spacingUnit" ) ) );
233 mSpacingMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( elem.attribute( QStringLiteral( "spacingUnitScale" ) ) );
234
235 //label placement method
236 if ( elem.attribute( QStringLiteral( "labelPlacementMethod" ) ) == QLatin1String( "Height" ) )
237 {
239 }
240 else
241 {
243 }
244
245 // orientation
246 if ( elem.attribute( QStringLiteral( "diagramOrientation" ) ) == QLatin1String( "Left" ) )
247 {
249 }
250 else if ( elem.attribute( QStringLiteral( "diagramOrientation" ) ) == QLatin1String( "Right" ) )
251 {
253 }
254 else if ( elem.attribute( QStringLiteral( "diagramOrientation" ) ) == QLatin1String( "Down" ) )
255 {
257 }
258 else
259 {
261 }
262
263 // scale dependency
264 if ( elem.attribute( QStringLiteral( "scaleDependency" ) ) == QLatin1String( "Diameter" ) )
265 {
266 scaleByArea = false;
267 }
268 else
269 {
270 scaleByArea = true;
271 }
272
273 barWidth = elem.attribute( QStringLiteral( "barWidth" ) ).toDouble();
274
275 if ( elem.hasAttribute( QStringLiteral( "angleOffset" ) ) )
276 rotationOffset = std::fmod( 360.0 - elem.attribute( QStringLiteral( "angleOffset" ) ).toInt() / 16.0, 360.0 );
277 else
278 rotationOffset = elem.attribute( QStringLiteral( "rotationOffset" ) ).toDouble();
279
280 minimumSize = elem.attribute( QStringLiteral( "minimumSize" ) ).toDouble();
281
282 const QDomNodeList axisSymbolNodes = elem.elementsByTagName( QStringLiteral( "axisSymbol" ) );
283 if ( axisSymbolNodes.count() > 0 )
284 {
285 const QDomElement axisSymbolElem = axisSymbolNodes.at( 0 ).toElement().firstChildElement();
286 mAxisLineSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( axisSymbolElem, context ) );
287 }
288 else
289 {
290 mAxisLineSymbol = std::make_unique< QgsLineSymbol >();
291 }
292
293 mShowAxis = elem.attribute( QStringLiteral( "showAxis" ), QStringLiteral( "0" ) ).toInt();
294
295 //colors
296 categoryColors.clear();
297 const QDomNodeList attributes = elem.elementsByTagName( QStringLiteral( "attribute" ) );
298
299
300 if ( attributes.length() > 0 )
301 {
302 for ( int i = 0; i < attributes.size(); i++ )
303 {
304 const QDomElement attrElem = attributes.at( i ).toElement();
305 QColor newColor( attrElem.attribute( QStringLiteral( "color" ) ) );
306 newColor.setAlphaF( attrElem.attribute( QStringLiteral( "colorOpacity" ), QStringLiteral( "1.0" ) ).toDouble() );
307 categoryColors.append( newColor );
308 categoryAttributes.append( attrElem.attribute( QStringLiteral( "field" ) ) );
309 categoryLabels.append( attrElem.attribute( QStringLiteral( "label" ) ) );
310 if ( categoryLabels.constLast().isEmpty() )
311 {
312 categoryLabels.back() = categoryAttributes.back();
313 }
314 }
315 }
316 else
317 {
318 // Restore old format attributes and colors
319
320 const QStringList colorList = elem.attribute( QStringLiteral( "colors" ) ).split( '/' );
321 QStringList::const_iterator colorIt = colorList.constBegin();
322 for ( ; colorIt != colorList.constEnd(); ++colorIt )
323 {
324 QColor newColor( *colorIt );
325 categoryColors.append( QColor( newColor ) );
326 }
327
328 //attribute indices
329 categoryAttributes.clear();
330 const QStringList catList = elem.attribute( QStringLiteral( "categories" ) ).split( '/' );
331 QStringList::const_iterator catIt = catList.constBegin();
332 for ( ; catIt != catList.constEnd(); ++catIt )
333 {
334 categoryAttributes.append( *catIt );
335 categoryLabels.append( *catIt );
336 }
337 }
338
339 const QDomElement effectElem = elem.firstChildElement( QStringLiteral( "effect" ) );
340 if ( !effectElem.isNull() )
341 setPaintEffect( QgsApplication::paintEffectRegistry()->createEffect( effectElem ) );
342 else
344}
345
346void QgsDiagramSettings::writeXml( QDomElement &rendererElem, QDomDocument &doc, const QgsReadWriteContext &context ) const
347{
348 QDomElement categoryElem = doc.createElement( QStringLiteral( "DiagramCategory" ) );
349 categoryElem.setAttribute( QStringLiteral( "enabled" ), enabled );
350 categoryElem.appendChild( QgsFontUtils::toXmlElement( font, doc, QStringLiteral( "fontProperties" ) ) );
351 categoryElem.setAttribute( QStringLiteral( "backgroundColor" ), backgroundColor.name() );
352 categoryElem.setAttribute( QStringLiteral( "backgroundAlpha" ), backgroundColor.alpha() );
353 categoryElem.setAttribute( QStringLiteral( "width" ), QString::number( size.width() ) );
354 categoryElem.setAttribute( QStringLiteral( "height" ), QString::number( size.height() ) );
355 categoryElem.setAttribute( QStringLiteral( "penColor" ), penColor.name() );
356 categoryElem.setAttribute( QStringLiteral( "penAlpha" ), penColor.alpha() );
357 categoryElem.setAttribute( QStringLiteral( "penWidth" ), QString::number( penWidth ) );
358 categoryElem.setAttribute( QStringLiteral( "scaleBasedVisibility" ), scaleBasedVisibility );
359 categoryElem.setAttribute( QStringLiteral( "minScaleDenominator" ), QString::number( maximumScale ) );
360 categoryElem.setAttribute( QStringLiteral( "maxScaleDenominator" ), QString::number( minimumScale ) );
361 categoryElem.setAttribute( QStringLiteral( "opacity" ), QString::number( opacity ) );
362 categoryElem.setAttribute( QStringLiteral( "spacing" ), QString::number( mSpacing ) );
363 categoryElem.setAttribute( QStringLiteral( "spacingUnit" ), QgsUnitTypes::encodeUnit( mSpacingUnit ) );
364 categoryElem.setAttribute( QStringLiteral( "spacingUnitScale" ), QgsSymbolLayerUtils::encodeMapUnitScale( mSpacingMapUnitScale ) );
365 categoryElem.setAttribute( QStringLiteral( "direction" ), QString::number( mDirection ) );
366
367 //diagram size unit type and scale
368 categoryElem.setAttribute( QStringLiteral( "sizeType" ), QgsUnitTypes::encodeUnit( sizeType ) );
369 categoryElem.setAttribute( QStringLiteral( "sizeScale" ), QgsSymbolLayerUtils::encodeMapUnitScale( sizeScale ) );
370
371 //line width unit type and scale
372 categoryElem.setAttribute( QStringLiteral( "lineSizeType" ), QgsUnitTypes::encodeUnit( lineSizeUnit ) );
373 categoryElem.setAttribute( QStringLiteral( "lineSizeScale" ), QgsSymbolLayerUtils::encodeMapUnitScale( lineSizeScale ) );
374
375 // label placement method (text diagram)
377 {
378 categoryElem.setAttribute( QStringLiteral( "labelPlacementMethod" ), QStringLiteral( "Height" ) );
379 }
380 else
381 {
382 categoryElem.setAttribute( QStringLiteral( "labelPlacementMethod" ), QStringLiteral( "XHeight" ) );
383 }
384
385 if ( scaleByArea )
386 {
387 categoryElem.setAttribute( QStringLiteral( "scaleDependency" ), QStringLiteral( "Area" ) );
388 }
389 else
390 {
391 categoryElem.setAttribute( QStringLiteral( "scaleDependency" ), QStringLiteral( "Diameter" ) );
392 }
393
394 // orientation (histogram)
395 switch ( diagramOrientation )
396 {
397 case Left:
398 categoryElem.setAttribute( QStringLiteral( "diagramOrientation" ), QStringLiteral( "Left" ) );
399 break;
400
401 case Right:
402 categoryElem.setAttribute( QStringLiteral( "diagramOrientation" ), QStringLiteral( "Right" ) );
403 break;
404
405 case Down:
406 categoryElem.setAttribute( QStringLiteral( "diagramOrientation" ), QStringLiteral( "Down" ) );
407 break;
408
409 case Up:
410 categoryElem.setAttribute( QStringLiteral( "diagramOrientation" ), QStringLiteral( "Up" ) );
411 break;
412 }
413
414 categoryElem.setAttribute( QStringLiteral( "barWidth" ), QString::number( barWidth ) );
415 categoryElem.setAttribute( QStringLiteral( "minimumSize" ), QString::number( minimumSize ) );
416 categoryElem.setAttribute( QStringLiteral( "rotationOffset" ), QString::number( rotationOffset ) );
417
418 const int nCats = std::min( categoryColors.size(), categoryAttributes.size() );
419 for ( int i = 0; i < nCats; ++i )
420 {
421 QDomElement attributeElem = doc.createElement( QStringLiteral( "attribute" ) );
422
423 attributeElem.setAttribute( QStringLiteral( "field" ), categoryAttributes.at( i ) );
424 attributeElem.setAttribute( QStringLiteral( "color" ), categoryColors.at( i ).name() );
425 attributeElem.setAttribute( QStringLiteral( "colorOpacity" ), QString::number( categoryColors.at( i ).alphaF() ) );
426 attributeElem.setAttribute( QStringLiteral( "label" ), categoryLabels.at( i ) );
427 categoryElem.appendChild( attributeElem );
428 }
429
430 categoryElem.setAttribute( QStringLiteral( "showAxis" ), mShowAxis ? QStringLiteral( "1" ) : QStringLiteral( "0" ) );
431 QDomElement axisSymbolElem = doc.createElement( QStringLiteral( "axisSymbol" ) );
432 const QDomElement symbolElem = QgsSymbolLayerUtils::saveSymbol( QString(), mAxisLineSymbol.get(), doc, context );
433 axisSymbolElem.appendChild( symbolElem );
434 categoryElem.appendChild( axisSymbolElem );
435
436 if ( mPaintEffect && !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect.get() ) )
437 mPaintEffect->saveProperties( doc, categoryElem );
438
439 rendererElem.appendChild( categoryElem );
440}
441
443{
444 if ( mDiagram.get() == d )
445 return;
446
447 mDiagram.reset( d );
448}
449
451 : mDiagram( other.mDiagram ? other.mDiagram->clone() : nullptr )
452 , mShowAttributeLegend( other.mShowAttributeLegend )
453{
454}
455
457{
458 mDiagram.reset( other.mDiagram ? other.mDiagram->clone() : nullptr );
460 return *this;
461}
462
463void QgsDiagramRenderer::renderDiagram( const QgsFeature &feature, QgsRenderContext &c, QPointF pos, const QgsPropertyCollection &properties ) const
464{
465 if ( !mDiagram )
466 {
467 return;
468 }
469
471 if ( !diagramSettings( feature, c, s ) )
472 {
473 return;
474 }
475
476 if ( properties.hasActiveProperties() )
477 {
478 c.expressionContext().setOriginalValueVariable( QgsColorUtils::colorToString( s.backgroundColor ) );
480 c.expressionContext().setOriginalValueVariable( QgsColorUtils::colorToString( s.penColor ) );
481 s.penColor = properties.valueAsColor( QgsDiagramLayerSettings::Property::StrokeColor, c.expressionContext(), s.penColor );
482 c.expressionContext().setOriginalValueVariable( s.penWidth );
483 s.penWidth = properties.valueAsDouble( QgsDiagramLayerSettings::Property::StrokeWidth, c.expressionContext(), s.penWidth );
484 c.expressionContext().setOriginalValueVariable( s.rotationOffset );
486 }
487
488 QgsPaintEffect *effect = s.paintEffect();
489 std::unique_ptr< QgsEffectPainter > effectPainter;
490 if ( effect && effect->enabled() )
491 {
492 effectPainter = std::make_unique< QgsEffectPainter >( c, effect );
493 }
494
495 mDiagram->renderDiagram( feature, c, s, pos );
496}
497
498QSizeF QgsDiagramRenderer::sizeMapUnits( const QgsFeature &feature, const QgsRenderContext &c ) const
499{
501 if ( !diagramSettings( feature, c, s ) )
502 {
503 return QSizeF();
504 }
505
506 QSizeF size = diagramSize( feature, c );
507 if ( size.isValid() )
508 {
509 const double width = c.convertToMapUnits( size.width(), s.sizeType, s.sizeScale );
510 size.rheight() *= width / size.width();
511 size.setWidth( width );
512 }
513 return size;
514}
515
517{
518 QSet< QString > referenced;
519
520 if ( !mDiagram )
521 return referenced;
522
523 const auto constDiagramAttributes = diagramAttributes();
524 for ( const QString &att : constDiagramAttributes )
525 {
526 QgsExpression *expression = mDiagram->getExpression( att, context );
527 const auto constReferencedColumns = expression->referencedColumns();
528 for ( const QString &field : constReferencedColumns )
529 {
530 referenced << field;
531 }
532 }
533 return referenced;
534}
535
536void QgsDiagramRenderer::convertSizeToMapUnits( QSizeF &size, const QgsRenderContext &context ) const
537{
538 if ( !size.isValid() )
539 {
540 return;
541 }
542
543 const double pixelToMap = context.scaleFactor() * context.mapToPixel().mapUnitsPerPixel();
544 size.rwidth() *= pixelToMap;
545 size.rheight() *= pixelToMap;
546}
547
548int QgsDiagramRenderer::dpiPaintDevice( const QPainter *painter )
549{
550 if ( painter )
551 {
552 QPaintDevice *device = painter->device();
553 if ( device )
554 {
555 return device->logicalDpiX();
556 }
557 }
558 return -1;
559}
560
561void QgsDiagramRenderer::_readXml( const QDomElement &elem, const QgsReadWriteContext &context )
562{
563 Q_UNUSED( context )
564 mDiagram.reset();
565 const QString diagramType = elem.attribute( QStringLiteral( "diagramType" ) );
566 if ( diagramType == QLatin1String( "Pie" ) )
567 {
568 mDiagram.reset( new QgsPieDiagram() );
569 }
570 else if ( diagramType == QLatin1String( "Text" ) )
571 {
572 mDiagram.reset( new QgsTextDiagram() );
573 }
574 else if ( diagramType == QLatin1String( "Histogram" ) )
575 {
576 mDiagram.reset( new QgsHistogramDiagram() );
577 }
578 else if ( diagramType == QLatin1String( "Stacked" ) )
579 {
580 mDiagram.reset( new QgsStackedBarDiagram() );
581 }
582 else
583 {
584 // unknown diagram type -- default to histograms
585 mDiagram.reset( new QgsHistogramDiagram() );
586 }
587 mShowAttributeLegend = ( elem.attribute( QStringLiteral( "attributeLegend" ), QStringLiteral( "1" ) ) != QLatin1String( "0" ) );
588}
589
590void QgsDiagramRenderer::_writeXml( QDomElement &rendererElem, QDomDocument &doc, const QgsReadWriteContext &context ) const
591{
592 Q_UNUSED( doc )
593 Q_UNUSED( context )
594
595 if ( mDiagram )
596 {
597 rendererElem.setAttribute( QStringLiteral( "diagramType" ), mDiagram->diagramName() );
598 }
599 rendererElem.setAttribute( QStringLiteral( "attributeLegend" ), mShowAttributeLegend );
600}
601
606
608{
609 Q_UNUSED( c )
610 s = mSettings;
611 return true;
612}
613
615{
616 return mDiagram->diagramSize( feature.attributes(), c, mSettings );
617}
618
620{
621 QList<QgsDiagramSettings> settingsList;
622 settingsList.push_back( mSettings );
623 return settingsList;
624}
625
626void QgsSingleCategoryDiagramRenderer::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
627{
628 const QDomElement categoryElem = elem.firstChildElement( QStringLiteral( "DiagramCategory" ) );
629 if ( categoryElem.isNull() )
630 {
631 return;
632 }
633
634 mSettings.readXml( categoryElem, context );
635 _readXml( elem, context );
636}
637
638void QgsSingleCategoryDiagramRenderer::writeXml( QDomElement &layerElem, QDomDocument &doc, const QgsReadWriteContext &context ) const
639{
640 QDomElement rendererElem = doc.createElement( QStringLiteral( "SingleCategoryDiagramRenderer" ) );
641 mSettings.writeXml( rendererElem, doc, context );
642 _writeXml( rendererElem, doc, context );
643 layerElem.appendChild( rendererElem );
644}
645
646
651
653 : QgsDiagramRenderer( other )
654 , mSettings( other.mSettings )
655 , mInterpolationSettings( other.mInterpolationSettings )
656 , mDataDefinedSizeLegend( other.mDataDefinedSizeLegend ? new QgsDataDefinedSizeLegend( *other.mDataDefinedSizeLegend ) : nullptr )
657{
658}
659
664
666{
667 if ( &other == this )
668 {
669 return *this;
670 }
671 mSettings = other.mSettings;
672 mInterpolationSettings = other.mInterpolationSettings;
673 delete mDataDefinedSizeLegend;
674 mDataDefinedSizeLegend = new QgsDataDefinedSizeLegend( *other.mDataDefinedSizeLegend );
675 return *this;
676}
677
682
684{
685 QList<QgsDiagramSettings> settingsList;
686 settingsList.push_back( mSettings );
687 return settingsList;
688}
689
691{
692 s = mSettings;
693 s.size = diagramSize( feature, c );
694 return true;
695}
696
698{
699 return mSettings.categoryAttributes;
700}
701
703{
704 QSet< QString > referenced = QgsDiagramRenderer::referencedFields( context );
705 if ( mInterpolationSettings.classificationAttributeIsExpression )
706 {
707 QgsExpression *expression = mDiagram->getExpression( mInterpolationSettings.classificationAttributeExpression, context );
708 const auto constReferencedColumns = expression->referencedColumns();
709 for ( const QString &field : constReferencedColumns )
710 {
711 referenced << field;
712 }
713 }
714 else
715 {
716 referenced << mInterpolationSettings.classificationField;
717 }
718 return referenced;
719}
720
722{
723 return mDiagram->diagramSize( feature, c, mSettings, mInterpolationSettings );
724}
725
726void QgsLinearlyInterpolatedDiagramRenderer::readXml( const QDomElement &elem, const QgsReadWriteContext &context )
727{
728 mInterpolationSettings.lowerValue = elem.attribute( QStringLiteral( "lowerValue" ) ).toDouble();
729 mInterpolationSettings.upperValue = elem.attribute( QStringLiteral( "upperValue" ) ).toDouble();
730 mInterpolationSettings.lowerSize.setWidth( elem.attribute( QStringLiteral( "lowerWidth" ) ).toDouble() );
731 mInterpolationSettings.lowerSize.setHeight( elem.attribute( QStringLiteral( "lowerHeight" ) ).toDouble() );
732 mInterpolationSettings.upperSize.setWidth( elem.attribute( QStringLiteral( "upperWidth" ) ).toDouble() );
733 mInterpolationSettings.upperSize.setHeight( elem.attribute( QStringLiteral( "upperHeight" ) ).toDouble() );
734 mInterpolationSettings.classificationAttributeIsExpression = elem.hasAttribute( QStringLiteral( "classificationAttributeExpression" ) );
735 if ( mInterpolationSettings.classificationAttributeIsExpression )
736 {
737 mInterpolationSettings.classificationAttributeExpression = elem.attribute( QStringLiteral( "classificationAttributeExpression" ) );
738 }
739 else
740 {
741 mInterpolationSettings.classificationField = elem.attribute( QStringLiteral( "classificationField" ) );
742 }
743 const QDomElement settingsElem = elem.firstChildElement( QStringLiteral( "DiagramCategory" ) );
744 if ( !settingsElem.isNull() )
745 {
746 mSettings.readXml( settingsElem );
747 }
748
749 delete mDataDefinedSizeLegend;
750
751 const QDomElement ddsLegendSizeElem = elem.firstChildElement( QStringLiteral( "data-defined-size-legend" ) );
752 if ( !ddsLegendSizeElem.isNull() )
753 {
754 mDataDefinedSizeLegend = QgsDataDefinedSizeLegend::readXml( ddsLegendSizeElem, context );
755 }
756 else
757 {
758 // pre-3.0 projects
759 if ( elem.attribute( QStringLiteral( "sizeLegend" ), QStringLiteral( "0" ) ) != QLatin1String( "0" ) )
760 {
761 mDataDefinedSizeLegend = new QgsDataDefinedSizeLegend();
762 const QDomElement sizeLegendSymbolElem = elem.firstChildElement( QStringLiteral( "symbol" ) );
763 if ( !sizeLegendSymbolElem.isNull() && sizeLegendSymbolElem.attribute( QStringLiteral( "name" ) ) == QLatin1String( "sizeSymbol" ) )
764 {
765 mDataDefinedSizeLegend->setSymbol( QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( sizeLegendSymbolElem, context ) );
766 }
767 }
768 else
769 {
770 mDataDefinedSizeLegend = nullptr;
771 }
772 }
773
774 _readXml( elem, context );
775}
776
777void QgsLinearlyInterpolatedDiagramRenderer::writeXml( QDomElement &layerElem, QDomDocument &doc, const QgsReadWriteContext &context ) const
778{
779 QDomElement rendererElem = doc.createElement( QStringLiteral( "LinearlyInterpolatedDiagramRenderer" ) );
780 rendererElem.setAttribute( QStringLiteral( "lowerValue" ), QString::number( mInterpolationSettings.lowerValue ) );
781 rendererElem.setAttribute( QStringLiteral( "upperValue" ), QString::number( mInterpolationSettings.upperValue ) );
782 rendererElem.setAttribute( QStringLiteral( "lowerWidth" ), QString::number( mInterpolationSettings.lowerSize.width() ) );
783 rendererElem.setAttribute( QStringLiteral( "lowerHeight" ), QString::number( mInterpolationSettings.lowerSize.height() ) );
784 rendererElem.setAttribute( QStringLiteral( "upperWidth" ), QString::number( mInterpolationSettings.upperSize.width() ) );
785 rendererElem.setAttribute( QStringLiteral( "upperHeight" ), QString::number( mInterpolationSettings.upperSize.height() ) );
786 if ( mInterpolationSettings.classificationAttributeIsExpression )
787 {
788 rendererElem.setAttribute( QStringLiteral( "classificationAttributeExpression" ), mInterpolationSettings.classificationAttributeExpression );
789 }
790 else
791 {
792 rendererElem.setAttribute( QStringLiteral( "classificationField" ), mInterpolationSettings.classificationField );
793 }
794 mSettings.writeXml( rendererElem, doc );
795
796 if ( mDataDefinedSizeLegend )
797 {
798 QDomElement ddsLegendElem = doc.createElement( QStringLiteral( "data-defined-size-legend" ) );
799 mDataDefinedSizeLegend->writeXml( ddsLegendElem, context );
800 rendererElem.appendChild( ddsLegendElem );
801 }
802
803 _writeXml( rendererElem, doc, context );
804 layerElem.appendChild( rendererElem );
805}
806
807QList< QgsLayerTreeModelLegendNode * > QgsDiagramSettings::legendItems( QgsLayerTreeLayer *nodeLayer ) const
808{
809 QList< QgsLayerTreeModelLegendNode * > list;
810 list.reserve( categoryLabels.size() );
811 for ( int i = 0; i < categoryLabels.size(); ++i )
812 {
813 QPixmap pix( 16, 16 );
814 pix.fill( categoryColors[i] );
815 list << new QgsSimpleLegendNode( nodeLayer, categoryLabels[i], QIcon( pix ), nullptr, QStringLiteral( "diagram_%1" ).arg( QString::number( i ) ) );
816 }
817 return list;
818}
819
821{
822 return mAxisLineSymbol.get();
823}
824
826{
827 if ( axisLineSymbol != mAxisLineSymbol.get() )
828 mAxisLineSymbol.reset( axisLineSymbol );
829}
830
832{
833 return mShowAxis;
834}
835
837{
838 mShowAxis = showAxis;
839}
840
842{
843 return mPaintEffect.get();
844}
845
847{
848 if ( effect != mPaintEffect.get() )
849 mPaintEffect.reset( effect );
850}
851
853 : mAxisLineSymbol( std::make_unique< QgsLineSymbol >() )
854{
855}
856
858
860 : enabled( other.enabled )
861 , font( other.font )
862 , categoryColors( other.categoryColors )
863 , categoryAttributes( other.categoryAttributes )
864 , categoryLabels( other.categoryLabels )
865 , size( other.size )
866 , sizeType( other.sizeType )
867 , sizeScale( other.sizeScale )
868 , lineSizeUnit( other.lineSizeUnit )
869 , lineSizeScale( other.lineSizeScale )
870 , backgroundColor( other.backgroundColor )
871 , penColor( other.penColor )
872 , penWidth( other.penWidth )
873 , labelPlacementMethod( other.labelPlacementMethod )
874 , diagramOrientation( other.diagramOrientation )
875 , barWidth( other.barWidth )
876 , opacity( other.opacity )
877 , scaleByArea( other.scaleByArea )
878 , rotationOffset( other.rotationOffset )
879 , scaleBasedVisibility( other.scaleBasedVisibility )
880 , maximumScale( other.maximumScale )
881 , minimumScale( other.minimumScale )
882 , minimumSize( other.minimumSize )
883 , mSpacing( other.mSpacing )
884 , mSpacingUnit( other.mSpacingUnit )
885 , mSpacingMapUnitScale( other.mSpacingMapUnitScale )
886 , mDirection( other.mDirection )
887 , mShowAxis( other.mShowAxis )
888 , mAxisLineSymbol( other.mAxisLineSymbol ? other.mAxisLineSymbol->clone() : nullptr )
889 , mPaintEffect( other.mPaintEffect ? other.mPaintEffect->clone() : nullptr )
890{
891
892}
893
895{
896 enabled = other.enabled;
897 font = other.font;
901 size = other.size;
902 sizeType = other.sizeType;
903 sizeScale = other.sizeScale;
907 penColor = other.penColor;
908 penWidth = other.penWidth;
911 barWidth = other.barWidth;
912 opacity = other.opacity;
913 scaleByArea = other.scaleByArea;
918 minimumSize = other.minimumSize;
919 mSpacing = other.mSpacing;
920 mSpacingUnit = other.mSpacingUnit;
921 mSpacingMapUnitScale = other.mSpacingMapUnitScale;
922 mDirection = other.mDirection;
923 mAxisLineSymbol.reset( other.mAxisLineSymbol ? other.mAxisLineSymbol->clone() : nullptr );
924 mShowAxis = other.mShowAxis;
925 mPaintEffect.reset( other.mPaintEffect ? other.mPaintEffect->clone() : nullptr );
926 return *this;
927}
928
930{
931 return mDirection;
932}
933
935{
936 mDirection = direction;
937}
938
939QList< QgsLayerTreeModelLegendNode * > QgsDiagramRenderer::legendItems( QgsLayerTreeLayer * ) const
940{
941 return QList< QgsLayerTreeModelLegendNode * >();
942}
943
944QList< QgsLayerTreeModelLegendNode * > QgsSingleCategoryDiagramRenderer::legendItems( QgsLayerTreeLayer *nodeLayer ) const
945{
946 QList< QgsLayerTreeModelLegendNode * > nodes;
948 nodes = mSettings.legendItems( nodeLayer );
949
950 return nodes;
951}
952
953QList< QgsLayerTreeModelLegendNode * > QgsLinearlyInterpolatedDiagramRenderer::legendItems( QgsLayerTreeLayer *nodeLayer ) const
954{
955 QList< QgsLayerTreeModelLegendNode * > nodes;
957 nodes = mSettings.legendItems( nodeLayer );
958
959 if ( mDataDefinedSizeLegend && mDiagram )
960 {
961 // add size legend
962 QgsMarkerSymbol *legendSymbol = mDataDefinedSizeLegend->symbol() ? mDataDefinedSizeLegend->symbol()->clone() : QgsMarkerSymbol::createSimple( QVariantMap() );
963 legendSymbol->setSizeUnit( mSettings.sizeType );
964 legendSymbol->setSizeMapUnitScale( mSettings.sizeScale );
965
966 QgsDataDefinedSizeLegend ddSizeLegend( *mDataDefinedSizeLegend );
967 ddSizeLegend.setSymbol( legendSymbol ); // transfers ownership
968
969 QList<QgsDataDefinedSizeLegend::SizeClass> sizeClasses;
970 if ( ddSizeLegend.classes().isEmpty() )
971 {
972 // automatic class creation if the classes are not defined manually
973 const auto prettyBreaks { QgsSymbolLayerUtils::prettyBreaks( mInterpolationSettings.lowerValue, mInterpolationSettings.upperValue, 4 ) };
974 for ( const double v : prettyBreaks )
975 {
976 const double size = mDiagram->legendSize( v, mSettings, mInterpolationSettings );
977 sizeClasses << QgsDataDefinedSizeLegend::SizeClass( size, QString::number( v ) );
978 }
979 }
980 else
981 {
982 // manual classes need to get size scaled because the QgsSizeScaleTransformer is not used in diagrams :-(
983 const auto constClasses = ddSizeLegend.classes();
984 for ( const QgsDataDefinedSizeLegend::SizeClass &sc : constClasses )
985 {
986 const double size = mDiagram->legendSize( sc.size, mSettings, mInterpolationSettings );
987 sizeClasses << QgsDataDefinedSizeLegend::SizeClass( size, sc.label );
988 }
989 }
990 ddSizeLegend.setClasses( sizeClasses );
991
992 const auto constLegendSymbolList = ddSizeLegend.legendSymbolList();
993 for ( const QgsLegendSymbolItem &si : constLegendSymbolList )
994 {
995 if ( auto *lDataDefinedSizeLegendSettings = si.dataDefinedSizeLegendSettings() )
996 nodes << new QgsDataDefinedSizeLegendNode( nodeLayer, *lDataDefinedSizeLegendSettings );
997 else
998 nodes << new QgsSymbolLegendNode( nodeLayer, si );
999 }
1000 }
1001
1002 return nodes;
1003}
1004
1006{
1007 delete mDataDefinedSizeLegend;
1008 mDataDefinedSizeLegend = settings;
1009}
1010
@ MapUnits
Map units.
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.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
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)
void setRenderer(QgsDiagramRenderer *diagramRenderer)
Sets the diagram renderer associated with the layer.
@ PositionX
X-coordinate data defined diagram position.
@ Distance
Distance to diagram from feature.
@ PositionY
Y-coordinate data defined diagram position.
@ Show
Whether to show the diagram.
@ Priority
Diagram priority (between 0 and 10)
@ ZIndex
Z-index for diagram ordering.
@ BackgroundColor
Diagram background color.
@ StartAngle
Angle offset for pie diagram.
@ IsObstacle
Whether diagram features act as obstacles for other diagrams/labels.
@ AlwaysShow
Whether the diagram should always be shown, even if it overlaps other diagrams/labels.
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 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.
virtual QList< QString > diagramAttributes() const =0
Returns attribute indices needed for diagram rendering.
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)
virtual QgsDiagramRenderer * clone() const =0
Returns new instance that is equivalent to this one.
static int dpiPaintDevice(const QPainter *)
Returns the paint device dpi (or -1 in case of error.
Stores the settings for rendering a single diagram.
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.
Qgis::RenderUnit sizeType
Diagram size unit.
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.
Qgis::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 unique ID, geometry and a list of field...
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.
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.
QgsLinearlyInterpolatedDiagramRenderer & operator=(const QgsLinearlyInterpolatedDiagramRenderer &other)
double mapUnitsPerPixel() const
Returns the current map units per pixel.
A marker symbol type, for rendering Point and MultiPoint geometries.
static QgsMarkerSymbol * createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
void setSizeMapUnitScale(const QgsMapUnitScale &scale) const
Sets the size map unit scale for the whole symbol (including all symbol layers).
void setSizeUnit(Qgis::RenderUnit unit) const
Sets the size units for the whole symbol (including all symbol layers).
static QgsPaintEffect * defaultStack()
Returns a new effect stack consisting of a sensible selection of default effects.
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.
A grouped map of multiple QgsProperty objects, each referenced by a integer key value.
void clear() final
Removes all properties from the collection.
bool prepare(const QgsExpressionContext &context=QgsExpressionContext()) const final
Prepares the collection against a specified expression context.
bool hasActiveProperties() const final
Returns true if the collection has any active properties, or false if all properties within the colle...
QSet< QString > referencedFields(const QgsExpressionContext &context=QgsExpressionContext(), bool ignoreContext=false) const final
Returns the set of any fields referenced by the active properties from the collection.
Definition for a property.
Definition qgsproperty.h:45
@ Double
Double value (including negative values)
Definition qgsproperty.h:55
@ StrokeWidth
Line stroke width.
Definition qgsproperty.h:70
@ Boolean
Boolean value.
Definition qgsproperty.h:51
@ Rotation
Rotation (value between 0-360 degrees)
Definition qgsproperty.h:58
@ ColorWithAlpha
Color with alpha channel.
Definition qgsproperty.h:62
@ DoublePositive
Positive double value (including 0)
Definition qgsproperty.h:56
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 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 Qgis::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
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
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
Definition of one class for the legend.