File indexing completed on 2024-05-12 04:20:32
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 KCHARTCHART_H 0010 #define KCHARTCHART_H 0011 0012 #include <QWidget> 0013 0014 #include "kchart_export.h" 0015 #include "KChartGlobal.h" 0016 0017 /* 0018 Simplified(*) overview of object ownership in a chart: 0019 0020 Chart is-a QWidget 0021 | 0022 n CoordinatePlanes is-a AbstractArea is-a AbstractLayoutItem is-a QLayoutItem 0023 | 0024 n Diagrams is-a QAbstractItemView is-a QWidget 0025 / | \ 0026 AbstractGrid | Axes (can be shared between diagrams) is-a AbstractArea is-a... QLayoutItem 0027 (no base class) | 0028 Legends is-a AbstractAreaWidget is-a QWidget 0029 0030 (*) less important classes, including base classes, removed. 0031 0032 0033 Layout rules: 0034 0035 In principle, every size or existence change in one of the objects listed above must be propagated 0036 to all other objects. This could change their size. 0037 There are also settings changes that invalidate the size of other components, where the size changes 0038 are detected and propagated. 0039 0040 0041 Painting call tree (simplified): 0042 0043 Chart::paint() (from users) / paintEvent() (from framework) 0044 ChartPrivate::paintAll()-----------------------------------------------\ 0045 CoordinatePlane::paintAll() (from AbstractArea)--------\ Axis::paintAll()-\ 0046 CoordinatePlane::paint() (from AbstractLayoutItem) Grid::drawGrid() Axis::paint() 0047 Diagram::paint( PaintContext* paintContext ) 0048 0049 Note that grids are painted from the coordinate plane, not from the diagram as ownership would suggest. 0050 0051 */ 0052 0053 namespace KChart { 0054 0055 class BackgroundAttributes; 0056 class FrameAttributes; 0057 class AbstractDiagram; 0058 class AbstractCoordinatePlane; 0059 class HeaderFooter; 0060 class Legend; 0061 0062 typedef QList<AbstractCoordinatePlane*> CoordinatePlaneList; 0063 typedef QList<HeaderFooter*> HeaderFooterList; 0064 typedef QList<Legend*> LegendList; 0065 0066 0067 /** 0068 * @class Chart KChartChart.h KChartChart 0069 * @brief A chart with one or more diagrams. 0070 * 0071 * The Chart class represents a drawing consisting of one or more diagrams 0072 * and various optional elements such as legends, axes, text boxes, headers 0073 * or footers. It takes ownership of all these elements when they are assigned 0074 * to it. Each diagram is associated with a coordinate plane, of which the chart 0075 * can have more than one. The coordinate planes (and thus the associated diagrams) 0076 * can be laid out in various ways. 0077 * 0078 * The Chart class makes heavy use of the Qt Interview framework for model/view 0079 * programming, and thus requires data to be presented to it in a QAbstractItemModel 0080 * compatible way. For many simple charts, especially if the visualized data is 0081 * static, KChart::Widget provides an abstracted interface, that hides the complexity 0082 * of Interview to a large extent. 0083 */ 0084 class KCHART_EXPORT Chart : public QWidget 0085 { 0086 Q_OBJECT 0087 // KD Chart 3.0: leading is inter-line distance of text. this here is MARGIN or SPACING. 0088 Q_PROPERTY( int globalLeadingTop READ globalLeadingTop WRITE setGlobalLeadingTop ) 0089 Q_PROPERTY( int globalLeadingBottom READ globalLeadingBottom WRITE setGlobalLeadingBottom ) 0090 Q_PROPERTY( int globalLeadingLeft READ globalLeadingLeft WRITE setGlobalLeadingLeft ) 0091 Q_PROPERTY( int globalLeadingRight READ globalLeadingRight WRITE setGlobalLeadingRight ) 0092 Q_PROPERTY( bool useNewLayoutSystem READ useNewLayoutSystem WRITE setUseNewLayoutSystem ) 0093 0094 KCHART_DECLARE_PRIVATE_BASE_POLYMORPHIC_QWIDGET( Chart ) 0095 0096 public: 0097 explicit Chart ( QWidget* parent = nullptr ); 0098 ~Chart() override; 0099 0100 /** 0101 * @brief useNewLayoutSystem 0102 * Be very careful activating the new layout system, 0103 * its still experimental and works only if the user knows 0104 * what he is doing. The reason is that the system does not prevent 0105 * the user from creating sharing graphs that are not layoutable in a 0106 * plane and still needs assistance from the user. 0107 */ 0108 bool useNewLayoutSystem() const; 0109 void setUseNewLayoutSystem( bool value ); 0110 0111 /** 0112 \brief Specify the frame attributes to be used, by default is it a thin black line. 0113 0114 To hide the frame line, you could do something like this: 0115 \verbatim 0116 KChart::FrameAttributes frameAttrs( my_chart->frameAttributes() ); 0117 frameAttrs.setVisible( false ); 0118 my_chart->setFrameAttributes( frameAttrs ); 0119 \endverbatim 0120 0121 \sa setBackgroundAttributes 0122 */ 0123 void setFrameAttributes( const FrameAttributes &a ); 0124 FrameAttributes frameAttributes() const; 0125 0126 /** 0127 \brief Specify the background attributes to be used, by default there is no background. 0128 0129 To set a light blue background, you could do something like this: 0130 \verbatim 0131 KChart::BackgroundAttributes backgroundAttrs( my_chart->backgroundAttributes() ); 0132 backgroundAttrs.setVisible( true ); 0133 backgroundAttrs.setBrush( QColor(0xd0,0xd0,0xff) ); 0134 my_chart->setBackgroundAttributes( backgroundAttrs ); 0135 \endverbatim 0136 0137 \sa setFrameAttributes 0138 */ 0139 void setBackgroundAttributes( const BackgroundAttributes &a ); 0140 BackgroundAttributes backgroundAttributes() const; 0141 0142 /** 0143 * Each chart must have at least one coordinate plane. 0144 * Initially a default CartesianCoordinatePlane is created. 0145 * Use replaceCoordinatePlane() to replace it with a different 0146 * one, such as a PolarCoordinatePlane. 0147 * @return The first coordinate plane of the chart. 0148 */ 0149 AbstractCoordinatePlane* coordinatePlane(); 0150 0151 /** 0152 * The list of coordinate planes. 0153 * @return The list of coordinate planes. 0154 */ 0155 CoordinatePlaneList coordinatePlanes(); 0156 0157 /** 0158 * Adds a coordinate plane to the chart. The chart takes ownership. 0159 * @param plane The coordinate plane to add. 0160 * 0161 * \sa replaceCoordinatePlane, takeCoordinatePlane 0162 */ 0163 void addCoordinatePlane( AbstractCoordinatePlane* plane ); 0164 0165 /** 0166 * Inserts a coordinate plane to the chart at index @p index. 0167 * The chart takes ownership. 0168 * 0169 * @param index The index where to add the plane 0170 * @param plane The coordinate plane to add. 0171 * 0172 * \sa replaceCoordinatePlane, takeCoordinatePlane 0173 */ 0174 void insertCoordinatePlane( int index, AbstractCoordinatePlane* plane ); 0175 0176 /** 0177 * Replaces the old coordinate plane, or appends the 0178 * plane, it there is none yet. 0179 * 0180 * @param plane The coordinate plane to be used instead of the old plane. 0181 * This parameter must not be zero, or the method will do nothing. 0182 * 0183 * @param oldPlane The coordinate plane to be removed by the new plane. This 0184 * plane will be deleted automatically. If the parameter is omitted, 0185 * the very first coordinate plane will be replaced. In case, there was no 0186 * plane yet, the new plane will just be added. 0187 * 0188 * \note If you want to re-use the old coordinate plane, call takeCoordinatePlane and 0189 * addCoordinatePlane, instead of using replaceCoordinatePlane. 0190 * 0191 * \sa addCoordinatePlane, takeCoordinatePlane 0192 */ 0193 void replaceCoordinatePlane( AbstractCoordinatePlane* plane, 0194 AbstractCoordinatePlane* oldPlane = nullptr ); 0195 0196 /** 0197 * Removes the coordinate plane from the chart, without deleting it. 0198 * 0199 * The chart no longer owns the plane, so it is 0200 * the caller's responsibility to delete the plane. 0201 * 0202 * \sa addCoordinatePlane, takeCoordinatePlane 0203 */ 0204 void takeCoordinatePlane( AbstractCoordinatePlane* plane ); 0205 0206 /** 0207 * Set the coordinate plane layout that should be used as model for 0208 * the internal used layout. The layout needs to be an instance of 0209 * QHBoxLayout or QVBoxLayout. 0210 */ 0211 void setCoordinatePlaneLayout( QLayout * layout ); 0212 QLayout* coordinatePlaneLayout(); 0213 0214 /** 0215 * The first header or footer of the chart. By default there is none. 0216 * @return The first header or footer of the chart or 0 if there was none 0217 * added to the chart. 0218 */ 0219 HeaderFooter* headerFooter(); 0220 0221 /** 0222 * The list of headers and footers associated with the chart. 0223 * @return The list of headers and footers associated with the chart. 0224 */ 0225 HeaderFooterList headerFooters(); 0226 0227 /** 0228 * Adds a header or a footer to the chart. The chart takes ownership. 0229 * @param headerFooter The header (or footer, resp.) to add. 0230 * 0231 * \sa replaceHeaderFooter, takeHeaderFooter 0232 */ 0233 void addHeaderFooter( HeaderFooter* headerFooter ); 0234 0235 /** 0236 * Replaces the old header (or footer, resp.), or appends the 0237 * new header or footer, it there is none yet. 0238 * 0239 * @param headerFooter The header or footer to be used instead of the old one. 0240 * This parameter must not be zero, or the method will do nothing. 0241 * 0242 * @param oldHeaderFooter The header or footer to be removed by the new one. This 0243 * header or footer will be deleted automatically. If the parameter is omitted, 0244 * the very first header or footer will be replaced. In case, there was no 0245 * header and no footer yet, the new header or footer will just be added. 0246 * 0247 * \note If you want to re-use the old header or footer, call takeHeaderFooter and 0248 * addHeaderFooter, instead of using replaceHeaderFooter. 0249 * 0250 * \sa addHeaderFooter, takeHeaderFooter 0251 */ 0252 void replaceHeaderFooter ( HeaderFooter* headerFooter, 0253 HeaderFooter* oldHeaderFooter = nullptr ); 0254 0255 /** 0256 * Removes the header (or footer, resp.) from the chart, without deleting it. 0257 * 0258 * The chart no longer owns the header or footer, so it is 0259 * the caller's responsibility to delete the header or footer. 0260 * 0261 * \sa addHeaderFooter, replaceHeaderFooter 0262 */ 0263 void takeHeaderFooter( HeaderFooter* headerFooter ); 0264 0265 /** 0266 * The first legend of the chart or 0 if there was none added to the chart. 0267 * @return The first legend of the chart or 0 if none exists. 0268 */ 0269 Legend* legend(); 0270 0271 /** 0272 * The list of all legends associated with the chart. 0273 * @return The list of all legends associated with the chart. 0274 */ 0275 LegendList legends(); 0276 0277 /** 0278 * Add the given legend to the chart. The chart takes ownership. 0279 * @param legend The legend to add. 0280 * 0281 * \sa replaceLegend, takeLegend 0282 */ 0283 void addLegend( Legend* legend ); 0284 0285 /** 0286 * Replaces the old legend, or appends the 0287 * new legend, it there is none yet. 0288 * 0289 * @param legend The legend to be used instead of the old one. 0290 * This parameter must not be zero, or the method will do nothing. 0291 * 0292 * @param oldLegend The legend to be removed by the new one. This 0293 * legend will be deleted automatically. If the parameter is omitted, 0294 * the very first legend will be replaced. In case, there was no 0295 * legend yet, the new legend will just be added. 0296 * 0297 * If you want to re-use the old legend, call takeLegend and 0298 * addLegend, instead of using replaceLegend. 0299 * 0300 * \note Whenever addLegend is called the font sizes used by the 0301 * Legend are set to relative and they get coupled to the Chart's size, 0302 * with their relative values being 20 for the item texts and 24 to the 0303 * title text. So if you want to use custom font sizes for the Legend 0304 * make sure to set them after calling addLegend. 0305 * 0306 * \sa addLegend, takeLegend 0307 */ 0308 void replaceLegend ( Legend* legend, Legend* oldLegend = nullptr ); 0309 0310 /** 0311 * Removes the legend from the chart, without deleting it. 0312 * 0313 * The chart no longer owns the legend, so it is 0314 * the caller's responsibility to delete the legend. 0315 * 0316 * \sa addLegend, takeLegend 0317 */ 0318 void takeLegend( Legend* legend ); 0319 0320 /** 0321 * Set the padding between the margin of the widget and the area that 0322 * the contents are drawn into. 0323 * @param left The padding on the left side. 0324 * @param top The padding at the top. 0325 * @param right The padding on the left hand side. 0326 * @param bottom The padding on the bottom. 0327 * 0328 * \note Using previous versions of KD Chart you might have called 0329 * setGlobalLeading() to make room for long Abscissa labels (or for an 0330 * overlapping top label of an Ordinate axis, resp.) that would not fit 0331 * into the normal axis area. This is \em no \em longer \em needed 0332 * because KD Chart now is using hidden auto-spacer items reserving 0333 * as much free space as is needed for axes with overlapping content 0334 * at the respective sides. 0335 * 0336 * \sa setGlobalLeadingTop, setGlobalLeadingBottom, setGlobalLeadingLeft, setGlobalLeadingRight 0337 * \sa globalLeadingTop, globalLeadingBottom, globalLeadingLeft, globalLeadingRight 0338 */ 0339 void setGlobalLeading( int left, int top, int right, int bottom ); 0340 0341 /** 0342 * Set the padding between the start of the widget and the start 0343 * of the area that is used for drawing on the left. 0344 * @param leading The padding value. 0345 * 0346 * \sa setGlobalLeading 0347 */ 0348 void setGlobalLeadingLeft( int leading ); 0349 0350 /** 0351 * The padding between the start of the widget and the start 0352 * of the area that is used for drawing on the left. 0353 * @return The padding between the start of the widget and the start 0354 * of the area that is used for drawing on the left. 0355 * 0356 * \sa setGlobalLeading 0357 */ 0358 int globalLeadingLeft() const; 0359 0360 /** 0361 * Set the padding between the start of the widget and the start 0362 * of the area that is used for drawing at the top. 0363 * @param leading The padding value. 0364 * 0365 * \sa setGlobalLeading 0366 */ 0367 void setGlobalLeadingTop( int leading ); 0368 0369 /** 0370 * The padding between the start of the widget and the start 0371 * of the area that is used for drawing at the top. 0372 * @return The padding between the start of the widget and the start 0373 * of the area that is used for drawing at the top. 0374 * 0375 * \sa setGlobalLeading 0376 */ 0377 int globalLeadingTop() const; 0378 0379 /** 0380 * Set the padding between the start of the widget and the start 0381 * of the area that is used for drawing on the right. 0382 * @param leading The padding value. 0383 * 0384 * \sa setGlobalLeading 0385 */ 0386 void setGlobalLeadingRight( int leading ); 0387 0388 /** 0389 * The padding between the start of the widget and the start 0390 * of the area that is used for drawing on the right. 0391 * @return The padding between the start of the widget and the start 0392 * of the area that is used for drawing on the right. 0393 * 0394 * \sa setGlobalLeading 0395 */ 0396 int globalLeadingRight() const; 0397 0398 /** 0399 * Set the padding between the start of the widget and the start 0400 * of the area that is used for drawing on the bottom. 0401 * @param leading The padding value. 0402 * 0403 * \sa setGlobalLeading 0404 */ 0405 void setGlobalLeadingBottom( int leading ); 0406 0407 /** 0408 * The padding between the start of the widget and the start 0409 * of the area that is used for drawing at the bottom. 0410 * @return The padding between the start of the widget and the start 0411 * of the area that is used for drawing at the bottom. 0412 * 0413 * \sa setGlobalLeading 0414 */ 0415 int globalLeadingBottom() const; 0416 0417 /** 0418 * Paints all the contents of the chart. Use this method to make KChart 0419 * draw into your QPainter. 0420 * 0421 * \note Any global leading settings will be used by the paint method too, 0422 * so make sure to set them to zero, if you want the drawing to have the exact 0423 * size of the target rectangle. 0424 * 0425 * \param painter The painter to be drawn into. 0426 * \param rect The rectangle to be filled by the Chart's drawing. 0427 * 0428 * \sa setGlobalLeading 0429 */ 0430 void paint( QPainter* painter, const QRect& rect ); 0431 0432 void reLayoutFloatingLegends(); 0433 0434 Q_SIGNALS: 0435 /** Emitted upon change of a property of the Chart or any of its components. */ 0436 void propertiesChanged(); 0437 void finishedDrawing(); 0438 0439 protected: 0440 /** 0441 * Adjusts the internal layout when the chart is resized. 0442 */ 0443 /* reimp */ void resizeEvent ( QResizeEvent * event ) override; 0444 0445 /** 0446 * @brief Draws the background and frame, then calls paint(). 0447 * 0448 * In most cases there is no need to override this method in a derived 0449 * class, but if you do, do not forget to call paint(). 0450 * @sa paint 0451 */ 0452 /* reimp */ void paintEvent( QPaintEvent* event ) override; 0453 0454 /** reimp */ 0455 void mousePressEvent( QMouseEvent* event ) override; 0456 /** reimp */ 0457 void mouseDoubleClickEvent( QMouseEvent* event ) override; 0458 /** reimp */ 0459 void mouseMoveEvent( QMouseEvent* event ) override; 0460 /** reimp */ 0461 void mouseReleaseEvent( QMouseEvent* event ) override; 0462 /** reimp */ 0463 bool event( QEvent* event ) override; 0464 0465 private: 0466 // TODO move this to the private class 0467 void addLegendInternal( Legend *legend, bool setMeasures ); 0468 }; 0469 0470 // Here we have a few docu block to be included into the API documentation: 0471 /** 0472 * \dir src 0473 * \brief Implementation directory of KChart. 0474 * 0475 * This directory contains the header files and the source files of both, 0476 * the private and the public classes. 0477 * 0478 * \note Only classes that have an include wrapper in the \c $KCHARTDIR/include 0479 * directory are part of the supported API. 0480 * All other classes are to be considered as implementation details, they 0481 * could be changed in future versions of KChart without notice. 0482 * 0483 * In other words: No class that is not mentioned in the \c $KCHARTDIR/include 0484 * directory may be directly used by your application. 0485 * 0486 * The recommended way to include classes of the KChart API is including 0487 * them by class name, so instead of including KChartChart.h you would say: 0488 * 0489 \verbatim 0490 #include <KChartChart> 0491 \endverbatim 0492 * 0493 * When following this there is no reason to include the \c $KCHARTDIR/src 0494 * directory, it is sufficient to include \c $KCHARTDIR/include 0495 */ 0496 } 0497 /** 0498 * @class QAbstractItemView "(do not include)" 0499 * @brief Class only listed here to document inheritance of some KChart classes. 0500 * 0501 * Please consult the respective Qt documentation for details: 0502 * <A HREF="http://doc.trolltech.com/">http://doc.trolltech.com/</A> 0503 */ 0504 /** 0505 * @class QAbstractProxyModel "(do not include)" 0506 * @brief Class only listed here to document inheritance of some KChart classes. 0507 * 0508 * Please consult the respective Qt documentation for details: 0509 * <A HREF="http://doc.trolltech.com/">http://doc.trolltech.com/</A> 0510 */ 0511 /** 0512 * @class QFrame "(do not include)" 0513 * @brief Class only listed here to document inheritance of some KChart classes. 0514 * 0515 * Please consult the respective Qt documentation for details: 0516 * <A HREF="http://doc.trolltech.com/">http://doc.trolltech.com/</A> 0517 */ 0518 /** 0519 * @class QObject "(do not include)" 0520 * @brief Class only listed here to document inheritance of some KChart classes. 0521 * 0522 * Please consult the respective Qt documentation for details: 0523 * <A HREF="http://doc.trolltech.com/">http://doc.trolltech.com/</A> 0524 */ 0525 /** 0526 * @class QSortFilterProxyModel "(do not include)" 0527 * @brief Class only listed here to document inheritance of some KChart classes. 0528 * 0529 * Please consult the respective Qt documentation for details: 0530 * <A HREF="http://doc.trolltech.com/">http://doc.trolltech.com/</A> 0531 */ 0532 /** 0533 * @class QWidget "(do not include)" 0534 * @brief Class only listed here to document inheritance of some KChart classes. 0535 * 0536 * Please consult the respective Qt documentation for details: 0537 * <A HREF="http://doc.trolltech.com/">http://doc.trolltech.com/</A> 0538 */ 0539 /** 0540 * @class QTextDocument "(do not include)" 0541 * @brief Class only listed here to document inheritance of some KChart classes. 0542 * 0543 * Please consult the respective Qt documentation for details: 0544 * <A HREF="http://doc.trolltech.com/">http://doc.trolltech.com/</A> 0545 */ 0546 /** 0547 * @class QLayoutItem "(do not include)" 0548 * @brief Class only listed here to document inheritance of some KChart classes. 0549 * 0550 * Please consult the respective Qt documentation for details: 0551 * <A HREF="http://doc.trolltech.com/">http://doc.trolltech.com/</A> 0552 */ 0553 /** 0554 * @class QGraphicsPolygonItem "(do not include)" 0555 * @brief Class only listed here to document inheritance of some KChart classes. 0556 * 0557 * Please consult the respective Qt documentation for details: 0558 * <A HREF="http://doc.trolltech.com/">http://doc.trolltech.com/</A> 0559 */ 0560 0561 0562 #endif