Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgsdiagramrenderer.h
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 : : #ifndef QGSDIAGRAMRENDERER_H
16 : : #define QGSDIAGRAMRENDERER_H
17 : :
18 : : #include "qgis_core.h"
19 : : #include "qgis_sip.h"
20 : : #include <QColor>
21 : : #include <QFont>
22 : : #include <QList>
23 : : #include <QPointF>
24 : : #include <QSizeF>
25 : : #include <QDomDocument>
26 : :
27 : : #include "qgsexpressioncontext.h"
28 : : #include "qgsfields.h"
29 : : #include "qgscoordinatetransform.h"
30 : : #include "qgssymbol.h"
31 : : #include "qgsproperty.h"
32 : : #include "qgspropertycollection.h"
33 : :
34 : : #include "diagram/qgsdiagram.h"
35 : : #include "qgsreadwritecontext.h"
36 : :
37 : : class QgsDiagramRenderer;
38 : : class QgsFeature;
39 : : class QgsRenderContext;
40 : : class QDomElement;
41 : : class QgsMapToPixel;
42 : : class QgsReadWriteContext;
43 : : class QgsVectorLayer;
44 : : class QgsLayerTreeModelLegendNode;
45 : : class QgsLayerTreeLayer;
46 : : class QgsPaintEffect;
47 : : class QgsDataDefinedSizeLegend;
48 : :
49 : : namespace pal { class Layer; } SIP_SKIP
50 : :
51 : : /**
52 : : * \ingroup core
53 : : * \class QgsDiagramLayerSettings
54 : : * \brief Stores the settings for rendering of all diagrams for a layer.
55 : : *
56 : : * QgsDiagramSettings stores the settings related to rendering the individual diagrams themselves, while
57 : : * QgsDiagramLayerSettings stores settings which control how ALL diagrams within a layer are rendered.
58 : : */
59 : :
60 : : class CORE_EXPORT QgsDiagramLayerSettings
61 : : {
62 : : public:
63 : :
64 : : //avoid inclusion of QgsPalLabeling
65 : : enum Placement
66 : : {
67 : : AroundPoint = 0, // Point / Polygon
68 : : OverPoint, // Point / Polygon
69 : : Line, // Line / Polygon
70 : : Curved, // Line
71 : : Horizontal, // Polygon
72 : : Free // Polygon
73 : : };
74 : :
75 : : //! Line placement flags for controlling line based placements
76 : : enum LinePlacementFlag
77 : : {
78 : : OnLine = 1,
79 : : AboveLine = 1 << 1,
80 : : BelowLine = 1 << 2,
81 : : MapOrientation = 1 << 4,
82 : : };
83 : : Q_DECLARE_FLAGS( LinePlacementFlags, LinePlacementFlag )
84 : :
85 : : /**
86 : : * Data definable properties.
87 : : * \since QGIS 3.0
88 : : */
89 : : enum Property
90 : : {
91 : : BackgroundColor, //!< Diagram background color
92 : : StrokeColor, //!< Stroke color
93 : : StrokeWidth, //!< Stroke width
94 : : PositionX, //!< X-coordinate data defined diagram position
95 : : PositionY, //!< Y-coordinate data defined diagram position
96 : : Distance, //!< Distance to diagram from feature
97 : : Priority, //!< Diagram priority (between 0 and 10)
98 : : ZIndex, //!< Z-index for diagram ordering
99 : : IsObstacle, //!< Whether diagram features act as obstacles for other diagrams/labels
100 : : Show, //!< Whether to show the diagram
101 : : AlwaysShow, //!< Whether the diagram should always be shown, even if it overlaps other diagrams/labels
102 : : StartAngle, //!< Angle offset for pie diagram
103 : : };
104 : :
105 : : /**
106 : : * Returns the diagram property definitions.
107 : : * \since QGIS 3.0
108 : : */
109 : : static const QgsPropertiesDefinition &propertyDefinitions();
110 : :
111 : : /**
112 : : * Constructor for QgsDiagramLayerSettings.
113 : : */
114 : : QgsDiagramLayerSettings();
115 : :
116 : : //! Copy constructor
117 : : QgsDiagramLayerSettings( const QgsDiagramLayerSettings &rh );
118 : :
119 : : QgsDiagramLayerSettings &operator=( const QgsDiagramLayerSettings &rh );
120 : :
121 : : ~QgsDiagramLayerSettings();
122 : :
123 : : /**
124 : : * Returns the diagram placement.
125 : : * \see setPlacement()
126 : : * \since QGIS 2.16
127 : : */
128 : 0 : Placement placement() const { return mPlacement; }
129 : :
130 : : /**
131 : : * Sets the diagram placement.
132 : : * \param value placement value
133 : : * \see placement()
134 : : * \since QGIS 2.16
135 : : */
136 : : void setPlacement( Placement value ) { mPlacement = value; }
137 : :
138 : : /**
139 : : * Returns the diagram placement flags. These are only used if the diagram placement
140 : : * is set to a line type.
141 : : * \see setLinePlacementFlags()
142 : : * \since QGIS 2.16
143 : : */
144 : : LinePlacementFlags linePlacementFlags() const { return mPlacementFlags; }
145 : :
146 : : /**
147 : : * Sets the the diagram placement flags. These are only used if the diagram placement
148 : : * is set to a line type.
149 : : * \param flags placement value
150 : : * \see linePlacementFlags()
151 : : * \since QGIS 2.16
152 : : */
153 : : void setLinePlacementFlags( LinePlacementFlags flags ) { mPlacementFlags = flags; }
154 : :
155 : : /**
156 : : * Returns the diagram priority.
157 : : * \returns diagram priority, where 0 = low and 10 = high
158 : : * \note placement priority is shared with labeling, so diagrams with a high priority may displace labels
159 : : * and vice-versa
160 : : * \see setPriority()
161 : : * \since QGIS 2.16
162 : : */
163 : 0 : int priority() const { return mPriority; }
164 : :
165 : : /**
166 : : * Sets the diagram priority.
167 : : * \param value priority, where 0 = low and 10 = high
168 : : * \see priority()
169 : : * \since QGIS 2.16
170 : : */
171 : : void setPriority( int value ) { mPriority = value; }
172 : :
173 : : /**
174 : : * Returns the diagram z-index. Diagrams (or labels) with a higher z-index are drawn over diagrams
175 : : * with a lower z-index.
176 : : * \note z-index ordering is shared with labeling, so diagrams with a high z-index may be drawn over labels
177 : : * with a low z-index and vice-versa
178 : : * \see setZIndex()
179 : : * \since QGIS 2.16
180 : : */
181 : 0 : double zIndex() const { return mZIndex; }
182 : :
183 : : /**
184 : : * Sets the diagram z-index. Diagrams (or labels) with a higher z-index are drawn over diagrams
185 : : * with a lower z-index.
186 : : * \param index diagram z-index
187 : : * \see zIndex()
188 : : * \since QGIS 2.16
189 : : */
190 : : void setZIndex( double index ) { mZIndex = index; }
191 : :
192 : : /**
193 : : * Returns whether the feature associated with a diagram acts as an obstacle for other labels or diagrams.
194 : : * \see setIsObstacle()
195 : : * \since QGIS 2.16
196 : : */
197 : 0 : bool isObstacle() const { return mObstacle; }
198 : :
199 : : /**
200 : : * Sets whether the feature associated with a diagram acts as an obstacle for other labels or diagrams.
201 : : * \param isObstacle set to TRUE for feature to act as obstacle
202 : : * \see isObstacle()
203 : : * \since QGIS 2.16
204 : : */
205 : : void setIsObstacle( bool isObstacle ) { mObstacle = isObstacle; }
206 : :
207 : : /**
208 : : * Returns the distance between the diagram and the feature (in mm).
209 : : * \see setDistance()
210 : : * \since QGIS 2.16
211 : : */
212 : 0 : double distance() const { return mDistance; }
213 : :
214 : : /**
215 : : * Sets the distance between the diagram and the feature.
216 : : * \param distance distance in mm
217 : : * \see distance()
218 : : * \since QGIS 2.16
219 : : */
220 : : void setDistance( double distance ) { mDistance = distance; }
221 : :
222 : : /**
223 : : * Returns the diagram renderer associated with the layer.
224 : : * \see setRenderer()
225 : : * \since QGIS 2.16
226 : : */
227 : 0 : QgsDiagramRenderer *renderer() { return mRenderer; }
228 : :
229 : : /**
230 : : * Returns the diagram renderer associated with the layer.
231 : : * \see setRenderer()
232 : : * \note not available in Python bindings
233 : : * \since QGIS 2.16
234 : : */
235 : 0 : const QgsDiagramRenderer *renderer() const { return mRenderer; } SIP_SKIP
236 : :
237 : : /**
238 : : * Sets the diagram renderer associated with the layer.
239 : : * \param diagramRenderer diagram renderer. Ownership is transferred to the object.
240 : : * \see renderer()
241 : : * \since QGIS 2.16
242 : : */
243 : : void setRenderer( QgsDiagramRenderer *diagramRenderer SIP_TRANSFER );
244 : :
245 : : /**
246 : : * Returns the coordinate transform associated with the layer, or an
247 : : * invalid transform if no transformation is required.
248 : : * \see setCoordinateTransform()
249 : : * \since QGIS 2.16
250 : : */
251 : 0 : QgsCoordinateTransform coordinateTransform() const { return mCt; }
252 : :
253 : : /**
254 : : * Sets the coordinate transform associated with the layer.
255 : : * \param transform coordinate transform. Ownership is transferred to the object.
256 : : * \see coordinateTransform()
257 : : * \since QGIS 2.16
258 : : */
259 : : void setCoordinateTransform( const QgsCoordinateTransform &transform );
260 : :
261 : : /**
262 : : * Returns whether the layer should show all diagrams, including overlapping diagrams
263 : : * \see setShowAllDiagrams()
264 : : * \since QGIS 2.16
265 : : */
266 : 0 : bool showAllDiagrams() const { return mShowAll; }
267 : :
268 : : /**
269 : : * Sets whether the layer should show all diagrams, including overlapping diagrams
270 : : * \param showAllDiagrams set to TRUE to show all diagrams
271 : : * \see showAllDiagrams()
272 : : * \since QGIS 2.16
273 : : */
274 : : void setShowAllDiagrams( bool showAllDiagrams ) { mShowAll = showAllDiagrams; }
275 : :
276 : : /**
277 : : * Reads the diagram settings from a DOM element.
278 : : * \see writeXml()
279 : : */
280 : : void readXml( const QDomElement &elem );
281 : :
282 : : /**
283 : : * Writes the diagram settings to a DOM element.
284 : : * \see readXml()
285 : : */
286 : : void writeXml( QDomElement &layerElem, QDomDocument &doc ) const;
287 : :
288 : : /**
289 : : * Prepares the diagrams for a specified expression context. Calling prepare before rendering
290 : : * multiple diagrams allows precalculation of expensive setup tasks such as parsing expressions.
291 : : * Returns TRUE if preparation was successful.
292 : : * \since QGIS 3.0
293 : : */
294 : : bool prepare( const QgsExpressionContext &context = QgsExpressionContext() ) const;
295 : :
296 : : /**
297 : : * Returns the set of any fields referenced by the layer's diagrams.
298 : : * \param context expression context the diagrams will be drawn using
299 : : * \since QGIS 2.16
300 : : */
301 : : QSet< QString > referencedFields( const QgsExpressionContext &context = QgsExpressionContext() ) const;
302 : :
303 : : /**
304 : : * Returns a reference to the diagram's property collection, used for data defined overrides.
305 : : * \see setDataDefinedProperties()
306 : : * \since QGIS 3.0
307 : : */
308 : 0 : QgsPropertyCollection &dataDefinedProperties() { return mDataDefinedProperties; }
309 : :
310 : : /**
311 : : * Returns a reference to the diagram's property collection, used for data defined overrides.
312 : : * \see setDataDefinedProperties()
313 : : * \see Property
314 : : * \note not available in Python bindings
315 : : * \since QGIS 3.0
316 : : */
317 : 0 : const QgsPropertyCollection &dataDefinedProperties() const { return mDataDefinedProperties; } SIP_SKIP
318 : :
319 : : /**
320 : : * Sets the diagram's property collection, used for data defined overrides.
321 : : * \param collection property collection. Existing properties will be replaced.
322 : : * \see dataDefinedProperties()
323 : : * \see Property
324 : : * \since QGIS 3.0
325 : : */
326 : 0 : void setDataDefinedProperties( const QgsPropertyCollection &collection ) { mDataDefinedProperties = collection; }
327 : :
328 : : private:
329 : :
330 : : //! Associated coordinate transform, or invalid transform for no transformation
331 : : QgsCoordinateTransform mCt;
332 : :
333 : : //! Diagram placement
334 : : Placement mPlacement = AroundPoint;
335 : :
336 : : //! Diagram placement flags
337 : : LinePlacementFlags mPlacementFlags = OnLine;
338 : :
339 : : /**
340 : : * Placement priority, where 0 = low and 10 = high
341 : : * \note placement priority is shared with labeling, so diagrams with a high priority may displace labels
342 : : * and vice-versa
343 : : */
344 : : int mPriority = 5;
345 : :
346 : : //! Z-index of diagrams, where diagrams with a higher z-index are drawn on top of diagrams with a lower z-index
347 : : double mZIndex = 0.0;
348 : :
349 : : //! Whether associated feature acts as an obstacle for other labels or diagrams
350 : : bool mObstacle = false;
351 : :
352 : : //! Distance between diagram and the feature (in mm)
353 : : double mDistance = 0.0;
354 : :
355 : : //! Associated diagram renderer. Owned by this object.
356 : : QgsDiagramRenderer *mRenderer = nullptr;
357 : :
358 : : //! Whether to show all diagrams, including overlapping diagrams
359 : : bool mShowAll = true;
360 : :
361 : : //! Property collection for data defined diagram settings
362 : : QgsPropertyCollection mDataDefinedProperties;
363 : :
364 : : static void initPropertyDefinitions();
365 : :
366 : : //! Property definitions
367 : : static QgsPropertiesDefinition sPropertyDefinitions;
368 : :
369 : : };
370 : :
371 : : /**
372 : : * \ingroup core
373 : : * \class QgsDiagramSettings
374 : : * \brief Stores the settings for rendering a single diagram.
375 : : *
376 : : * QgsDiagramSettings stores the settings related to rendering the individual diagrams themselves, while
377 : : * QgsDiagramLayerSettings stores settings which control how ALL diagrams within a layer are rendered.
378 : : */
379 : :
380 : : class CORE_EXPORT QgsDiagramSettings
381 : : {
382 : : public:
383 : :
384 : : enum LabelPlacementMethod
385 : : {
386 : : Height,
387 : : XHeight
388 : : };
389 : :
390 : : //! Orientation of histogram
391 : : enum DiagramOrientation
392 : : {
393 : : Up,
394 : : Down,
395 : : Left,
396 : : Right
397 : : };
398 : :
399 : : /**
400 : : * Angular directions.
401 : : * \since QGIS 3.12
402 : : */
403 : : enum Direction
404 : : {
405 : : Clockwise, //!< Clockwise orientation
406 : : Counterclockwise, //!< Counter-clockwise orientation
407 : : };
408 : :
409 : : //! Constructor for QgsDiagramSettings
410 : : QgsDiagramSettings();
411 : : ~QgsDiagramSettings();
412 : :
413 : : //! Copy constructor
414 : : QgsDiagramSettings( const QgsDiagramSettings &other );
415 : :
416 : : QgsDiagramSettings &operator=( const QgsDiagramSettings &other );
417 : :
418 : : bool enabled = true;
419 : : QFont font;
420 : : QList< QColor > categoryColors;
421 : : QList< QString > categoryAttributes;
422 : : //! \since QGIS 2.10
423 : : QList< QString > categoryLabels;
424 : : QSizeF size; //size
425 : :
426 : : /**
427 : : * Diagram size unit
428 : : */
429 : : QgsUnitTypes::RenderUnit sizeType = QgsUnitTypes::RenderMillimeters;
430 : :
431 : : /**
432 : : * Diagram size unit scale
433 : : * \since QGIS 2.16
434 : : */
435 : : QgsMapUnitScale sizeScale;
436 : :
437 : : /**
438 : : * Line unit index
439 : : * \since QGIS 2.16
440 : : */
441 : : QgsUnitTypes::RenderUnit lineSizeUnit = QgsUnitTypes::RenderMillimeters;
442 : :
443 : : /**
444 : : * Line unit scale
445 : : * \since QGIS 2.16
446 : : */
447 : : QgsMapUnitScale lineSizeScale;
448 : :
449 : : QColor backgroundColor;
450 : : QColor penColor;
451 : : double penWidth = 0.0;
452 : : LabelPlacementMethod labelPlacementMethod = QgsDiagramSettings::Height;
453 : : DiagramOrientation diagramOrientation = QgsDiagramSettings::Up;
454 : : double barWidth = 5.0;
455 : :
456 : : //! Opacity, from 0 (transparent) to 1.0 (opaque)
457 : : double opacity = 1.0;
458 : :
459 : : bool scaleByArea = true;
460 : :
461 : : /**
462 : : * Rotation offset, in degrees clockwise from horizontal.
463 : : * \since QGIS 3.0
464 : : */
465 : : double rotationOffset = 270;
466 : :
467 : : bool scaleBasedVisibility = false;
468 : :
469 : : /**
470 : : * The maximum map scale (i.e. most "zoomed in" scale) at which the diagrams will be visible.
471 : : * The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
472 : : * A scale of 0 indicates no maximum scale visibility.
473 : : * \see minimumScale
474 : : */
475 : : double maximumScale = 0;
476 : :
477 : : /**
478 : : * The minimum map scale (i.e. most "zoomed out" scale) at which the diagrams will be visible.
479 : : * The scale value indicates the scale denominator, e.g. 1000.0 for a 1:1000 map.
480 : : * A scale of 0 indicates no minimum scale visibility.
481 : : * \see maximumScale
482 : : */
483 : : double minimumScale = 0;
484 : :
485 : : //! Scale diagrams smaller than mMinimumSize to mMinimumSize
486 : : double minimumSize = 0.0;
487 : :
488 : : /**
489 : : * Returns the spacing between diagram contents.
490 : : *
491 : : * Spacing units can be retrieved by calling spacingUnit().
492 : : *
493 : : * \see setSpacing()
494 : : * \see spacingUnit()
495 : : * \see spacingMapUnitScale()
496 : : *
497 : : * \since QGIS 3.12
498 : : */
499 : 0 : double spacing() const { return mSpacing; }
500 : :
501 : : /**
502 : : * Sets the \a spacing between diagram contents.
503 : : *
504 : : * Spacing units are set via setSpacingUnit().
505 : : *
506 : : * \see spacing()
507 : : * \see setSpacingUnit()
508 : : * \see setSpacingMapUnitScale()
509 : : *
510 : : * \since QGIS 3.12
511 : : */
512 : : void setSpacing( double spacing ) { mSpacing = spacing; }
513 : :
514 : : /**
515 : : * Sets the \a unit for the content spacing.
516 : : * \see spacingUnit()
517 : : * \see setSpacing()
518 : : * \see setSpacingMapUnitScale()
519 : : *
520 : : * \since QGIS 3.12
521 : : */
522 : : void setSpacingUnit( QgsUnitTypes::RenderUnit unit ) { mSpacingUnit = unit; }
523 : :
524 : : /**
525 : : * Returns the units for the content spacing.
526 : : * \see setSpacingUnit()
527 : : * \see spacing()
528 : : * \see spacingMapUnitScale()
529 : : * \since QGIS 3.12
530 : : */
531 : 0 : QgsUnitTypes::RenderUnit spacingUnit() const { return mSpacingUnit; }
532 : :
533 : : /**
534 : : * Sets the map unit \a scale for the content spacing.
535 : : * \see spacingMapUnitScale()
536 : : * \see setSpacing()
537 : : * \see setSpacingUnit()
538 : : *
539 : : * \since QGIS 3.12
540 : : */
541 : : void setSpacingMapUnitScale( const QgsMapUnitScale &scale ) { mSpacingMapUnitScale = scale; }
542 : :
543 : : /**
544 : : * Returns the map unit scale for the content spacing.
545 : : * \see setSpacingMapUnitScale()
546 : : * \see spacing()
547 : : * \see spacingUnit()
548 : : *
549 : : * \since QGIS 3.12
550 : : */
551 : 0 : const QgsMapUnitScale &spacingMapUnitScale() const { return mSpacingMapUnitScale; }
552 : :
553 : : /**
554 : : * Returns the chart's angular direction.
555 : : *
556 : : * \see setDirection()
557 : : * \since QGIS 3.12
558 : : */
559 : : Direction direction() const;
560 : :
561 : : /**
562 : : * Sets the chart's angular \a direction.
563 : : *
564 : : * \see direction()
565 : : * \since QGIS 3.12
566 : : */
567 : : void setDirection( Direction direction );
568 : :
569 : : //! Reads diagram settings from XML
570 : : void readXml( const QDomElement &elem, const QgsReadWriteContext &context = QgsReadWriteContext() );
571 : : //! Writes diagram settings to XML
572 : : void writeXml( QDomElement &rendererElem, QDomDocument &doc, const QgsReadWriteContext &context = QgsReadWriteContext() ) const;
573 : :
574 : : /**
575 : : * Returns list of legend nodes for the diagram
576 : : * \note caller is responsible for deletion of QgsLayerTreeModelLegendNodes
577 : : * \since QGIS 2.10
578 : : */
579 : : QList< QgsLayerTreeModelLegendNode * > legendItems( QgsLayerTreeLayer *nodeLayer ) const SIP_FACTORY;
580 : :
581 : : /**
582 : : * Returns the line symbol to use for rendering axis in diagrams.
583 : : *
584 : : * \see setAxisLineSymbol()
585 : : * \see showAxis()
586 : : *
587 : : * \since QGIS 3.12
588 : : */
589 : : QgsLineSymbol *axisLineSymbol() const;
590 : :
591 : : /**
592 : : * Sets the line \a symbol to use for rendering axis in diagrams.
593 : : *
594 : : * Ownership of \a symbol is transferred to the settings.
595 : : *
596 : : * \see axisLineSymbol()
597 : : * \see setShowAxis()
598 : : *
599 : : * \since QGIS 3.12
600 : : */
601 : : void setAxisLineSymbol( QgsLineSymbol *symbol SIP_TRANSFER );
602 : :
603 : : /**
604 : : * Returns TRUE if the diagram axis should be shown.
605 : : *
606 : : * \see setShowAxis()
607 : : * \see axisLineSymbol()
608 : : *
609 : : * \since QGIS 3.12
610 : : */
611 : : bool showAxis() const;
612 : :
613 : : /**
614 : : * Sets whether the diagram axis should be shown.
615 : : *
616 : : * \see showAxis()
617 : : * \see setAxisLineSymbol()
618 : : *
619 : : * \since QGIS 3.12
620 : : */
621 : : void setShowAxis( bool showAxis );
622 : :
623 : : /**
624 : : * Returns the paint effect to use while rendering diagrams.
625 : : *
626 : : * \see setPaintEffect()
627 : : *
628 : : * \since QGIS 3.12
629 : : */
630 : : QgsPaintEffect *paintEffect() const;
631 : :
632 : : /**
633 : : * Sets the paint \a effect to use while rendering diagrams.
634 : : *
635 : : * Ownership of \a effect is transferred to the settings.
636 : : *
637 : : * \see paintEffect()
638 : : *
639 : : * \since QGIS 3.12
640 : : */
641 : : void setPaintEffect( QgsPaintEffect *effect SIP_TRANSFER );
642 : :
643 : : private:
644 : :
645 : : double mSpacing = 0;
646 : : QgsUnitTypes::RenderUnit mSpacingUnit = QgsUnitTypes::RenderMillimeters;
647 : : QgsMapUnitScale mSpacingMapUnitScale;
648 : : Direction mDirection = Counterclockwise;
649 : :
650 : : bool mShowAxis = false;
651 : : std::unique_ptr< QgsLineSymbol > mAxisLineSymbol;
652 : : std::unique_ptr< QgsPaintEffect > mPaintEffect;
653 : :
654 : : };
655 : :
656 : : /**
657 : : * \ingroup core
658 : : * \class QgsDiagramInterpolationSettings
659 : : * \brief Additional diagram settings for interpolated size rendering.
660 : : */
661 : 0 : class CORE_EXPORT QgsDiagramInterpolationSettings
662 : : {
663 : : public:
664 : : QSizeF lowerSize;
665 : : QSizeF upperSize;
666 : : double lowerValue;
667 : : double upperValue;
668 : :
669 : : //! Name of the field for classification
670 : : QString classificationField;
671 : :
672 : : QString classificationAttributeExpression;
673 : : bool classificationAttributeIsExpression;
674 : : };
675 : :
676 : :
677 : : /**
678 : : * \ingroup core
679 : : * \class QgsDiagramRenderer
680 : : * \brief Evaluates and returns the diagram settings relating to a diagram for a specific feature.
681 : : */
682 : :
683 : : class CORE_EXPORT QgsDiagramRenderer
684 : : {
685 : :
686 : : #ifdef SIP_RUN
687 : : SIP_CONVERT_TO_SUBCLASS_CODE
688 : : if ( sipCpp->rendererName() == QLatin1String( "SingleCategory" ) )
689 : : sipType = sipType_QgsSingleCategoryDiagramRenderer;
690 : : else if ( sipCpp->rendererName() == QLatin1String( "LinearlyInterpolated" ) )
691 : : sipType = sipType_QgsLinearlyInterpolatedDiagramRenderer;
692 : : else
693 : : sipType = NULL;
694 : : SIP_END
695 : : #endif
696 : :
697 : : public:
698 : :
699 : : /**
700 : : * Constructor for QgsDiagramRenderer.
701 : : */
702 : 0 : QgsDiagramRenderer() = default;
703 : 0 : virtual ~QgsDiagramRenderer() = default;
704 : :
705 : : /**
706 : : * Returns new instance that is equivalent to this one
707 : : * \since QGIS 2.4
708 : : */
709 : : virtual QgsDiagramRenderer *clone() const = 0 SIP_FACTORY;
710 : :
711 : : //! Returns size of the diagram for a feature in map units. Returns an invalid QSizeF in case of error
712 : : virtual QSizeF sizeMapUnits( const QgsFeature &feature, const QgsRenderContext &c ) const;
713 : :
714 : : virtual QString rendererName() const = 0;
715 : :
716 : : //! Returns attribute indices needed for diagram rendering
717 : : virtual QList<QString> diagramAttributes() const = 0;
718 : :
719 : : /**
720 : : * Returns the set of any fields required for diagram rendering
721 : : * \param context expression context the diagrams will be drawn using
722 : : * \since QGIS 2.16
723 : : */
724 : : virtual QSet< QString > referencedFields( const QgsExpressionContext &context = QgsExpressionContext() ) const;
725 : :
726 : : /**
727 : : * Renders the diagram for a specified feature at a specific position in the passed render context.
728 : : */
729 : : void renderDiagram( const QgsFeature &feature, QgsRenderContext &c, QPointF pos, const QgsPropertyCollection &properties = QgsPropertyCollection() ) const;
730 : :
731 : : void setDiagram( QgsDiagram *d SIP_TRANSFER );
732 : : QgsDiagram *diagram() const { return mDiagram.get(); }
733 : :
734 : : //! Returns list with all diagram settings in the renderer
735 : : virtual QList<QgsDiagramSettings> diagramSettings() const = 0;
736 : :
737 : : /**
738 : : * Reads diagram state from a DOM element. Subclasses should ensure that _readXml() is called
739 : : * by their readXml implementation to restore the general QgsDiagramRenderer settings.
740 : : * \see writeXml()
741 : : */
742 : : virtual void readXml( const QDomElement &elem, const QgsReadWriteContext &context ) = 0;
743 : :
744 : : /**
745 : : * Writes diagram state to a DOM element. Subclasses should ensure that _writeXml() is called
746 : : * by their writeXml implementation to save the general QgsDiagramRenderer settings.
747 : : * \see readXml()
748 : : */
749 : : virtual void writeXml( QDomElement &layerElem, QDomDocument &doc, const QgsReadWriteContext &context ) const = 0;
750 : :
751 : : /**
752 : : * Returns list of legend nodes for the diagram
753 : : * \note caller is responsible for deletion of QgsLayerTreeModelLegendNodes
754 : : * \since QGIS 2.10
755 : : */
756 : : virtual QList< QgsLayerTreeModelLegendNode * > legendItems( QgsLayerTreeLayer *nodeLayer ) const SIP_FACTORY;
757 : :
758 : : /**
759 : : * Returns TRUE if renderer will show legend items for diagram attributes.
760 : : * \see setAttributeLegend()
761 : : * \since QGIS 2.16
762 : : */
763 : : bool attributeLegend() const { return mShowAttributeLegend; }
764 : :
765 : : /**
766 : : * Sets whether the renderer will show legend items for diagram attributes.
767 : : * \param enabled set to TRUE to show diagram attribute legend
768 : : * \see attributeLegend()
769 : : * \since QGIS 2.16
770 : : */
771 : : void setAttributeLegend( bool enabled ) { mShowAttributeLegend = enabled; }
772 : :
773 : : protected:
774 : : QgsDiagramRenderer( const QgsDiagramRenderer &other );
775 : : QgsDiagramRenderer &operator=( const QgsDiagramRenderer &other );
776 : :
777 : : /**
778 : : * Returns diagram settings for a feature (or FALSE if the diagram for the feature is not to be rendered). Used internally within renderDiagram()
779 : : * \param feature the feature
780 : : * \param c render context
781 : : * \param s out: diagram settings for the feature
782 : : */
783 : : virtual bool diagramSettings( const QgsFeature &feature, const QgsRenderContext &c, QgsDiagramSettings &s ) const = 0;
784 : :
785 : : //! Returns size of the diagram (in painter units) or an invalid size in case of error
786 : : virtual QSizeF diagramSize( const QgsFeature &features, const QgsRenderContext &c ) const = 0;
787 : :
788 : : //! Converts size from mm to map units
789 : : void convertSizeToMapUnits( QSizeF &size, const QgsRenderContext &context ) const;
790 : :
791 : : //! Returns the paint device dpi (or -1 in case of error
792 : : static int dpiPaintDevice( const QPainter * );
793 : :
794 : : //read / write diagram
795 : :
796 : : /**
797 : : * Reads internal QgsDiagramRenderer state from a DOM element.
798 : : * \see _writeXml()
799 : : */
800 : : void _readXml( const QDomElement &elem, const QgsReadWriteContext &context );
801 : :
802 : : /**
803 : : * Writes internal QgsDiagramRenderer diagram state to a DOM element.
804 : : * \see _readXml()
805 : : */
806 : : void _writeXml( QDomElement &rendererElem, QDomDocument &doc, const QgsReadWriteContext &context ) const;
807 : :
808 : : //! Reference to the object that does the real diagram rendering
809 : : std::unique_ptr< QgsDiagram > mDiagram;
810 : :
811 : : //! Whether to show an attribute legend for the diagrams
812 : 0 : bool mShowAttributeLegend = true;
813 : : };
814 : :
815 : : /**
816 : : * \ingroup core
817 : : * \brief Renders the diagrams for all features with the same settings
818 : : */
819 : 0 : class CORE_EXPORT QgsSingleCategoryDiagramRenderer : public QgsDiagramRenderer
820 : : {
821 : : public:
822 : :
823 : : //! Constructor for QgsSingleCategoryDiagramRenderer
824 : 0 : QgsSingleCategoryDiagramRenderer() = default;
825 : :
826 : : QgsSingleCategoryDiagramRenderer *clone() const override SIP_FACTORY;
827 : :
828 : 0 : QString rendererName() const override { return QStringLiteral( "SingleCategory" ); }
829 : :
830 : 0 : QList<QString> diagramAttributes() const override { return mSettings.categoryAttributes; }
831 : :
832 : : void setDiagramSettings( const QgsDiagramSettings &s ) { mSettings = s; }
833 : :
834 : : QList<QgsDiagramSettings> diagramSettings() const override;
835 : :
836 : : void readXml( const QDomElement &elem, const QgsReadWriteContext &context ) override;
837 : : void writeXml( QDomElement &layerElem, QDomDocument &doc, const QgsReadWriteContext &context ) const override;
838 : :
839 : : QList< QgsLayerTreeModelLegendNode * > legendItems( QgsLayerTreeLayer *nodeLayer ) const override SIP_FACTORY;
840 : :
841 : : protected:
842 : : bool diagramSettings( const QgsFeature &feature, const QgsRenderContext &c, QgsDiagramSettings &s ) const override;
843 : :
844 : : QSizeF diagramSize( const QgsFeature &, const QgsRenderContext &c ) const override;
845 : :
846 : : private:
847 : : QgsDiagramSettings mSettings;
848 : : };
849 : :
850 : : /**
851 : : * \ingroup core
852 : : * \class QgsLinearlyInterpolatedDiagramRenderer
853 : : */
854 : : class CORE_EXPORT QgsLinearlyInterpolatedDiagramRenderer : public QgsDiagramRenderer
855 : : {
856 : : public:
857 : : QgsLinearlyInterpolatedDiagramRenderer();
858 : : ~QgsLinearlyInterpolatedDiagramRenderer() override;
859 : :
860 : : QgsLinearlyInterpolatedDiagramRenderer *clone() const override SIP_FACTORY;
861 : :
862 : : //! Returns list with all diagram settings in the renderer
863 : : QList<QgsDiagramSettings> diagramSettings() const override;
864 : :
865 : : void setDiagramSettings( const QgsDiagramSettings &s ) { mSettings = s; }
866 : :
867 : : QList<QString> diagramAttributes() const override;
868 : :
869 : : QSet< QString > referencedFields( const QgsExpressionContext &context = QgsExpressionContext() ) const override;
870 : :
871 : 0 : QString rendererName() const override { return QStringLiteral( "LinearlyInterpolated" ); }
872 : :
873 : : void setLowerValue( double val ) { mInterpolationSettings.lowerValue = val; }
874 : : double lowerValue() const { return mInterpolationSettings.lowerValue; }
875 : :
876 : : void setUpperValue( double val ) { mInterpolationSettings.upperValue = val; }
877 : : double upperValue() const { return mInterpolationSettings.upperValue; }
878 : :
879 : : void setLowerSize( QSizeF s ) { mInterpolationSettings.lowerSize = s; }
880 : : QSizeF lowerSize() const { return mInterpolationSettings.lowerSize; }
881 : :
882 : : void setUpperSize( QSizeF s ) { mInterpolationSettings.upperSize = s; }
883 : : QSizeF upperSize() const { return mInterpolationSettings.upperSize; }
884 : :
885 : : /**
886 : : * Returns the field name used for interpolating the diagram size.
887 : : * \see setClassificationField()
888 : : * \since QGIS 3.0
889 : : */
890 : : QString classificationField() const { return mInterpolationSettings.classificationField; }
891 : :
892 : : /**
893 : : * Sets the field name used for interpolating the diagram size.
894 : : * \see classificationField()
895 : : * \since QGIS 3.0
896 : : */
897 : : void setClassificationField( const QString &field ) { mInterpolationSettings.classificationField = field; }
898 : :
899 : : QString classificationAttributeExpression() const { return mInterpolationSettings.classificationAttributeExpression; }
900 : : void setClassificationAttributeExpression( const QString &expression ) { mInterpolationSettings.classificationAttributeExpression = expression; }
901 : :
902 : : bool classificationAttributeIsExpression() const { return mInterpolationSettings.classificationAttributeIsExpression; }
903 : : void setClassificationAttributeIsExpression( bool isExpression ) { mInterpolationSettings.classificationAttributeIsExpression = isExpression; }
904 : :
905 : : void readXml( const QDomElement &elem, const QgsReadWriteContext &context ) override;
906 : : void writeXml( QDomElement &layerElem, QDomDocument &doc, const QgsReadWriteContext &context ) const override;
907 : :
908 : : QList< QgsLayerTreeModelLegendNode * > legendItems( QgsLayerTreeLayer *nodeLayer ) const override SIP_FACTORY;
909 : :
910 : : /**
911 : : * Configures appearance of legend. Takes ownership of the passed settings objects.
912 : : * \since QGIS 3.0
913 : : */
914 : : void setDataDefinedSizeLegend( QgsDataDefinedSizeLegend *settings SIP_TRANSFER );
915 : :
916 : : /**
917 : : * Returns configuration of appearance of legend. Will return NULLPTR if no configuration has been set.
918 : : * \since QGIS 3.0
919 : : */
920 : : QgsDataDefinedSizeLegend *dataDefinedSizeLegend() const;
921 : :
922 : : protected:
923 : : bool diagramSettings( const QgsFeature &feature, const QgsRenderContext &c, QgsDiagramSettings &s ) const override;
924 : :
925 : : QSizeF diagramSize( const QgsFeature &, const QgsRenderContext &c ) const override;
926 : :
927 : : //! Copy constructor
928 : : QgsLinearlyInterpolatedDiagramRenderer( const QgsLinearlyInterpolatedDiagramRenderer &other );
929 : :
930 : : private:
931 : : QgsDiagramSettings mSettings;
932 : : QgsDiagramInterpolationSettings mInterpolationSettings;
933 : :
934 : : //! Stores more settings about how legend for varying size of symbols should be rendered
935 : : QgsDataDefinedSizeLegend *mDataDefinedSizeLegend = nullptr;
936 : :
937 : : QgsLinearlyInterpolatedDiagramRenderer &operator=( const QgsLinearlyInterpolatedDiagramRenderer & ) = delete;
938 : : };
939 : :
940 : : #endif // QGSDIAGRAMRENDERER_H
|