File indexing completed on 2024-05-12 04:20:35
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 KCHARTLEGEND_H 0010 #define KCHARTLEGEND_H 0011 0012 #include "KChartAbstractAreaWidget.h" 0013 #include "KChartPosition.h" 0014 #include "KChartMarkerAttributes.h" 0015 0016 class QTextTable; 0017 0018 namespace KChart { 0019 0020 class AbstractDiagram; 0021 typedef QList<AbstractDiagram*> DiagramList; 0022 typedef QList<const AbstractDiagram*> ConstDiagramList; 0023 0024 /** 0025 * @brief Legend defines the interface for the legend drawing class. 0026 * 0027 * Legend is the class for drawing legends for all kinds of diagrams ("chart types"). 0028 * 0029 * Legend is drawn on chart level, not per diagram, but you can have more than one 0030 * legend per chart, using KChart::Chart::addLegend(). 0031 * 0032 * \note Legend is different from all other classes of KChart, since it can be 0033 * displayed outside of the Chart's area. If you want to, you can embed the legend 0034 * into your own widget, or into another part of a bigger layout, into which you might 0035 * have inserted the Chart. 0036 * 0037 * On the other hand, please note that you MUST call Chart::addLegend to get your 0038 * legend positioned into the correct place of your chart - if you want to have 0039 * the legend shown inside of the chart (that's probably true for most cases). 0040 */ 0041 class KCHART_EXPORT Legend : public AbstractAreaWidget 0042 { 0043 Q_OBJECT 0044 0045 Q_DISABLE_COPY( Legend ) 0046 KCHART_DECLARE_PRIVATE_DERIVED_QWIDGET( Legend ) 0047 0048 public: 0049 explicit Legend( QWidget* parent = nullptr ); 0050 explicit Legend( KChart::AbstractDiagram* diagram, QWidget* parent = nullptr ); 0051 ~Legend() override; 0052 0053 0054 enum LegendStyle { MarkersOnly = 0, 0055 LinesOnly = 1, 0056 MarkersAndLines = 2 }; 0057 0058 0059 void setLegendStyle( LegendStyle style ); 0060 LegendStyle legendStyle() const; 0061 0062 0063 0064 /** 0065 * Creates an exact copy of this legend. 0066 */ 0067 virtual Legend * clone() const; 0068 0069 /** 0070 * Returns true if both legends have the same settings. 0071 */ 0072 bool compare( const Legend* other ) const; 0073 0074 void resizeEvent( QResizeEvent * event ) override; // TODO: should be protected 0075 0076 virtual void paint( QPainter* painter ) override; 0077 void paint( QPainter* painter, const QRect &rect); 0078 void setVisible( bool visible ) override; 0079 0080 /** 0081 Specifies the reference area for font size of title text, 0082 and for font size of the item texts, IF automatic area 0083 detection is set. 0084 0085 \note This parameter is ignored, if the Measure given for 0086 setTitleTextAttributes (or setTextAttributes, resp.) is 0087 not specifying automatic area detection. 0088 0089 If no reference area is specified, but automatic area 0090 detection is set, then the size of the legend's parent 0091 widget will be used. 0092 0093 \sa KChart::Measure, KChartEnums::MeasureCalculationMode 0094 */ 0095 void setReferenceArea( const QWidget* area ); 0096 /** 0097 Returns the reference area, that is used for font size of title text, 0098 and for font size of the item texts, IF automatic area 0099 detection is set. 0100 0101 \sa setReferenceArea 0102 */ 0103 const QWidget* referenceArea() const; 0104 0105 /** 0106 * The first diagram of the legend or 0 if there was none added to the legend. 0107 * @return The first diagram of the legend or 0. 0108 * 0109 * \sa diagrams, addDiagram, removeDiagram, removeDiagrams, replaceDiagram, setDiagram 0110 */ 0111 KChart::AbstractDiagram* diagram() const; 0112 0113 /** 0114 * The list of all diagrams associated with the legend. 0115 * @return The list of all diagrams associated with the legend. 0116 * 0117 * \sa diagram, addDiagram, removeDiagram, removeDiagrams, replaceDiagram, setDiagram 0118 */ 0119 DiagramList diagrams() const; 0120 0121 /** 0122 * @return The list of diagrams associated with this legend. 0123 */ 0124 ConstDiagramList constDiagrams() const; 0125 0126 /** 0127 * Add the given diagram to the legend. 0128 * @param newDiagram The diagram to add. 0129 * 0130 * \sa diagram, diagrams, removeDiagram, removeDiagrams, replaceDiagram, setDiagram 0131 */ 0132 void addDiagram( KChart::AbstractDiagram* newDiagram ); 0133 0134 /** 0135 * Removes the diagram from the legend's list of diagrams. 0136 * 0137 * \sa diagram, diagrams, addDiagram, removeDiagrams, replaceDiagram, setDiagram 0138 */ 0139 void removeDiagram( KChart::AbstractDiagram* oldDiagram ); 0140 0141 /** 0142 * Removes all diagrams from the legend's list of diagrams. 0143 * 0144 * \sa diagram, diagrams, addDiagram, removeDiagram, replaceDiagram, setDiagram 0145 */ 0146 void removeDiagrams(); 0147 0148 /** 0149 * Replaces the old diagram, or appends the 0150 * new diagram, it there is none yet. 0151 * 0152 * @param newDiagram The diagram to be used instead of the old one. 0153 * If this parameter is zero, the first diagram will just be removed. 0154 * 0155 * @param oldDiagram The diagram to be removed by the new one. This 0156 * diagram will be deleted automatically. If the parameter is omitted, 0157 * the very first diagram will be replaced. In case, there was no 0158 * diagram yet, the new diagram will just be added. 0159 * 0160 * \sa diagram, diagrams, addDiagram, removeDiagram, removeDiagrams, setDiagram 0161 */ 0162 void replaceDiagram( KChart::AbstractDiagram* newDiagram, 0163 KChart::AbstractDiagram* oldDiagram = nullptr ); 0164 0165 /** 0166 * Returns the offset of the first dataset of \c diagram. 0167 * 0168 */ 0169 uint dataSetOffset( KChart::AbstractDiagram* diagram ); 0170 0171 /** 0172 * @brief A convenience method doing the same as replaceDiagram( newDiagram, 0 ); 0173 * 0174 * Replaces the first diagram by the given diagram. 0175 * If the legend's list of diagram is empty the given diagram is added to the list. 0176 * 0177 * \sa diagram, diagrams, addDiagram, removeDiagram, removeDiagrams, replaceDiagram 0178 */ 0179 void setDiagram( KChart::AbstractDiagram* newDiagram ); 0180 0181 /** 0182 * \brief Specify the position of a non-floating legend. 0183 * 0184 * Use setFloatingPosition to set position and alignment 0185 * if your legend is floating. 0186 * 0187 * \sa setAlignment, setFloatingPosition 0188 */ 0189 void setPosition( Position position ); 0190 0191 /** 0192 * Returns the position of a non-floating legend. 0193 * \sa setPosition 0194 */ 0195 Position position() const; 0196 0197 /** 0198 * \brief Specify the alignment of a non-floating legend. 0199 * 0200 * Use setFloatingPosition to set position and alignment 0201 * if your legend is floating. 0202 * 0203 * \sa alignment, setPosition, setFloatingPosition 0204 */ 0205 void setAlignment( Qt::Alignment ); 0206 0207 /** 0208 * Returns the alignment of a non-floating legend. 0209 * \sa setAlignment 0210 */ 0211 Qt::Alignment alignment() const; 0212 0213 /** 0214 * \brief Specify the alignment of the text elements within the legend 0215 * 0216 * \sa textAlignment() 0217 */ 0218 void setTextAlignment( Qt::Alignment ); 0219 0220 /** 0221 * \brief Returns the alignment used while rendering text elements within the legend. 0222 * 0223 * \sa setTextAlignment() 0224 */ 0225 Qt::Alignment textAlignment() const; 0226 0227 /** 0228 * \brief Specify the alignment of the legend symbol( alignment of Legend::LinesOnly) 0229 * within the legend 0230 * 0231 * \sa legendSymbolAlignment() 0232 */ 0233 void setLegendSymbolAlignment(Qt::Alignment); 0234 0235 /** 0236 * \brief Returns the alignment used while drawing legend symbol(alignment of Legend::LinesOnly) 0237 * within the legend. 0238 * 0239 * \sa setLegendSymbolAlignment() 0240 */ 0241 Qt::Alignment legendSymbolAlignment() const; 0242 0243 /** 0244 * \brief Specify the position and alignment of a floating legend. 0245 * 0246 * Use setPosition and setAlignment to set position and alignment 0247 * if your legend is non-floating. 0248 * 0249 * \note When setFloatingPosition is called, the Legend's position value is set to 0250 * KChart::Position::Floating automatically. 0251 * 0252 * If your Chart is pointed to by m_chart, your could have the floating legend 0253 * aligned exactly to the chart's coordinate plane's top-right corner 0254 * with the following commands: 0255 \verbatim 0256 KChart::RelativePosition relativePosition; 0257 relativePosition.setReferenceArea( m_chart->coordinatePlane() ); 0258 relativePosition.setReferencePosition( Position::NorthEast ); 0259 relativePosition.setAlignment( Qt::AlignTop | Qt::AlignRight ); 0260 relativePosition.setHorizontalPadding( 0261 KChart::Measure( -1.0, KChartEnums::MeasureCalculationModeAbsolute ) ); 0262 relativePosition.setVerticalPadding( 0263 KChart::Measure( 0.0, KChartEnums::MeasureCalculationModeAbsolute ) ); 0264 m_legend->setFloatingPosition( relativePosition ); 0265 \endverbatim 0266 * 0267 * To have the legend positioned at a fixed point, measured from the QPainter's top left corner, 0268 * you could use the following code code: 0269 * 0270 \verbatim 0271 KChart::RelativePosition relativePosition; 0272 relativePosition.setReferencePoints( PositionPoints( QPointF( 0.0, 0.0 ) ) ); 0273 relativePosition.setReferencePosition( Position::NorthWest ); 0274 relativePosition.setAlignment( Qt::AlignTop | Qt::AlignLeft ); 0275 relativePosition.setHorizontalPadding( 0276 KChart::Measure( 4.0, KChartEnums::MeasureCalculationModeAbsolute ) ); 0277 relativePosition.setVerticalPadding( 0278 KChart::Measure( 4.0, KChartEnums::MeasureCalculationModeAbsolute ) ); 0279 m_legend->setFloatingPosition( relativePosition ); 0280 \endverbatim 0281 * Actually that's exactly the code KChart is using as default position for any floating legends, 0282 * so if you just say setPosition( KChart::Position::Floating ) without calling setFloatingPosition 0283 * your legend will be positioned at point 4/4. 0284 * 0285 * \sa setPosition, setAlignment 0286 */ 0287 void setFloatingPosition( const RelativePosition& relativePosition ); 0288 0289 /** 0290 * Returns the position of a floating legend. 0291 * \sa setFloatingPosition 0292 */ 0293 const RelativePosition floatingPosition() const; 0294 0295 void setOrientation( Qt::Orientation orientation ); 0296 Qt::Orientation orientation() const; 0297 0298 0299 void setSortOrder( Qt::SortOrder order ); 0300 Qt::SortOrder sortOrder() const; 0301 0302 void setShowLines( bool legendShowLines ); 0303 bool showLines() const; 0304 0305 0306 /** 0307 \brief Removes all legend texts that might have been set by setText. 0308 0309 This resets the Legend to default behaviour: Texts are created automatically. 0310 */ 0311 void resetTexts(); 0312 void setText( uint dataset, const QString& text ); 0313 QString text( uint dataset ) const; 0314 const QMap<uint,QString> texts() const; 0315 0316 /** 0317 * Sets a list of datasets that are to be hidden in the legend. 0318 * 0319 * By passing an empty list, you show all datasets. 0320 * All datasets are shown by default, which means 0321 * that hiddenDatasets() returns an empty list. 0322 */ 0323 void setHiddenDatasets( const QList<uint> hiddenDatasets ); 0324 const QList<uint> hiddenDatasets() const; 0325 void setDatasetHidden( uint dataset, bool hidden ); 0326 bool datasetIsHidden( uint dataset ) const; 0327 0328 uint datasetCount() const; 0329 0330 void setDefaultColors(); 0331 void setRainbowColors(); 0332 void setSubduedColors( bool ordered = false ); 0333 0334 void setBrushesFromDiagram( KChart::AbstractDiagram* diagram ); 0335 0336 /** 0337 * Note: there is no color() getter method, since setColor 0338 * just sets a QBrush with the respective color, so the 0339 * brush() getter method is sufficient. 0340 */ 0341 void setColor( uint dataset, const QColor& color ); 0342 0343 void setBrush( uint dataset, const QBrush& brush ); 0344 QBrush brush( uint dataset ) const; 0345 const QMap<uint,QBrush> brushes() const; 0346 0347 void setPen( uint dataset, const QPen& pen ); 0348 QPen pen( uint dataset ) const; 0349 const QMap<uint,QPen> pens() const; 0350 0351 /** 0352 * Note that any sizes specified via setMarkerAttributes are ignored, 0353 * unless you disable the automatic size calculation, by saying 0354 * setUseAutomaticMarkerSize( false ) 0355 */ 0356 void setMarkerAttributes( uint dataset, const MarkerAttributes& ); 0357 MarkerAttributes markerAttributes( uint dataset ) const; 0358 const QMap<uint, MarkerAttributes> markerAttributes() const; 0359 0360 /** 0361 * This option is on by default, it means that Marker sizes in the Legend 0362 * will be the same as the font height used for their respective label texts. 0363 * 0364 * Set this to false, if you want to specify the marker sizes via setMarkerAttributes 0365 * or if you want the Legend to use the same marker sizes as they are used in the Diagrams. 0366 */ 0367 void setUseAutomaticMarkerSize( bool useAutomaticMarkerSize ); 0368 bool useAutomaticMarkerSize() const; 0369 0370 void setTextAttributes( const TextAttributes &a ); 0371 TextAttributes textAttributes() const; 0372 0373 void setTitleText( const QString& text ); 0374 QString titleText() const; 0375 0376 void setTitleTextAttributes( const TextAttributes &a ); 0377 TextAttributes titleTextAttributes() const; 0378 0379 void setSpacing( uint space ); 0380 uint spacing() const; 0381 0382 // called internally by KChart::Chart, when painting into a custom QPainter 0383 void forceRebuild() override; 0384 0385 QSize minimumSizeHint() const override; 0386 QSize sizeHint() const override; 0387 bool hasHeightForWidth() const override; 0388 int heightForWidth( int width ) const override; 0389 void needSizeHint() override; 0390 void resizeLayout( const QSize& size ) override; 0391 0392 Q_SIGNALS: 0393 void destroyedLegend( KChart::Legend* ); 0394 /** Emitted upon change of a property of the Legend or any of its components. */ 0395 void propertiesChanged(); 0396 0397 private Q_SLOTS: 0398 void emitPositionChanged(); 0399 void resetDiagram( KChart::AbstractDiagram* ); 0400 void activateTheLayout(); 0401 void setNeedRebuild(); 0402 void buildLegend(); 0403 }; // End of class Legend 0404 0405 } 0406 0407 0408 #endif // KCHARTLEGEND_H