File indexing completed on 2024-06-16 04:09:13
0001 /* 0002 * SPDX-FileCopyrightText: 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. 0003 * 0004 * This file is part of the KD Chart library. 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #ifndef KCHARTPIEDIAGRAM_H 0010 #define KCHARTPIEDIAGRAM_H 0011 0012 #include "KChartAbstractPieDiagram.h" 0013 0014 namespace KChart { 0015 0016 class LabelPaintCache; 0017 0018 /** 0019 * @brief PieDiagram defines a common pie diagram 0020 */ 0021 class KCHART_EXPORT PieDiagram : public AbstractPieDiagram 0022 { 0023 Q_OBJECT 0024 0025 Q_DISABLE_COPY( PieDiagram ) 0026 KCHART_DECLARE_DERIVED_DIAGRAM( PieDiagram, PolarCoordinatePlane ) 0027 0028 public: 0029 explicit PieDiagram( 0030 QWidget* parent = nullptr, PolarCoordinatePlane* plane = nullptr ); 0031 ~PieDiagram() override; 0032 0033 protected: 0034 // Implement AbstractDiagram 0035 /** \reimpl */ 0036 void paint( PaintContext* paintContext ) override; 0037 0038 public: 0039 /** 0040 * Describes which decorations are painted around data labels. 0041 */ 0042 enum LabelDecoration { 0043 NoDecoration = 0, ///< No decoration 0044 FrameDecoration = 1, ///< A rectangular frame is painted around the label text 0045 LineFromSliceDecoration = 2 ///< A line is drawn from the pie slice to its label 0046 }; 0047 Q_DECLARE_FLAGS( LabelDecorations, LabelDecoration ) 0048 /// Set the decorations to be painted around data labels according to @p decorations. 0049 void setLabelDecorations( LabelDecorations decorations ); 0050 /// Return the decorations to be painted around data labels. 0051 LabelDecorations labelDecorations() const; 0052 0053 /// If @p enabled is set to true, labels that would overlap will be shuffled to avoid overlap. 0054 /// \note Collision avoidance may allow labels to be closer than AbstractDiagram with 0055 /// allowOverlappingDataValueTexts() == false, so you should usually also call 0056 /// setAllowOverlappingDataValueTexts( true ) if you enable this feature. 0057 void setLabelCollisionAvoidanceEnabled( bool enabled ); 0058 /// Return whether overlapping labels will be moved to until they don't overlap anymore. 0059 bool isLabelCollisionAvoidanceEnabled() const; 0060 0061 /** \reimpl */ 0062 void resize ( const QSizeF& area ) override; 0063 0064 // Implement AbstractPolarDiagram 0065 /** \reimpl */ 0066 qreal valueTotals () const override; 0067 /** \reimpl */ 0068 qreal numberOfValuesPerDataset() const override; 0069 /** \reimpl */ 0070 qreal numberOfGridRings() const override; 0071 0072 0073 /** 0074 * Creates an exact copy of this diagram. 0075 */ 0076 virtual PieDiagram * clone() const; 0077 0078 protected: 0079 /** \reimpl */ 0080 const QPair<QPointF, QPointF> calculateDataBoundaries() const override; 0081 void paintEvent( QPaintEvent* ) override; 0082 void resizeEvent( QResizeEvent* ) override; 0083 0084 private: 0085 // ### move to private class? 0086 void placeLabels( PaintContext* paintContext ); 0087 // Solve problems with label overlap by changing label positions inside d->labelPaintCache. 0088 void shuffleLabels( QRectF* textBoundingRect ); 0089 void paintInternal( PaintContext* paintContext ); 0090 0091 /** 0092 Internal method that draws one of the slices in a pie chart. 0093 0094 \param painter the QPainter to draw in 0095 \param dataset the dataset to draw the pie for 0096 \param slice the slice to draw 0097 \param threeDPieHeight the height of the three dimensional effect 0098 */ 0099 void drawSlice( QPainter* painter, const QRectF& drawPosition, uint slice ); 0100 0101 /** 0102 Internal method that draws the surface of one of the slices in a pie chart. 0103 0104 \param painter the QPainter to draw in 0105 \param dataset the dataset to draw the slice for 0106 \param slice the slice to draw 0107 */ 0108 void drawSliceSurface( QPainter* painter, const QRectF& drawPosition, uint slice ); 0109 void addSliceLabel( LabelPaintCache* lpc, const QRectF& drawPosition, uint slice ); 0110 0111 /** 0112 Internal method that draws the shadow creating the 3D effect of a pie 0113 0114 \param painter the QPainter to draw in 0115 \param drawPosition the position to draw at 0116 \param slice the slice to draw the shadow for 0117 */ 0118 void draw3DEffect( QPainter* painter, const QRectF& drawPosition, uint slice ); 0119 0120 /** 0121 Internal method that draws the cut surface of a slice (think of a real pie cut into slices) 0122 in 3D mode, for surfaces that are facing the observer. 0123 0124 \param painter the QPainter to draw in 0125 \param rect the position to draw at 0126 \param threeDHeight the height of the shadow 0127 \param angle the angle of the segment 0128 */ 0129 void draw3dCutSurface( QPainter* painter, 0130 const QRectF& rect, 0131 qreal threeDHeight, 0132 qreal angle ); 0133 0134 /** 0135 Internal method that draws the outer rim of a slice when the rim is facing the observer. 0136 0137 \param painter the QPainter to draw in 0138 \param rect the position to draw at 0139 \param threeDHeight the height of the shadow 0140 \param startAngle the starting angle of the segment 0141 \param endAngle the ending angle of the segment 0142 */ 0143 void draw3dOuterRim( QPainter* painter, 0144 const QRectF& rect, 0145 qreal threeDHeight, 0146 qreal startAngle, 0147 qreal endAngle ); 0148 void calcSliceAngles(); 0149 void calcPieSize( const QRectF &contentsRect ); 0150 QRectF twoDPieRect( const QRectF &contentsRect, const ThreeDPieAttributes& threeDAttrs ) const; 0151 QRectF explodedDrawPosition( const QRectF& drawPosition, uint slice ) const; 0152 0153 /** 0154 Internal method that finds the slice that is located at the position specified by \c angle. 0155 0156 \param angle the angle at which to search for a slice 0157 \return the number of the slice found 0158 */ 0159 uint findSliceAt( qreal angle, int columnCount ); 0160 0161 /** 0162 Internal method that finds the slice that is located to the left of \c slice. 0163 0164 \param slice the slice to start the search from 0165 \return the number of the pie to the left of \c pie 0166 */ 0167 uint findLeftSlice( uint slice, int columnCount ); 0168 0169 /** 0170 Internal method that finds the slice that is located to the right of \c slice. 0171 0172 \param slice the slice to start the search from 0173 \return the number of the slice to the right of \c slice 0174 */ 0175 uint findRightSlice( uint slice, int columnCount ); 0176 0177 /** 0178 * Auxiliary method returning a point to a given boundary 0179 * rectangle of the enclosed ellipse and an angle. 0180 */ 0181 QPointF pointOnEllipse( const QRectF& boundingBox, qreal angle ); 0182 }; // End of class KChartPieDiagram 0183 0184 Q_DECLARE_OPERATORS_FOR_FLAGS( PieDiagram::LabelDecorations ) 0185 0186 } 0187 #endif // KCHARTPIEDIAGRAM_H