File indexing completed on 2024-04-14 03:41:12

0001 /*
0002     QCustomPlot, an easy to use, modern plotting widget for Qt
0003     SPDX-FileCopyrightText: 2011-2021 Emanuel Eichhammer <http://www.qcustomplot.com/>
0004 
0005     SPDX-License-Identifier: GPL-3.0-or-later
0006 */
0007 
0008 #ifndef QCUSTOMPLOT_H
0009 #define QCUSTOMPLOT_H
0010 
0011 #include <QtCore/qglobal.h>
0012 
0013 // some Qt version/configuration dependent macros to include or exclude certain code paths:
0014 #ifdef QCUSTOMPLOT_USE_OPENGL
0015 #  if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
0016 #    define QCP_OPENGL_PBUFFER
0017 #  else
0018 #    define QCP_OPENGL_FBO
0019 #  endif
0020 #  if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0)
0021 #    define QCP_OPENGL_OFFSCREENSURFACE
0022 #  endif
0023 #endif
0024 
0025 #define QCP_DEVICEPIXELRATIO_SUPPORTED
0026 #define QCP_DEVICEPIXELRATIO_FLOAT
0027 
0028 #include <QtCore/QObject>
0029 #include <QtCore/QPointer>
0030 #include <QtCore/QSharedPointer>
0031 #include <QtCore/QTimer>
0032 #include <QtGui/QPainter>
0033 #include <QtGui/QPainterPath>
0034 #include <QtGui/QPaintEvent>
0035 #include <QtGui/QMouseEvent>
0036 #include <QtGui/QWheelEvent>
0037 #include <QtGui/QPixmap>
0038 #include <QtCore/QVector>
0039 #include <QtCore/QString>
0040 #include <QtCore/QDateTime>
0041 #include <QtCore/QMultiMap>
0042 #include <QtCore/QFlags>
0043 #include <QtCore/QDebug>
0044 #include <QtCore/QStack>
0045 #include <QtCore/QCache>
0046 #include <QtCore/QMargins>
0047 #include <qmath.h>
0048 #include <limits>
0049 #include <algorithm>
0050 #ifdef QCP_OPENGL_FBO
0051 #  include <QtGui/QOpenGLContext>
0052 #  if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0053 #    include <QtGui/QOpenGLFramebufferObject>
0054 #  else
0055 #    include <QOpenGLFramebufferObject>
0056 #    include <QOpenGLPaintDevice>
0057 #  endif
0058 #  ifdef QCP_OPENGL_OFFSCREENSURFACE
0059 #    include <QtGui/QOffscreenSurface>
0060 #  else
0061 #    include <QtGui/QWindow>
0062 #  endif
0063 #endif
0064 #ifdef QCP_OPENGL_PBUFFER
0065 #  include <QtOpenGL/QGLPixelBuffer>
0066 #endif
0067 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
0068 #  include <qnumeric.h>
0069 #  include <QtGui/QWidget>
0070 #  include <QtGui/QPrinter>
0071 #  include <QtGui/QPrintEngine>
0072 #else
0073 #  include <QtNumeric>
0074 #  include <QtWidgets/QWidget>
0075 #  include <QtPrintSupport/QtPrintSupport>
0076 #endif
0077 #if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0)
0078 #  include <QtCore/QElapsedTimer>
0079 #endif
0080 # if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
0081 #  include <QtCore/QTimeZone>
0082 #endif
0083 
0084 class QCPPainter;
0085 class QCustomPlot;
0086 class QCPLayerable;
0087 class QCPLayoutElement;
0088 class QCPLayout;
0089 class QCPAxis;
0090 class QCPAxisRect;
0091 class QCPAxisPainterPrivate;
0092 class QCPAbstractPlottable;
0093 class QCPGraph;
0094 class QCPAbstractItem;
0095 class QCPPlottableInterface1D;
0096 class QCPLegend;
0097 class QCPItemPosition;
0098 class QCPLayer;
0099 class QCPAbstractLegendItem;
0100 class QCPSelectionRect;
0101 class QCPColorMap;
0102 class QCPColorScale;
0103 class QCPBars;
0104 class QCPPolarAxisRadial;
0105 class QCPPolarAxisAngular;
0106 class QCPPolarGrid;
0107 class QCPPolarGraph;
0108 
0109 /* including file 'src/global.h'            */
0110 /* modified 2021-03-29T02:30:44, size 16981 */
0111 
0112 #define QCUSTOMPLOT_VERSION_STR "2.1.0"
0113 #define QCUSTOMPLOT_VERSION 0x020100
0114 
0115 // decl definitions for shared library compilation/usage:
0116 #if defined(QT_STATIC_BUILD)
0117 #  define QCP_LIB_DECL
0118 #elif defined(QCUSTOMPLOT_COMPILE_LIBRARY)
0119 #  define QCP_LIB_DECL Q_DECL_EXPORT
0120 #elif defined(QCUSTOMPLOT_USE_LIBRARY)
0121 #  define QCP_LIB_DECL Q_DECL_IMPORT
0122 #else
0123 #  define QCP_LIB_DECL
0124 #endif
0125 
0126 // define empty macro for Q_DECL_OVERRIDE if it doesn't exist (Qt < 5)
0127 #ifndef Q_DECL_OVERRIDE
0128 #  define Q_DECL_OVERRIDE
0129 #endif
0130 
0131 /*!
0132   The QCP Namespace contains general enums, QFlags and functions used throughout the QCustomPlot
0133   library.
0134   
0135   It provides QMetaObject-based reflection of its enums and flags via \a QCP::staticMetaObject.
0136 */
0137 #ifndef Q_MOC_RUN
0138 namespace QCP {
0139 #else
0140 class QCP { // when in moc-run, make it look like a class, so we get Q_GADGET, Q_ENUMS/Q_FLAGS features in namespace
0141   Q_GADGET
0142   Q_ENUMS(ExportPen)
0143   Q_ENUMS(ResolutionUnit)
0144   Q_ENUMS(SignDomain)
0145   Q_ENUMS(MarginSide)
0146   Q_FLAGS(MarginSides)
0147   Q_ENUMS(AntialiasedElement)
0148   Q_FLAGS(AntialiasedElements)
0149   Q_ENUMS(PlottingHint)
0150   Q_FLAGS(PlottingHints)
0151   Q_ENUMS(Interaction)
0152   Q_FLAGS(Interactions)
0153   Q_ENUMS(SelectionRectMode)
0154   Q_ENUMS(SelectionType)
0155 public:
0156 #endif
0157 
0158 /*!
0159   Defines the different units in which the image resolution can be specified in the export
0160   functions.
0161 
0162   \see QCustomPlot::savePng, QCustomPlot::saveJpg, QCustomPlot::saveBmp, QCustomPlot::saveRastered
0163 */
0164 enum ResolutionUnit { ruDotsPerMeter       ///< Resolution is given in dots per meter (dpm)
0165                       ,ruDotsPerCentimeter ///< Resolution is given in dots per centimeter (dpcm)
0166                       ,ruDotsPerInch       ///< Resolution is given in dots per inch (DPI/PPI)
0167                     };
0168 
0169 /*!
0170   Defines how cosmetic pens (pens with numerical width 0) are handled during export.
0171 
0172   \see QCustomPlot::savePdf
0173 */
0174 enum ExportPen { epNoCosmetic     ///< Cosmetic pens are converted to pens with pixel width 1 when exporting
0175                  ,epAllowCosmetic ///< Cosmetic pens are exported normally (e.g. in PDF exports, cosmetic pens always appear as 1 pixel on screen, independent of viewer zoom level)
0176                };
0177 
0178 /*!
0179   Represents negative and positive sign domain, e.g. for passing to \ref
0180   QCPAbstractPlottable::getKeyRange and \ref QCPAbstractPlottable::getValueRange.
0181   
0182   This is primarily needed when working with logarithmic axis scales, since only one of the sign
0183   domains can be visible at a time.
0184 */
0185 enum SignDomain { sdNegative  ///< The negative sign domain, i.e. numbers smaller than zero
0186                   ,sdBoth     ///< Both sign domains, including zero, i.e. all numbers
0187                   ,sdPositive ///< The positive sign domain, i.e. numbers greater than zero
0188                 };
0189 
0190 /*!
0191   Defines the sides of a rectangular entity to which margins can be applied.
0192   
0193   \see QCPLayoutElement::setAutoMargins, QCPAxisRect::setAutoMargins
0194 */
0195 enum MarginSide { msLeft     = 0x01 ///< <tt>0x01</tt> left margin
0196                   ,msRight   = 0x02 ///< <tt>0x02</tt> right margin
0197                   ,msTop     = 0x04 ///< <tt>0x04</tt> top margin
0198                   ,msBottom  = 0x08 ///< <tt>0x08</tt> bottom margin
0199                   ,msAll     = 0xFF ///< <tt>0xFF</tt> all margins
0200                   ,msNone    = 0x00 ///< <tt>0x00</tt> no margin
0201                 };
0202 Q_DECLARE_FLAGS(MarginSides, MarginSide)
0203 
0204 /*!
0205   Defines what objects of a plot can be forcibly drawn antialiased/not antialiased. If an object is
0206   neither forcibly drawn antialiased nor forcibly drawn not antialiased, it is up to the respective
0207   element how it is drawn. Typically it provides a \a setAntialiased function for this.
0208   
0209   \c AntialiasedElements is a flag of or-combined elements of this enum type.
0210   
0211   \see QCustomPlot::setAntialiasedElements, QCustomPlot::setNotAntialiasedElements
0212 */
0213 enum AntialiasedElement { aeAxes           = 0x0001 ///< <tt>0x0001</tt> Axis base line and tick marks
0214                           ,aeGrid          = 0x0002 ///< <tt>0x0002</tt> Grid lines
0215                           ,aeSubGrid       = 0x0004 ///< <tt>0x0004</tt> Sub grid lines
0216                           ,aeLegend        = 0x0008 ///< <tt>0x0008</tt> Legend box
0217                           ,aeLegendItems   = 0x0010 ///< <tt>0x0010</tt> Legend items
0218                           ,aePlottables    = 0x0020 ///< <tt>0x0020</tt> Main lines of plottables
0219                           ,aeItems         = 0x0040 ///< <tt>0x0040</tt> Main lines of items
0220                           ,aeScatters      = 0x0080 ///< <tt>0x0080</tt> Scatter symbols of plottables (excluding scatter symbols of type ssPixmap)
0221                           ,aeFills         = 0x0100 ///< <tt>0x0100</tt> Borders of fills (e.g. under or between graphs)
0222                           ,aeZeroLine      = 0x0200 ///< <tt>0x0200</tt> Zero-lines, see \ref QCPGrid::setZeroLinePen
0223                           ,aeOther         = 0x8000 ///< <tt>0x8000</tt> Other elements that don't fit into any of the existing categories
0224                           ,aeAll           = 0xFFFF ///< <tt>0xFFFF</tt> All elements
0225                           ,aeNone          = 0x0000 ///< <tt>0x0000</tt> No elements
0226                         };
0227 Q_DECLARE_FLAGS(AntialiasedElements, AntialiasedElement)
0228 
0229 /*!
0230   Defines plotting hints that control various aspects of the quality and speed of plotting.
0231   
0232   \see QCustomPlot::setPlottingHints
0233 */
0234 enum PlottingHint { phNone              = 0x000 ///< <tt>0x000</tt> No hints are set
0235                     ,phFastPolylines    = 0x001 ///< <tt>0x001</tt> Graph/Curve lines are drawn with a faster method. This reduces the quality especially of the line segment
0236                                                 ///<                joins, thus is most effective for pen sizes larger than 1. It is only used for solid line pens.
0237                     ,phImmediateRefresh = 0x002 ///< <tt>0x002</tt> causes an immediate repaint() instead of a soft update() when QCustomPlot::replot() is called with parameter \ref QCustomPlot::rpRefreshHint.
0238                                                 ///<                This is set by default to prevent the plot from freezing on fast consecutive replots (e.g. user drags ranges with mouse).
0239                     ,phCacheLabels      = 0x004 ///< <tt>0x004</tt> axis (tick) labels will be cached as pixmaps, increasing replot performance.
0240                   };
0241 Q_DECLARE_FLAGS(PlottingHints, PlottingHint)
0242 
0243 /*!
0244   Defines the mouse interactions possible with QCustomPlot.
0245   
0246   \c Interactions is a flag of or-combined elements of this enum type.
0247   
0248   \see QCustomPlot::setInteractions
0249 */
0250 enum Interaction { iNone              = 0x000 ///< <tt>0x000</tt> None of the interactions are possible
0251                    ,iRangeDrag        = 0x001 ///< <tt>0x001</tt> Axis ranges are draggable (see \ref QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeDragAxes)
0252                    ,iRangeZoom        = 0x002 ///< <tt>0x002</tt> Axis ranges are zoomable with the mouse wheel (see \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeZoomAxes)
0253                    ,iMultiSelect      = 0x004 ///< <tt>0x004</tt> The user can select multiple objects by holding the modifier set by \ref QCustomPlot::setMultiSelectModifier while clicking
0254                    ,iSelectPlottables = 0x008 ///< <tt>0x008</tt> Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable)
0255                    ,iSelectAxes       = 0x010 ///< <tt>0x010</tt> Axes are selectable (or parts of them, see QCPAxis::setSelectableParts)
0256                    ,iSelectLegend     = 0x020 ///< <tt>0x020</tt> Legends are selectable (or their child items, see QCPLegend::setSelectableParts)
0257                    ,iSelectItems      = 0x040 ///< <tt>0x040</tt> Items are selectable (Rectangles, Arrows, Textitems, etc. see \ref QCPAbstractItem)
0258                    ,iSelectOther      = 0x080 ///< <tt>0x080</tt> All other objects are selectable (e.g. your own derived layerables, other layout elements,...)
0259                    ,iSelectPlottablesBeyondAxisRect = 0x100 ///< <tt>0x100</tt> When performing plottable selection/hit tests, this flag extends the sensitive area beyond the axis rect
0260                  };
0261 Q_DECLARE_FLAGS(Interactions, Interaction)
0262 
0263 /*!
0264   Defines the behaviour of the selection rect.
0265   
0266   \see QCustomPlot::setSelectionRectMode, QCustomPlot::selectionRect, QCPSelectionRect
0267 */
0268 enum SelectionRectMode { srmNone    ///< The selection rect is disabled, and all mouse events are forwarded to the underlying objects, e.g. for axis range dragging
0269                          ,srmZoom   ///< When dragging the mouse, a selection rect becomes active. Upon releasing, the axes that are currently set as range zoom axes (\ref QCPAxisRect::setRangeZoomAxes) will have their ranges zoomed accordingly.
0270                          ,srmSelect ///< When dragging the mouse, a selection rect becomes active. Upon releasing, plottable data points that were within the selection rect are selected, if the plottable's selectability setting permits. (See  \ref dataselection "data selection mechanism" for details.)
0271                          ,srmCustom ///< When dragging the mouse, a selection rect becomes active. It is the programmer's responsibility to connect according slots to the selection rect's signals (e.g. \ref QCPSelectionRect::accepted) in order to process the user interaction.
0272                        };
0273 
0274 /*!
0275   Defines the different ways a plottable can be selected. These images show the effect of the
0276   different selection types, when the indicated selection rect was dragged:
0277   
0278   <center>
0279   <table>
0280   <tr>
0281     <td>\image html selectiontype-none.png stNone</td>
0282     <td>\image html selectiontype-whole.png stWhole</td>
0283     <td>\image html selectiontype-singledata.png stSingleData</td>
0284     <td>\image html selectiontype-datarange.png stDataRange</td>
0285     <td>\image html selectiontype-multipledataranges.png stMultipleDataRanges</td>
0286   </tr>
0287   </table>
0288   </center>
0289   
0290   \see QCPAbstractPlottable::setSelectable, QCPDataSelection::enforceType
0291 */
0292 enum SelectionType { stNone                ///< The plottable is not selectable
0293                      ,stWhole              ///< Selection behaves like \ref stMultipleDataRanges, but if there are any data points selected, the entire plottable is drawn as selected.
0294                      ,stSingleData         ///< One individual data point can be selected at a time
0295                      ,stDataRange          ///< Multiple contiguous data points (a data range) can be selected
0296                      ,stMultipleDataRanges ///< Any combination of data points/ranges can be selected
0297                     };
0298 
0299 /*! \internal
0300   
0301   Returns whether the specified \a value is considered an invalid data value for plottables (i.e.
0302   is \e nan or \e +/-inf). This function is used to check data validity upon replots, when the
0303   compiler flag \c QCUSTOMPLOT_CHECK_DATA is set.
0304 */
0305 inline bool isInvalidData(double value)
0306 {
0307   return qIsNaN(value) || qIsInf(value);
0308 }
0309 
0310 /*! \internal
0311   \overload
0312   
0313   Checks two arguments instead of one.
0314 */
0315 inline bool isInvalidData(double value1, double value2)
0316 {
0317   return isInvalidData(value1) || isInvalidData(value2);
0318 }
0319 
0320 /*! \internal
0321   
0322   Sets the specified \a side of \a margins to \a value
0323   
0324   \see getMarginValue
0325 */
0326 inline void setMarginValue(QMargins &margins, QCP::MarginSide side, int value)
0327 {
0328   switch (side)
0329   {
0330     case QCP::msLeft: margins.setLeft(value); break;
0331     case QCP::msRight: margins.setRight(value); break;
0332     case QCP::msTop: margins.setTop(value); break;
0333     case QCP::msBottom: margins.setBottom(value); break;
0334     case QCP::msAll: margins = QMargins(value, value, value, value); break;
0335     default: break;
0336   }
0337 }
0338 
0339 /*! \internal
0340   
0341   Returns the value of the specified \a side of \a margins. If \a side is \ref QCP::msNone or
0342   \ref QCP::msAll, returns 0.
0343   
0344   \see setMarginValue
0345 */
0346 inline int getMarginValue(const QMargins &margins, QCP::MarginSide side)
0347 {
0348   switch (side)
0349   {
0350     case QCP::msLeft: return margins.left();
0351     case QCP::msRight: return margins.right();
0352     case QCP::msTop: return margins.top();
0353     case QCP::msBottom: return margins.bottom();
0354     default: break;
0355   }
0356   return 0;
0357 }
0358 
0359 
0360 extern const QMetaObject staticMetaObject; // in moc-run we create a static meta object for QCP "fake" object. This line is the link to it via QCP::staticMetaObject in normal operation as namespace
0361 
0362 } // end of namespace QCP
0363 Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::AntialiasedElements)
0364 Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::PlottingHints)
0365 Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::MarginSides)
0366 Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::Interactions)
0367 Q_DECLARE_METATYPE(QCP::ExportPen)
0368 Q_DECLARE_METATYPE(QCP::ResolutionUnit)
0369 Q_DECLARE_METATYPE(QCP::SignDomain)
0370 Q_DECLARE_METATYPE(QCP::MarginSide)
0371 Q_DECLARE_METATYPE(QCP::AntialiasedElement)
0372 Q_DECLARE_METATYPE(QCP::PlottingHint)
0373 Q_DECLARE_METATYPE(QCP::Interaction)
0374 Q_DECLARE_METATYPE(QCP::SelectionRectMode)
0375 Q_DECLARE_METATYPE(QCP::SelectionType)
0376 
0377 /* end of 'src/global.h' */
0378 
0379 
0380 /* including file 'src/vector2d.h'         */
0381 /* modified 2021-03-29T02:30:44, size 4988 */
0382 
0383 class QCP_LIB_DECL QCPVector2D
0384 {
0385 public:
0386   QCPVector2D();
0387   QCPVector2D(double x, double y);
0388   QCPVector2D(const QPoint &point);
0389   QCPVector2D(const QPointF &point);
0390   
0391   // getters:
0392   double x() const { return mX; }
0393   double y() const { return mY; }
0394   double &rx() { return mX; }
0395   double &ry() { return mY; }
0396   
0397   // setters:
0398   void setX(double x) { mX = x; }
0399   void setY(double y) { mY = y; }
0400   
0401   // non-virtual methods:
0402   double length() const { return qSqrt(mX*mX+mY*mY); }
0403   double lengthSquared() const { return mX*mX+mY*mY; }
0404   double angle() const { return qAtan2(mY, mX); }
0405   QPoint toPoint() const { return QPoint(int(mX), int(mY)); }
0406   QPointF toPointF() const { return QPointF(mX, mY); }
0407   
0408   bool isNull() const { return qIsNull(mX) && qIsNull(mY); }
0409   void normalize();
0410   QCPVector2D normalized() const;
0411   QCPVector2D perpendicular() const { return QCPVector2D(-mY, mX); }
0412   double dot(const QCPVector2D &vec) const { return mX*vec.mX+mY*vec.mY; }
0413   double distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const;
0414   double distanceSquaredToLine(const QLineF &line) const;
0415   double distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const;
0416   
0417   QCPVector2D &operator*=(double factor);
0418   QCPVector2D &operator/=(double divisor);
0419   QCPVector2D &operator+=(const QCPVector2D &vector);
0420   QCPVector2D &operator-=(const QCPVector2D &vector);
0421   
0422 private:
0423   // property members:
0424   double mX, mY;
0425   
0426   friend inline const QCPVector2D operator*(double factor, const QCPVector2D &vec);
0427   friend inline const QCPVector2D operator*(const QCPVector2D &vec, double factor);
0428   friend inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor);
0429   friend inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2);
0430   friend inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2);
0431   friend inline const QCPVector2D operator-(const QCPVector2D &vec);
0432 };
0433 Q_DECLARE_TYPEINFO(QCPVector2D, Q_MOVABLE_TYPE);
0434 
0435 inline const QCPVector2D operator*(double factor, const QCPVector2D &vec) { return QCPVector2D(vec.mX*factor, vec.mY*factor); }
0436 inline const QCPVector2D operator*(const QCPVector2D &vec, double factor) { return QCPVector2D(vec.mX*factor, vec.mY*factor); }
0437 inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor) { return QCPVector2D(vec.mX/divisor, vec.mY/divisor); }
0438 inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX+vec2.mX, vec1.mY+vec2.mY); }
0439 inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX-vec2.mX, vec1.mY-vec2.mY); }
0440 inline const QCPVector2D operator-(const QCPVector2D &vec) { return QCPVector2D(-vec.mX, -vec.mY); }
0441 
0442 /*! \relates QCPVector2D
0443 
0444   Prints \a vec in a human readable format to the qDebug output.
0445 */
0446 inline QDebug operator<< (QDebug d, const QCPVector2D &vec)
0447 {
0448     d.nospace() << "QCPVector2D(" << vec.x() << ", " << vec.y() << ")";
0449     return d.space();
0450 }
0451 
0452 /* end of 'src/vector2d.h' */
0453 
0454 
0455 /* including file 'src/painter.h'          */
0456 /* modified 2021-03-29T02:30:44, size 4035 */
0457 
0458 class QCP_LIB_DECL QCPPainter : public QPainter
0459 {
0460   Q_GADGET
0461 public:
0462   /*!
0463     Defines special modes the painter can operate in. They disable or enable certain subsets of features/fixes/workarounds,
0464     depending on whether they are wanted on the respective output device.
0465   */
0466   enum PainterMode { pmDefault       = 0x00   ///< <tt>0x00</tt> Default mode for painting on screen devices
0467                      ,pmVectorized   = 0x01   ///< <tt>0x01</tt> Mode for vectorized painting (e.g. PDF export). For example, this prevents some antialiasing fixes.
0468                      ,pmNoCaching    = 0x02   ///< <tt>0x02</tt> Mode for all sorts of exports (e.g. PNG, PDF,...). For example, this prevents using cached pixmap labels
0469                      ,pmNonCosmetic  = 0x04   ///< <tt>0x04</tt> Turns pen widths 0 to 1, i.e. disables cosmetic pens. (A cosmetic pen is always drawn with width 1 pixel in the vector image/pdf viewer, independent of zoom.)
0470                    };
0471   Q_ENUMS(PainterMode)
0472   Q_FLAGS(PainterModes)
0473   Q_DECLARE_FLAGS(PainterModes, PainterMode)
0474   
0475   QCPPainter();
0476   explicit QCPPainter(QPaintDevice *device);
0477   
0478   // getters:
0479   bool antialiasing() const { return testRenderHint(QPainter::Antialiasing); }
0480   PainterModes modes() const { return mModes; }
0481 
0482   // setters:
0483   void setAntialiasing(bool enabled);
0484   void setMode(PainterMode mode, bool enabled=true);
0485   void setModes(PainterModes modes);
0486 
0487   // methods hiding non-virtual base class functions (QPainter bug workarounds):
0488   bool begin(QPaintDevice *device);
0489   void setPen(const QPen &pen);
0490   void setPen(const QColor &color);
0491   void setPen(Qt::PenStyle penStyle);
0492   void drawLine(const QLineF &line);
0493   void drawLine(const QPointF &p1, const QPointF &p2) {drawLine(QLineF(p1, p2));}
0494   void save();
0495   void restore();
0496   
0497   // non-virtual methods:
0498   void makeNonCosmetic();
0499   
0500 protected:
0501   // property members:
0502   PainterModes mModes;
0503   bool mIsAntialiasing;
0504   
0505   // non-property members:
0506   QStack<bool> mAntialiasingStack;
0507 };
0508 Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPainter::PainterModes)
0509 Q_DECLARE_METATYPE(QCPPainter::PainterMode)
0510 
0511 /* end of 'src/painter.h' */
0512 
0513 
0514 /* including file 'src/paintbuffer.h'      */
0515 /* modified 2021-03-29T02:30:44, size 5006 */
0516 
0517 class QCP_LIB_DECL QCPAbstractPaintBuffer
0518 {
0519 public:
0520   explicit QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio);
0521   virtual ~QCPAbstractPaintBuffer();
0522   
0523   // getters:
0524   QSize size() const { return mSize; }
0525   bool invalidated() const { return mInvalidated; }
0526   double devicePixelRatio() const { return mDevicePixelRatio; }
0527   
0528   // setters:
0529   void setSize(const QSize &size);
0530   void setInvalidated(bool invalidated=true);
0531   void setDevicePixelRatio(double ratio);
0532   
0533   // introduced virtual methods:
0534   virtual QCPPainter *startPainting() = 0;
0535   virtual void donePainting() {}
0536   virtual void draw(QCPPainter *painter) const = 0;
0537   virtual void clear(const QColor &color) = 0;
0538   
0539 protected:
0540   // property members:
0541   QSize mSize;
0542   double mDevicePixelRatio;
0543   
0544   // non-property members:
0545   bool mInvalidated;
0546   
0547   // introduced virtual methods:
0548   virtual void reallocateBuffer() = 0;
0549 };
0550 
0551 
0552 class QCP_LIB_DECL QCPPaintBufferPixmap : public QCPAbstractPaintBuffer
0553 {
0554 public:
0555   explicit QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio);
0556   virtual ~QCPPaintBufferPixmap() Q_DECL_OVERRIDE;
0557   
0558   // reimplemented virtual methods:
0559   virtual QCPPainter *startPainting() Q_DECL_OVERRIDE;
0560   virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE;
0561   void clear(const QColor &color) Q_DECL_OVERRIDE;
0562   
0563 protected:
0564   // non-property members:
0565   QPixmap mBuffer;
0566   
0567   // reimplemented virtual methods:
0568   virtual void reallocateBuffer() Q_DECL_OVERRIDE;
0569 };
0570 
0571 
0572 #ifdef QCP_OPENGL_PBUFFER
0573 class QCP_LIB_DECL QCPPaintBufferGlPbuffer : public QCPAbstractPaintBuffer
0574 {
0575 public:
0576   explicit QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples);
0577   virtual ~QCPPaintBufferGlPbuffer() Q_DECL_OVERRIDE;
0578   
0579   // reimplemented virtual methods:
0580   virtual QCPPainter *startPainting() Q_DECL_OVERRIDE;
0581   virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE;
0582   void clear(const QColor &color) Q_DECL_OVERRIDE;
0583   
0584 protected:
0585   // non-property members:
0586   QGLPixelBuffer *mGlPBuffer;
0587   int mMultisamples;
0588   
0589   // reimplemented virtual methods:
0590   virtual void reallocateBuffer() Q_DECL_OVERRIDE;
0591 };
0592 #endif // QCP_OPENGL_PBUFFER
0593 
0594 
0595 #ifdef QCP_OPENGL_FBO
0596 class QCP_LIB_DECL QCPPaintBufferGlFbo : public QCPAbstractPaintBuffer
0597 {
0598 public:
0599   explicit QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer<QOpenGLContext> glContext, QWeakPointer<QOpenGLPaintDevice> glPaintDevice);
0600   virtual ~QCPPaintBufferGlFbo() Q_DECL_OVERRIDE;
0601   
0602   // reimplemented virtual methods:
0603   virtual QCPPainter *startPainting() Q_DECL_OVERRIDE;
0604   virtual void donePainting() Q_DECL_OVERRIDE;
0605   virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE;
0606   void clear(const QColor &color) Q_DECL_OVERRIDE;
0607   
0608 protected:
0609   // non-property members:
0610   QWeakPointer<QOpenGLContext> mGlContext;
0611   QWeakPointer<QOpenGLPaintDevice> mGlPaintDevice;
0612   QOpenGLFramebufferObject *mGlFrameBuffer;
0613   
0614   // reimplemented virtual methods:
0615   virtual void reallocateBuffer() Q_DECL_OVERRIDE;
0616 };
0617 #endif // QCP_OPENGL_FBO
0618 
0619 /* end of 'src/paintbuffer.h' */
0620 
0621 
0622 /* including file 'src/layer.h'            */
0623 /* modified 2021-03-29T02:30:44, size 7038 */
0624 
0625 class QCP_LIB_DECL QCPLayer : public QObject
0626 {
0627   Q_OBJECT
0628   /// \cond INCLUDE_QPROPERTIES
0629   Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot)
0630   Q_PROPERTY(QString name READ name)
0631   Q_PROPERTY(int index READ index)
0632   Q_PROPERTY(QList<QCPLayerable*> children READ children)
0633   Q_PROPERTY(bool visible READ visible WRITE setVisible)
0634   Q_PROPERTY(LayerMode mode READ mode WRITE setMode)
0635   /// \endcond
0636 public:
0637   
0638   /*!
0639     Defines the different rendering modes of a layer. Depending on the mode, certain layers can be
0640     replotted individually, without the need to replot (possibly complex) layerables on other
0641     layers.
0642 
0643     \see setMode
0644   */
0645   enum LayerMode { lmLogical   ///< Layer is used only for rendering order, and shares paint buffer with all other adjacent logical layers.
0646                    ,lmBuffered ///< Layer has its own paint buffer and may be replotted individually (see \ref replot).
0647                  };
0648   Q_ENUMS(LayerMode)
0649   
0650   QCPLayer(QCustomPlot* parentPlot, const QString &layerName);
0651   virtual ~QCPLayer();
0652   
0653   // getters:
0654   QCustomPlot *parentPlot() const { return mParentPlot; }
0655   QString name() const { return mName; }
0656   int index() const { return mIndex; }
0657   QList<QCPLayerable*> children() const { return mChildren; }
0658   bool visible() const { return mVisible; }
0659   LayerMode mode() const { return mMode; }
0660   
0661   // setters:
0662   void setVisible(bool visible);
0663   void setMode(LayerMode mode);
0664   
0665   // non-virtual methods:
0666   void replot();
0667   
0668 protected:
0669   // property members:
0670   QCustomPlot *mParentPlot;
0671   QString mName;
0672   int mIndex;
0673   QList<QCPLayerable*> mChildren;
0674   bool mVisible;
0675   LayerMode mMode;
0676   
0677   // non-property members:
0678   QWeakPointer<QCPAbstractPaintBuffer> mPaintBuffer;
0679   
0680   // non-virtual methods:
0681   void draw(QCPPainter *painter);
0682   void drawToPaintBuffer();
0683   void addChild(QCPLayerable *layerable, bool prepend);
0684   void removeChild(QCPLayerable *layerable);
0685   
0686 private:
0687   Q_DISABLE_COPY(QCPLayer)
0688   
0689   friend class QCustomPlot;
0690   friend class QCPLayerable;
0691 };
0692 Q_DECLARE_METATYPE(QCPLayer::LayerMode)
0693 
0694 class QCP_LIB_DECL QCPLayerable : public QObject
0695 {
0696   Q_OBJECT
0697   /// \cond INCLUDE_QPROPERTIES
0698   Q_PROPERTY(bool visible READ visible WRITE setVisible)
0699   Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot)
0700   Q_PROPERTY(QCPLayerable* parentLayerable READ parentLayerable)
0701   Q_PROPERTY(QCPLayer* layer READ layer WRITE setLayer NOTIFY layerChanged)
0702   Q_PROPERTY(bool antialiased READ antialiased WRITE setAntialiased)
0703   /// \endcond
0704 public:
0705   QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=nullptr);
0706   virtual ~QCPLayerable();
0707   
0708   // getters:
0709   bool visible() const { return mVisible; }
0710   QCustomPlot *parentPlot() const { return mParentPlot; }
0711   QCPLayerable *parentLayerable() const { return mParentLayerable.data(); }
0712   QCPLayer *layer() const { return mLayer; }
0713   bool antialiased() const { return mAntialiased; }
0714   
0715   // setters:
0716   void setVisible(bool on);
0717   Q_SLOT bool setLayer(QCPLayer *layer);
0718   bool setLayer(const QString &layerName);
0719   void setAntialiased(bool enabled);
0720   
0721   // introduced virtual methods:
0722   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const;
0723 
0724   // non-property methods:
0725   bool realVisibility() const;
0726   
0727 signals:
0728   void layerChanged(QCPLayer *newLayer);
0729   
0730 protected:
0731   // property members:
0732   bool mVisible;
0733   QCustomPlot *mParentPlot;
0734   QPointer<QCPLayerable> mParentLayerable;
0735   QCPLayer *mLayer;
0736   bool mAntialiased;
0737   
0738   // introduced virtual methods:
0739   virtual void parentPlotInitialized(QCustomPlot *parentPlot);
0740   virtual QCP::Interaction selectionCategory() const;
0741   virtual QRect clipRect() const;
0742   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const = 0;
0743   virtual void draw(QCPPainter *painter) = 0;
0744   // selection events:
0745   virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged);
0746   virtual void deselectEvent(bool *selectionStateChanged);
0747   // low-level mouse events:
0748   virtual void mousePressEvent(QMouseEvent *event, const QVariant &details);
0749   virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos);
0750   virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos);
0751   virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details);
0752   virtual void wheelEvent(QWheelEvent *event);
0753   
0754   // non-property methods:
0755   void initializeParentPlot(QCustomPlot *parentPlot);
0756   void setParentLayerable(QCPLayerable* parentLayerable);
0757   bool moveToLayer(QCPLayer *layer, bool prepend);
0758   void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const;
0759   
0760 private:
0761   Q_DISABLE_COPY(QCPLayerable)
0762   
0763   friend class QCustomPlot;
0764   friend class QCPLayer;
0765   friend class QCPAxisRect;
0766 };
0767 
0768 /* end of 'src/layer.h' */
0769 
0770 
0771 /* including file 'src/axis/range.h'       */
0772 /* modified 2021-03-29T02:30:44, size 5280 */
0773 
0774 class QCP_LIB_DECL QCPRange
0775 {
0776 public:
0777   double lower, upper;
0778   
0779   QCPRange();
0780   QCPRange(double lower, double upper);
0781   
0782   bool operator==(const QCPRange& other) const { return lower == other.lower && upper == other.upper; }
0783   bool operator!=(const QCPRange& other) const { return !(*this == other); }
0784   
0785   QCPRange &operator+=(const double& value) { lower+=value; upper+=value; return *this; }
0786   QCPRange &operator-=(const double& value) { lower-=value; upper-=value; return *this; }
0787   QCPRange &operator*=(const double& value) { lower*=value; upper*=value; return *this; }
0788   QCPRange &operator/=(const double& value) { lower/=value; upper/=value; return *this; }
0789   friend inline const QCPRange operator+(const QCPRange&, double);
0790   friend inline const QCPRange operator+(double, const QCPRange&);
0791   friend inline const QCPRange operator-(const QCPRange& range, double value);
0792   friend inline const QCPRange operator*(const QCPRange& range, double value);
0793   friend inline const QCPRange operator*(double value, const QCPRange& range);
0794   friend inline const QCPRange operator/(const QCPRange& range, double value);
0795   
0796   double size() const { return upper-lower; }
0797   double center() const { return (upper+lower)*0.5; }
0798   void normalize() { if (lower > upper) qSwap(lower, upper); }
0799   void expand(const QCPRange &otherRange);
0800   void expand(double includeCoord);
0801   QCPRange expanded(const QCPRange &otherRange) const;
0802   QCPRange expanded(double includeCoord) const;
0803   QCPRange bounded(double lowerBound, double upperBound) const;
0804   QCPRange sanitizedForLogScale() const;
0805   QCPRange sanitizedForLinScale() const;
0806   bool contains(double value) const { return value >= lower && value <= upper; }
0807   
0808   static bool validRange(double lower, double upper);
0809   static bool validRange(const QCPRange &range);
0810   static const double minRange;
0811   static const double maxRange;
0812   
0813 };
0814 Q_DECLARE_TYPEINFO(QCPRange, Q_MOVABLE_TYPE);
0815 
0816 /*! \relates QCPRange
0817 
0818   Prints \a range in a human readable format to the qDebug output.
0819 */
0820 inline QDebug operator<< (QDebug d, const QCPRange &range)
0821 {
0822     d.nospace() << "QCPRange(" << range.lower << ", " << range.upper << ")";
0823     return d.space();
0824 }
0825 
0826 /*!
0827   Adds \a value to both boundaries of the range.
0828 */
0829 inline const QCPRange operator+(const QCPRange& range, double value)
0830 {
0831   QCPRange result(range);
0832   result += value;
0833   return result;
0834 }
0835 
0836 /*!
0837   Adds \a value to both boundaries of the range.
0838 */
0839 inline const QCPRange operator+(double value, const QCPRange& range)
0840 {
0841   QCPRange result(range);
0842   result += value;
0843   return result;
0844 }
0845 
0846 /*!
0847   Subtracts \a value from both boundaries of the range.
0848 */
0849 inline const QCPRange operator-(const QCPRange& range, double value)
0850 {
0851   QCPRange result(range);
0852   result -= value;
0853   return result;
0854 }
0855 
0856 /*!
0857   Multiplies both boundaries of the range by \a value.
0858 */
0859 inline const QCPRange operator*(const QCPRange& range, double value)
0860 {
0861   QCPRange result(range);
0862   result *= value;
0863   return result;
0864 }
0865 
0866 /*!
0867   Multiplies both boundaries of the range by \a value.
0868 */
0869 inline const QCPRange operator*(double value, const QCPRange& range)
0870 {
0871   QCPRange result(range);
0872   result *= value;
0873   return result;
0874 }
0875 
0876 /*!
0877   Divides both boundaries of the range by \a value.
0878 */
0879 inline const QCPRange operator/(const QCPRange& range, double value)
0880 {
0881   QCPRange result(range);
0882   result /= value;
0883   return result;
0884 }
0885 
0886 /* end of 'src/axis/range.h' */
0887 
0888 
0889 /* including file 'src/selection.h'        */
0890 /* modified 2021-03-29T02:30:44, size 8569 */
0891 
0892 class QCP_LIB_DECL QCPDataRange
0893 {
0894 public:
0895   QCPDataRange();
0896   QCPDataRange(int begin, int end);
0897   
0898   bool operator==(const QCPDataRange& other) const { return mBegin == other.mBegin && mEnd == other.mEnd; }
0899   bool operator!=(const QCPDataRange& other) const { return !(*this == other); }
0900   
0901   // getters:
0902   int begin() const { return mBegin; }
0903   int end() const { return mEnd; }
0904   int size() const { return mEnd-mBegin; }
0905   int length() const { return size(); }
0906   
0907   // setters:
0908   void setBegin(int begin) { mBegin = begin; }
0909   void setEnd(int end)  { mEnd = end; }
0910   
0911   // non-property methods:
0912   bool isValid() const { return (mEnd >= mBegin) && (mBegin >= 0); }
0913   bool isEmpty() const { return length() == 0; }
0914   QCPDataRange bounded(const QCPDataRange &other) const;
0915   QCPDataRange expanded(const QCPDataRange &other) const;
0916   QCPDataRange intersection(const QCPDataRange &other) const;
0917   QCPDataRange adjusted(int changeBegin, int changeEnd) const { return QCPDataRange(mBegin+changeBegin, mEnd+changeEnd); }
0918   bool intersects(const QCPDataRange &other) const;
0919   bool contains(const QCPDataRange &other) const;
0920   
0921 private:
0922   // property members:
0923   int mBegin, mEnd;
0924 
0925 };
0926 Q_DECLARE_TYPEINFO(QCPDataRange, Q_MOVABLE_TYPE);
0927 
0928 
0929 class QCP_LIB_DECL QCPDataSelection
0930 {
0931 public:
0932   explicit QCPDataSelection();
0933   explicit QCPDataSelection(const QCPDataRange &range);
0934   
0935   bool operator==(const QCPDataSelection& other) const;
0936   bool operator!=(const QCPDataSelection& other) const { return !(*this == other); }
0937   QCPDataSelection &operator+=(const QCPDataSelection& other);
0938   QCPDataSelection &operator+=(const QCPDataRange& other);
0939   QCPDataSelection &operator-=(const QCPDataSelection& other);
0940   QCPDataSelection &operator-=(const QCPDataRange& other);
0941   friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b);
0942   friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b);
0943   friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataRange& b);
0944   friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataRange& b);
0945   friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b);
0946   friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b);
0947   friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b);
0948   friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b);
0949   
0950   // getters:
0951   int dataRangeCount() const { return mDataRanges.size(); }
0952   int dataPointCount() const;
0953   QCPDataRange dataRange(int index=0) const;
0954   QList<QCPDataRange> dataRanges() const { return mDataRanges; }
0955   QCPDataRange span() const;
0956   
0957   // non-property methods:
0958   void addDataRange(const QCPDataRange &dataRange, bool simplify=true);
0959   void clear();
0960   bool isEmpty() const { return mDataRanges.isEmpty(); }
0961   void simplify();
0962   void enforceType(QCP::SelectionType type);
0963   bool contains(const QCPDataSelection &other) const;
0964   QCPDataSelection intersection(const QCPDataRange &other) const;
0965   QCPDataSelection intersection(const QCPDataSelection &other) const;
0966   QCPDataSelection inverse(const QCPDataRange &outerRange) const;
0967   
0968 private:
0969   // property members:
0970   QList<QCPDataRange> mDataRanges;
0971   
0972   inline static bool lessThanDataRangeBegin(const QCPDataRange &a, const QCPDataRange &b) { return a.begin() < b.begin(); }
0973 };
0974 Q_DECLARE_METATYPE(QCPDataSelection)
0975 
0976 
0977 /*!
0978   Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
0979   The resulting data selection is already simplified (see \ref QCPDataSelection::simplify).
0980 */
0981 inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b)
0982 {
0983   QCPDataSelection result(a);
0984   result += b;
0985   return result;
0986 }
0987 
0988 /*!
0989   Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
0990   The resulting data selection is already simplified (see \ref QCPDataSelection::simplify).
0991 */
0992 inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b)
0993 {
0994   QCPDataSelection result(a);
0995   result += b;
0996   return result;
0997 }
0998 
0999 /*!
1000   Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
1001   The resulting data selection is already simplified (see \ref QCPDataSelection::simplify).
1002 */
1003 inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataRange& b)
1004 {
1005   QCPDataSelection result(a);
1006   result += b;
1007   return result;
1008 }
1009 
1010 /*!
1011   Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
1012   The resulting data selection is already simplified (see \ref QCPDataSelection::simplify).
1013 */
1014 inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataRange& b)
1015 {
1016   QCPDataSelection result(a);
1017   result += b;
1018   return result;
1019 }
1020 
1021 /*!
1022   Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b.
1023 */
1024 inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b)
1025 {
1026   QCPDataSelection result(a);
1027   result -= b;
1028   return result;
1029 }
1030 
1031 /*!
1032   Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b.
1033 */
1034 inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b)
1035 {
1036   QCPDataSelection result(a);
1037   result -= b;
1038   return result;
1039 }
1040 
1041 /*!
1042   Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b.
1043 */
1044 inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b)
1045 {
1046   QCPDataSelection result(a);
1047   result -= b;
1048   return result;
1049 }
1050 
1051 /*!
1052   Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b.
1053 */
1054 inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b)
1055 {
1056   QCPDataSelection result(a);
1057   result -= b;
1058   return result;
1059 }
1060 
1061 /*! \relates QCPDataRange
1062 
1063   Prints \a dataRange in a human readable format to the qDebug output.
1064 */
1065 inline QDebug operator<< (QDebug d, const QCPDataRange &dataRange)
1066 {
1067   d.nospace() << "QCPDataRange(" << dataRange.begin() << ", " << dataRange.end() << ")";
1068   return d;
1069 }
1070 
1071 /*! \relates QCPDataSelection
1072 
1073   Prints \a selection in a human readable format to the qDebug output.
1074 */
1075 inline QDebug operator<< (QDebug d, const QCPDataSelection &selection)
1076 {
1077     d.nospace() << "QCPDataSelection(";
1078     for (int i=0; i<selection.dataRangeCount(); ++i)
1079     {
1080       if (i != 0)
1081         d << ", ";
1082       d << selection.dataRange(i);
1083     }
1084     d << ")";
1085     return d;
1086 }
1087 
1088 
1089 
1090 /* end of 'src/selection.h' */
1091 
1092 
1093 /* including file 'src/selectionrect.h'    */
1094 /* modified 2021-03-29T02:30:44, size 3354 */
1095 
1096 class QCP_LIB_DECL QCPSelectionRect : public QCPLayerable
1097 {
1098   Q_OBJECT
1099 public:
1100   explicit QCPSelectionRect(QCustomPlot *parentPlot);
1101   virtual ~QCPSelectionRect() Q_DECL_OVERRIDE;
1102   
1103   // getters:
1104   QRect rect() const { return mRect; }
1105   QCPRange range(const QCPAxis *axis) const;
1106   QPen pen() const { return mPen; }
1107   QBrush brush() const { return mBrush; }
1108   bool isActive() const { return mActive; }
1109   
1110   // setters:
1111   void setPen(const QPen &pen);
1112   void setBrush(const QBrush &brush);
1113   
1114   // non-property methods:
1115   Q_SLOT void cancel();
1116   
1117 signals:
1118   void started(QMouseEvent *event);
1119   void changed(const QRect &rect, QMouseEvent *event);
1120   void canceled(const QRect &rect, QInputEvent *event);
1121   void accepted(const QRect &rect, QMouseEvent *event);
1122   
1123 protected:
1124   // property members:
1125   QRect mRect;
1126   QPen mPen;
1127   QBrush mBrush;
1128   // non-property members:
1129   bool mActive;
1130   
1131   // introduced virtual methods:
1132   virtual void startSelection(QMouseEvent *event);
1133   virtual void moveSelection(QMouseEvent *event);
1134   virtual void endSelection(QMouseEvent *event);
1135   virtual void keyPressEvent(QKeyEvent *event);
1136   
1137   // reimplemented virtual methods
1138   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
1139   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
1140   
1141   friend class QCustomPlot;
1142 };
1143 
1144 /* end of 'src/selectionrect.h' */
1145 
1146 
1147 /* including file 'src/layout.h'            */
1148 /* modified 2021-03-29T02:30:44, size 14279 */
1149 
1150 class QCP_LIB_DECL QCPMarginGroup : public QObject
1151 {
1152   Q_OBJECT
1153 public:
1154   explicit QCPMarginGroup(QCustomPlot *parentPlot);
1155   virtual ~QCPMarginGroup();
1156   
1157   // non-virtual methods:
1158   QList<QCPLayoutElement*> elements(QCP::MarginSide side) const { return mChildren.value(side); }
1159   bool isEmpty() const;
1160   void clear();
1161   
1162 protected:
1163   // non-property members:
1164   QCustomPlot *mParentPlot;
1165   QHash<QCP::MarginSide, QList<QCPLayoutElement*> > mChildren;
1166   
1167   // introduced virtual methods:
1168   virtual int commonMargin(QCP::MarginSide side) const;
1169   
1170   // non-virtual methods:
1171   void addChild(QCP::MarginSide side, QCPLayoutElement *element);
1172   void removeChild(QCP::MarginSide side, QCPLayoutElement *element);
1173   
1174 private:
1175   Q_DISABLE_COPY(QCPMarginGroup)
1176   
1177   friend class QCPLayoutElement;
1178 };
1179 
1180 
1181 class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable
1182 {
1183   Q_OBJECT
1184   /// \cond INCLUDE_QPROPERTIES
1185   Q_PROPERTY(QCPLayout* layout READ layout)
1186   Q_PROPERTY(QRect rect READ rect)
1187   Q_PROPERTY(QRect outerRect READ outerRect WRITE setOuterRect)
1188   Q_PROPERTY(QMargins margins READ margins WRITE setMargins)
1189   Q_PROPERTY(QMargins minimumMargins READ minimumMargins WRITE setMinimumMargins)
1190   Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize)
1191   Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize)
1192   Q_PROPERTY(SizeConstraintRect sizeConstraintRect READ sizeConstraintRect WRITE setSizeConstraintRect)
1193   /// \endcond
1194 public:
1195   /*!
1196     Defines the phases of the update process, that happens just before a replot. At each phase,
1197     \ref update is called with the according UpdatePhase value.
1198   */
1199   enum UpdatePhase { upPreparation ///< Phase used for any type of preparation that needs to be done before margin calculation and layout
1200                      ,upMargins    ///< Phase in which the margins are calculated and set
1201                      ,upLayout     ///< Final phase in which the layout system places the rects of the elements
1202                    };
1203   Q_ENUMS(UpdatePhase)
1204   
1205   /*!
1206     Defines to which rect of a layout element the size constraints that can be set via \ref
1207     setMinimumSize and \ref setMaximumSize apply. The outer rect (\ref outerRect) includes the
1208     margins (e.g. in the case of a QCPAxisRect the axis labels), whereas the inner rect (\ref rect)
1209     does not.
1210     
1211     \see setSizeConstraintRect
1212   */
1213   enum SizeConstraintRect { scrInnerRect ///< Minimum/Maximum size constraints apply to inner rect
1214                             , scrOuterRect ///< Minimum/Maximum size constraints apply to outer rect, thus include layout element margins
1215                           };
1216   Q_ENUMS(SizeConstraintRect)
1217 
1218   explicit QCPLayoutElement(QCustomPlot *parentPlot=nullptr);
1219   virtual ~QCPLayoutElement() Q_DECL_OVERRIDE;
1220   
1221   // getters:
1222   QCPLayout *layout() const { return mParentLayout; }
1223   QRect rect() const { return mRect; }
1224   QRect outerRect() const { return mOuterRect; }
1225   QMargins margins() const { return mMargins; }
1226   QMargins minimumMargins() const { return mMinimumMargins; }
1227   QCP::MarginSides autoMargins() const { return mAutoMargins; }
1228   QSize minimumSize() const { return mMinimumSize; }
1229   QSize maximumSize() const { return mMaximumSize; }
1230   SizeConstraintRect sizeConstraintRect() const { return mSizeConstraintRect; }
1231   QCPMarginGroup *marginGroup(QCP::MarginSide side) const { return mMarginGroups.value(side, nullptr); }
1232   QHash<QCP::MarginSide, QCPMarginGroup*> marginGroups() const { return mMarginGroups; }
1233   
1234   // setters:
1235   void setOuterRect(const QRect &rect);
1236   void setMargins(const QMargins &margins);
1237   void setMinimumMargins(const QMargins &margins);
1238   void setAutoMargins(QCP::MarginSides sides);
1239   void setMinimumSize(const QSize &size);
1240   void setMinimumSize(int width, int height);
1241   void setMaximumSize(const QSize &size);
1242   void setMaximumSize(int width, int height);
1243   void setSizeConstraintRect(SizeConstraintRect constraintRect);
1244   void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group);
1245   
1246   // introduced virtual methods:
1247   virtual void update(UpdatePhase phase);
1248   virtual QSize minimumOuterSizeHint() const;
1249   virtual QSize maximumOuterSizeHint() const;
1250   virtual QList<QCPLayoutElement*> elements(bool recursive) const;
1251   
1252   // reimplemented virtual methods:
1253   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
1254   
1255 protected:
1256   // property members:
1257   QCPLayout *mParentLayout;
1258   QSize mMinimumSize, mMaximumSize;
1259   SizeConstraintRect mSizeConstraintRect;
1260   QRect mRect, mOuterRect;
1261   QMargins mMargins, mMinimumMargins;
1262   QCP::MarginSides mAutoMargins;
1263   QHash<QCP::MarginSide, QCPMarginGroup*> mMarginGroups;
1264   
1265   // introduced virtual methods:
1266   virtual int calculateAutoMargin(QCP::MarginSide side);
1267   virtual void layoutChanged();
1268   
1269   // reimplemented virtual methods:
1270   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE { Q_UNUSED(painter) }
1271   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE { Q_UNUSED(painter) }
1272   virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE;
1273 
1274 private:
1275   Q_DISABLE_COPY(QCPLayoutElement)
1276   
1277   friend class QCustomPlot;
1278   friend class QCPLayout;
1279   friend class QCPMarginGroup;
1280 };
1281 Q_DECLARE_METATYPE(QCPLayoutElement::UpdatePhase)
1282 
1283 
1284 class QCP_LIB_DECL QCPLayout : public QCPLayoutElement
1285 {
1286   Q_OBJECT
1287 public:
1288   explicit QCPLayout();
1289   
1290   // reimplemented virtual methods:
1291   virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE;
1292   virtual QList<QCPLayoutElement*> elements(bool recursive) const Q_DECL_OVERRIDE;
1293   
1294   // introduced virtual methods:
1295   virtual int elementCount() const = 0;
1296   virtual QCPLayoutElement* elementAt(int index) const = 0;
1297   virtual QCPLayoutElement* takeAt(int index) = 0;
1298   virtual bool take(QCPLayoutElement* element) = 0;
1299   virtual void simplify();
1300   
1301   // non-virtual methods:
1302   bool removeAt(int index);
1303   bool remove(QCPLayoutElement* element);
1304   void clear();
1305   
1306 protected:
1307   // introduced virtual methods:
1308   virtual void updateLayout();
1309   
1310   // non-virtual methods:
1311   void sizeConstraintsChanged() const;
1312   void adoptElement(QCPLayoutElement *el);
1313   void releaseElement(QCPLayoutElement *el);
1314   QVector<int> getSectionSizes(QVector<int> maxSizes, QVector<int> minSizes, QVector<double> stretchFactors, int totalSize) const;
1315   static QSize getFinalMinimumOuterSize(const QCPLayoutElement *el);
1316   static QSize getFinalMaximumOuterSize(const QCPLayoutElement *el);
1317   
1318 private:
1319   Q_DISABLE_COPY(QCPLayout)
1320   friend class QCPLayoutElement;
1321 };
1322 
1323 
1324 class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout
1325 {
1326   Q_OBJECT
1327   /// \cond INCLUDE_QPROPERTIES
1328   Q_PROPERTY(int rowCount READ rowCount)
1329   Q_PROPERTY(int columnCount READ columnCount)
1330   Q_PROPERTY(QList<double> columnStretchFactors READ columnStretchFactors WRITE setColumnStretchFactors)
1331   Q_PROPERTY(QList<double> rowStretchFactors READ rowStretchFactors WRITE setRowStretchFactors)
1332   Q_PROPERTY(int columnSpacing READ columnSpacing WRITE setColumnSpacing)
1333   Q_PROPERTY(int rowSpacing READ rowSpacing WRITE setRowSpacing)
1334   Q_PROPERTY(FillOrder fillOrder READ fillOrder WRITE setFillOrder)
1335   Q_PROPERTY(int wrap READ wrap WRITE setWrap)
1336   /// \endcond
1337 public:
1338   
1339   /*!
1340     Defines in which direction the grid is filled when using \ref addElement(QCPLayoutElement*).
1341     The column/row at which wrapping into the next row/column occurs can be specified with \ref
1342     setWrap.
1343 
1344     \see setFillOrder
1345   */
1346   enum FillOrder { foRowsFirst    ///< Rows are filled first, and a new element is wrapped to the next column if the row count would exceed \ref setWrap.
1347                   ,foColumnsFirst ///< Columns are filled first, and a new element is wrapped to the next row if the column count would exceed \ref setWrap.
1348                 };
1349   Q_ENUMS(FillOrder)
1350   
1351   explicit QCPLayoutGrid();
1352   virtual ~QCPLayoutGrid() Q_DECL_OVERRIDE;
1353   
1354   // getters:
1355   int rowCount() const { return mElements.size(); }
1356   int columnCount() const { return mElements.size() > 0 ? mElements.first().size() : 0; }
1357   QList<double> columnStretchFactors() const { return mColumnStretchFactors; }
1358   QList<double> rowStretchFactors() const { return mRowStretchFactors; }
1359   int columnSpacing() const { return mColumnSpacing; }
1360   int rowSpacing() const { return mRowSpacing; }
1361   int wrap() const { return mWrap; }
1362   FillOrder fillOrder() const { return mFillOrder; }
1363   
1364   // setters:
1365   void setColumnStretchFactor(int column, double factor);
1366   void setColumnStretchFactors(const QList<double> &factors);
1367   void setRowStretchFactor(int row, double factor);
1368   void setRowStretchFactors(const QList<double> &factors);
1369   void setColumnSpacing(int pixels);
1370   void setRowSpacing(int pixels);
1371   void setWrap(int count);
1372   void setFillOrder(FillOrder order, bool rearrange=true);
1373   
1374   // reimplemented virtual methods:
1375   virtual void updateLayout() Q_DECL_OVERRIDE;
1376   virtual int elementCount() const Q_DECL_OVERRIDE { return rowCount()*columnCount(); }
1377   virtual QCPLayoutElement* elementAt(int index) const Q_DECL_OVERRIDE;
1378   virtual QCPLayoutElement* takeAt(int index) Q_DECL_OVERRIDE;
1379   virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE;
1380   virtual QList<QCPLayoutElement*> elements(bool recursive) const Q_DECL_OVERRIDE;
1381   virtual void simplify() Q_DECL_OVERRIDE;
1382   virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE;
1383   virtual QSize maximumOuterSizeHint() const Q_DECL_OVERRIDE;
1384   
1385   // non-virtual methods:
1386   QCPLayoutElement *element(int row, int column) const;
1387   bool addElement(int row, int column, QCPLayoutElement *element);
1388   bool addElement(QCPLayoutElement *element);
1389   bool hasElement(int row, int column);
1390   void expandTo(int newRowCount, int newColumnCount);
1391   void insertRow(int newIndex);
1392   void insertColumn(int newIndex);
1393   int rowColToIndex(int row, int column) const;
1394   void indexToRowCol(int index, int &row, int &column) const;
1395   
1396 protected:
1397   // property members:
1398   QList<QList<QCPLayoutElement*> > mElements;
1399   QList<double> mColumnStretchFactors;
1400   QList<double> mRowStretchFactors;
1401   int mColumnSpacing, mRowSpacing;
1402   int mWrap;
1403   FillOrder mFillOrder;
1404   
1405   // non-virtual methods:
1406   void getMinimumRowColSizes(QVector<int> *minColWidths, QVector<int> *minRowHeights) const;
1407   void getMaximumRowColSizes(QVector<int> *maxColWidths, QVector<int> *maxRowHeights) const;
1408   
1409 private:
1410   Q_DISABLE_COPY(QCPLayoutGrid)
1411 };
1412 Q_DECLARE_METATYPE(QCPLayoutGrid::FillOrder)
1413 
1414 
1415 class QCP_LIB_DECL QCPLayoutInset : public QCPLayout
1416 {
1417   Q_OBJECT
1418 public:
1419   /*!
1420     Defines how the placement and sizing is handled for a certain element in a QCPLayoutInset.
1421   */
1422   enum InsetPlacement { ipFree            ///< The element may be positioned/sized arbitrarily, see \ref setInsetRect
1423                         ,ipBorderAligned  ///< The element is aligned to one of the layout sides, see \ref setInsetAlignment
1424                       };
1425   Q_ENUMS(InsetPlacement)
1426   
1427   explicit QCPLayoutInset();
1428   virtual ~QCPLayoutInset() Q_DECL_OVERRIDE;
1429   
1430   // getters:
1431   InsetPlacement insetPlacement(int index) const;
1432   Qt::Alignment insetAlignment(int index) const;
1433   QRectF insetRect(int index) const;
1434   
1435   // setters:
1436   void setInsetPlacement(int index, InsetPlacement placement);
1437   void setInsetAlignment(int index, Qt::Alignment alignment);
1438   void setInsetRect(int index, const QRectF &rect);
1439   
1440   // reimplemented virtual methods:
1441   virtual void updateLayout() Q_DECL_OVERRIDE;
1442   virtual int elementCount() const Q_DECL_OVERRIDE;
1443   virtual QCPLayoutElement* elementAt(int index) const Q_DECL_OVERRIDE;
1444   virtual QCPLayoutElement* takeAt(int index) Q_DECL_OVERRIDE;
1445   virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE;
1446   virtual void simplify() Q_DECL_OVERRIDE {}
1447   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
1448   
1449   // non-virtual methods:
1450   void addElement(QCPLayoutElement *element, Qt::Alignment alignment);
1451   void addElement(QCPLayoutElement *element, const QRectF &rect);
1452   
1453 protected:
1454   // property members:
1455   QList<QCPLayoutElement*> mElements;
1456   QList<InsetPlacement> mInsetPlacement;
1457   QList<Qt::Alignment> mInsetAlignment;
1458   QList<QRectF> mInsetRect;
1459   
1460 private:
1461   Q_DISABLE_COPY(QCPLayoutInset)
1462 };
1463 Q_DECLARE_METATYPE(QCPLayoutInset::InsetPlacement)
1464 
1465 /* end of 'src/layout.h' */
1466 
1467 
1468 /* including file 'src/lineending.h'       */
1469 /* modified 2021-03-29T02:30:44, size 4426 */
1470 
1471 class QCP_LIB_DECL QCPLineEnding
1472 {
1473   Q_GADGET
1474 public:
1475   /*!
1476     Defines the type of ending decoration for line-like items, e.g. an arrow.
1477     
1478     \image html QCPLineEnding.png
1479     
1480     The width and length of these decorations can be controlled with the functions \ref setWidth
1481     and \ref setLength. Some decorations like \ref esDisc, \ref esSquare, \ref esDiamond and \ref esBar only
1482     support a width, the length property is ignored.
1483     
1484     \see QCPItemLine::setHead, QCPItemLine::setTail, QCPItemCurve::setHead, QCPItemCurve::setTail, QCPAxis::setLowerEnding, QCPAxis::setUpperEnding
1485   */
1486   enum EndingStyle { esNone          ///< No ending decoration
1487                      ,esFlatArrow    ///< A filled arrow head with a straight/flat back (a triangle)
1488                      ,esSpikeArrow   ///< A filled arrow head with an indented back
1489                      ,esLineArrow    ///< A non-filled arrow head with open back
1490                      ,esDisc         ///< A filled circle
1491                      ,esSquare       ///< A filled square
1492                      ,esDiamond      ///< A filled diamond (45 degrees rotated square)
1493                      ,esBar          ///< A bar perpendicular to the line
1494                      ,esHalfBar      ///< A bar perpendicular to the line, pointing out to only one side (to which side can be changed with \ref setInverted)
1495                      ,esSkewedBar    ///< A bar that is skewed (skew controllable via \ref setLength)
1496                    };
1497   Q_ENUMS(EndingStyle)
1498   
1499   QCPLineEnding();
1500   QCPLineEnding(EndingStyle style, double width=8, double length=10, bool inverted=false);
1501   
1502   // getters:
1503   EndingStyle style() const { return mStyle; }
1504   double width() const { return mWidth; }
1505   double length() const { return mLength; }
1506   bool inverted() const { return mInverted; }
1507   
1508   // setters:
1509   void setStyle(EndingStyle style);
1510   void setWidth(double width);
1511   void setLength(double length);
1512   void setInverted(bool inverted);
1513   
1514   // non-property methods:
1515   double boundingDistance() const;
1516   double realLength() const;
1517   void draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const;
1518   void draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const;
1519   
1520 protected:
1521   // property members:
1522   EndingStyle mStyle;
1523   double mWidth, mLength;
1524   bool mInverted;
1525 };
1526 Q_DECLARE_TYPEINFO(QCPLineEnding, Q_MOVABLE_TYPE);
1527 Q_DECLARE_METATYPE(QCPLineEnding::EndingStyle)
1528 
1529 /* end of 'src/lineending.h' */
1530 
1531 
1532 /* including file 'src/axis/labelpainter.h' */
1533 /* modified 2021-03-29T02:30:44, size 7086  */
1534 
1535 class QCPLabelPainterPrivate
1536 {
1537   Q_GADGET
1538 public:
1539   /*!
1540     TODO
1541   */
1542   enum AnchorMode { amRectangular    ///< 
1543                     ,amSkewedUpright ///<
1544                     ,amSkewedRotated ///<
1545                    };
1546   Q_ENUMS(AnchorMode)
1547   
1548   /*!
1549     TODO
1550   */
1551   enum AnchorReferenceType { artNormal    ///< 
1552                              ,artTangent ///<
1553                            };
1554   Q_ENUMS(AnchorReferenceType)
1555   
1556   /*!
1557     TODO
1558   */
1559   enum AnchorSide { asLeft      ///< 
1560                     ,asRight    ///< 
1561                     ,asTop      ///< 
1562                     ,asBottom   ///< 
1563                     ,asTopLeft
1564                     ,asTopRight
1565                     ,asBottomRight
1566                     ,asBottomLeft
1567                    };
1568   Q_ENUMS(AnchorSide)
1569   
1570   explicit QCPLabelPainterPrivate(QCustomPlot *parentPlot);
1571   virtual ~QCPLabelPainterPrivate();
1572   
1573   // setters:
1574   void setAnchorSide(AnchorSide side);
1575   void setAnchorMode(AnchorMode mode);
1576   void setAnchorReference(const QPointF &pixelPoint);
1577   void setAnchorReferenceType(AnchorReferenceType type);
1578   void setFont(const QFont &font);
1579   void setColor(const QColor &color);
1580   void setPadding(int padding);
1581   void setRotation(double rotation);
1582   void setSubstituteExponent(bool enabled);
1583   void setMultiplicationSymbol(QChar symbol);
1584   void setAbbreviateDecimalPowers(bool enabled);
1585   void setCacheSize(int labelCount);
1586   
1587   // getters:
1588   AnchorMode anchorMode() const { return mAnchorMode; }
1589   AnchorSide anchorSide() const { return mAnchorSide; }
1590   QPointF anchorReference() const { return mAnchorReference; }
1591   AnchorReferenceType anchorReferenceType() const { return mAnchorReferenceType; }
1592   QFont font() const { return mFont; }
1593   QColor color() const { return mColor; }
1594   int padding() const { return mPadding; }
1595   double rotation() const { return mRotation; }
1596   bool substituteExponent() const { return mSubstituteExponent; }
1597   QChar multiplicationSymbol() const { return mMultiplicationSymbol; }
1598   bool abbreviateDecimalPowers() const { return mAbbreviateDecimalPowers; }
1599   int cacheSize() const;
1600   
1601   //virtual int size() const;
1602   
1603   // non-property methods: 
1604   void drawTickLabel(QCPPainter *painter, const QPointF &tickPos, const QString &text);
1605   void clearCache();
1606   
1607   // constants that may be used with setMultiplicationSymbol:
1608   static const QChar SymbolDot;
1609   static const QChar SymbolCross;
1610   
1611 protected:
1612   struct CachedLabel
1613   {
1614     QPoint offset;
1615     QPixmap pixmap;
1616   };
1617   struct LabelData
1618   {
1619     AnchorSide side;
1620     double rotation; // angle in degrees
1621     QTransform transform; // the transform about the label anchor which is at (0, 0). Does not contain final absolute x/y positioning on the plot/axis
1622     QString basePart, expPart, suffixPart;
1623     QRect baseBounds, expBounds, suffixBounds;
1624     QRect totalBounds; // is in a coordinate system where label top left is at (0, 0)
1625     QRect rotatedTotalBounds; // is in a coordinate system where the label anchor is at (0, 0)
1626     QFont baseFont, expFont;
1627     QColor color;
1628   };
1629   
1630   // property members:
1631   AnchorMode mAnchorMode;
1632   AnchorSide mAnchorSide;
1633   QPointF mAnchorReference;
1634   AnchorReferenceType mAnchorReferenceType;
1635   QFont mFont;
1636   QColor mColor;
1637   int mPadding;
1638   double mRotation; // this is the rotation applied uniformly to all labels, not the heterogeneous rotation in amCircularRotated mode
1639   bool mSubstituteExponent;
1640   QChar mMultiplicationSymbol;
1641   bool mAbbreviateDecimalPowers;
1642   // non-property members:
1643   QCustomPlot *mParentPlot;
1644   QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters
1645   QCache<QString, CachedLabel> mLabelCache;
1646   QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox;
1647   int mLetterCapHeight, mLetterDescent;
1648   
1649   // introduced virtual methods:
1650   virtual void drawLabelMaybeCached(QCPPainter *painter, const QFont &font, const QColor &color, const QPointF &pos, AnchorSide side, double rotation, const QString &text);
1651   virtual QByteArray generateLabelParameterHash() const; // TODO: get rid of this in favor of invalidation flag upon setters?
1652 
1653   // non-virtual methods:
1654   QPointF getAnchorPos(const QPointF &tickPos);
1655   void drawText(QCPPainter *painter, const QPointF &pos, const LabelData &labelData) const;
1656   LabelData getTickLabelData(const QFont &font, const QColor &color, double rotation, AnchorSide side, const QString &text) const;
1657   void applyAnchorTransform(LabelData &labelData) const;
1658   //void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const;
1659   CachedLabel *createCachedLabel(const LabelData &labelData) const;
1660   QByteArray cacheKey(const QString &text, const QColor &color, double rotation, AnchorSide side) const;
1661   AnchorSide skewedAnchorSide(const QPointF &tickPos, double sideExpandHorz, double sideExpandVert) const;
1662   AnchorSide rotationCorrectedSide(AnchorSide side, double rotation) const;
1663   void analyzeFontMetrics();
1664 };
1665 Q_DECLARE_METATYPE(QCPLabelPainterPrivate::AnchorMode)
1666 Q_DECLARE_METATYPE(QCPLabelPainterPrivate::AnchorSide)
1667 
1668 
1669 /* end of 'src/axis/labelpainter.h' */
1670 
1671 
1672 /* including file 'src/axis/axisticker.h'  */
1673 /* modified 2021-03-29T02:30:44, size 4230 */
1674 
1675 class QCP_LIB_DECL QCPAxisTicker
1676 {
1677   Q_GADGET
1678 public:
1679   /*!
1680     Defines the strategies that the axis ticker may follow when choosing the size of the tick step.
1681     
1682     \see setTickStepStrategy
1683   */
1684   enum TickStepStrategy
1685   {
1686     tssReadability    ///< A nicely readable tick step is prioritized over matching the requested number of ticks (see \ref setTickCount)
1687     ,tssMeetTickCount ///< Less readable tick steps are allowed which in turn facilitates getting closer to the requested tick count
1688   };
1689   Q_ENUMS(TickStepStrategy)
1690   
1691   QCPAxisTicker();
1692   virtual ~QCPAxisTicker();
1693   
1694   // getters:
1695   TickStepStrategy tickStepStrategy() const { return mTickStepStrategy; }
1696   int tickCount() const { return mTickCount; }
1697   double tickOrigin() const { return mTickOrigin; }
1698   
1699   // setters:
1700   void setTickStepStrategy(TickStepStrategy strategy);
1701   void setTickCount(int count);
1702   void setTickOrigin(double origin);
1703   
1704   // introduced virtual methods:
1705   virtual void generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector<double> &ticks, QVector<double> *subTicks, QVector<QString> *tickLabels);
1706   
1707 protected:
1708   // property members:
1709   TickStepStrategy mTickStepStrategy;
1710   int mTickCount;
1711   double mTickOrigin;
1712   
1713   // introduced virtual methods:
1714   virtual double getTickStep(const QCPRange &range);
1715   virtual int getSubTickCount(double tickStep);
1716   virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision);
1717   virtual QVector<double> createTickVector(double tickStep, const QCPRange &range);
1718   virtual QVector<double> createSubTickVector(int subTickCount, const QVector<double> &ticks);
1719   virtual QVector<QString> createLabelVector(const QVector<double> &ticks, const QLocale &locale, QChar formatChar, int precision);
1720   
1721   // non-virtual methods:
1722   void trimTicks(const QCPRange &range, QVector<double> &ticks, bool keepOneOutlier) const;
1723   double pickClosest(double target, const QVector<double> &candidates) const;
1724   double getMantissa(double input, double *magnitude=nullptr) const;
1725   double cleanMantissa(double input) const;
1726   
1727 private:
1728   Q_DISABLE_COPY(QCPAxisTicker)
1729   
1730 };
1731 Q_DECLARE_METATYPE(QCPAxisTicker::TickStepStrategy)
1732 Q_DECLARE_METATYPE(QSharedPointer<QCPAxisTicker>)
1733 
1734 /* end of 'src/axis/axisticker.h' */
1735 
1736 
1737 /* including file 'src/axis/axistickerdatetime.h' */
1738 /* modified 2021-03-29T02:30:44, size 3600        */
1739 
1740 class QCP_LIB_DECL QCPAxisTickerDateTime : public QCPAxisTicker
1741 {
1742 public:
1743   QCPAxisTickerDateTime();
1744   
1745   // getters:
1746   QString dateTimeFormat() const { return mDateTimeFormat; }
1747   Qt::TimeSpec dateTimeSpec() const { return mDateTimeSpec; }
1748 # if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
1749   QTimeZone timeZone() const { return mTimeZone; }
1750 #endif
1751   
1752   // setters:
1753   void setDateTimeFormat(const QString &format);
1754   void setDateTimeSpec(Qt::TimeSpec spec);
1755 # if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
1756   void setTimeZone(const QTimeZone &zone);
1757 # endif
1758   void setTickOrigin(double origin); // hides base class method but calls baseclass implementation ("using" throws off IDEs and doxygen)
1759   void setTickOrigin(const QDateTime &origin);
1760   
1761   // static methods:
1762   static QDateTime keyToDateTime(double key);
1763   static double dateTimeToKey(const QDateTime &dateTime);
1764   static double dateTimeToKey(const QDate &date, Qt::TimeSpec timeSpec=Qt::LocalTime);
1765   
1766 protected:
1767   // property members:
1768   QString mDateTimeFormat;
1769   Qt::TimeSpec mDateTimeSpec;
1770 # if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
1771   QTimeZone mTimeZone;
1772 # endif
1773   // non-property members:
1774   enum DateStrategy {dsNone, dsUniformTimeInDay, dsUniformDayInMonth} mDateStrategy;
1775   
1776   // reimplemented virtual methods:
1777   virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE;
1778   virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE;
1779   virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE;
1780   virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE;
1781 };
1782 
1783 /* end of 'src/axis/axistickerdatetime.h' */
1784 
1785 
1786 /* including file 'src/axis/axistickertime.h' */
1787 /* modified 2021-03-29T02:30:44, size 3542    */
1788 
1789 class QCP_LIB_DECL QCPAxisTickerTime : public QCPAxisTicker
1790 {
1791   Q_GADGET
1792 public:
1793   /*!
1794     Defines the logical units in which fractions of time spans can be expressed.
1795     
1796     \see setFieldWidth, setTimeFormat
1797   */
1798   enum TimeUnit { tuMilliseconds ///< Milliseconds, one thousandth of a second (%%z in \ref setTimeFormat)
1799                   ,tuSeconds     ///< Seconds (%%s in \ref setTimeFormat)
1800                   ,tuMinutes     ///< Minutes (%%m in \ref setTimeFormat)
1801                   ,tuHours       ///< Hours (%%h in \ref setTimeFormat)
1802                   ,tuDays        ///< Days (%%d in \ref setTimeFormat)
1803                 };
1804   Q_ENUMS(TimeUnit)
1805   
1806   QCPAxisTickerTime();
1807 
1808   // getters:
1809   QString timeFormat() const { return mTimeFormat; }
1810   int fieldWidth(TimeUnit unit) const { return mFieldWidth.value(unit); }
1811   
1812   // setters:
1813   void setTimeFormat(const QString &format);
1814   void setFieldWidth(TimeUnit unit, int width);
1815   
1816 protected:
1817   // property members:
1818   QString mTimeFormat;
1819   QHash<TimeUnit, int> mFieldWidth;
1820   
1821   // non-property members:
1822   TimeUnit mSmallestUnit, mBiggestUnit;
1823   QHash<TimeUnit, QString> mFormatPattern;
1824   
1825   // reimplemented virtual methods:
1826   virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE;
1827   virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE;
1828   virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE;
1829   
1830   // non-virtual methods:
1831   void replaceUnit(QString &text, TimeUnit unit, int value) const;
1832 };
1833 Q_DECLARE_METATYPE(QCPAxisTickerTime::TimeUnit)
1834 
1835 /* end of 'src/axis/axistickertime.h' */
1836 
1837 
1838 /* including file 'src/axis/axistickerfixed.h' */
1839 /* modified 2021-03-29T02:30:44, size 3308     */
1840 
1841 class QCP_LIB_DECL QCPAxisTickerFixed : public QCPAxisTicker
1842 {
1843   Q_GADGET
1844 public:
1845   /*!
1846     Defines how the axis ticker may modify the specified tick step (\ref setTickStep) in order to
1847     control the number of ticks in the axis range.
1848     
1849     \see setScaleStrategy
1850   */
1851   enum ScaleStrategy { ssNone      ///< Modifications are not allowed, the specified tick step is absolutely fixed. This might cause a high tick density and overlapping labels if the axis range is zoomed out.
1852                        ,ssMultiples ///< An integer multiple of the specified tick step is allowed. The used factor follows the base class properties of \ref setTickStepStrategy and \ref setTickCount.
1853                        ,ssPowers    ///< An integer power of the specified tick step is allowed.
1854                      };
1855   Q_ENUMS(ScaleStrategy)
1856   
1857   QCPAxisTickerFixed();
1858   
1859   // getters:
1860   double tickStep() const { return mTickStep; }
1861   ScaleStrategy scaleStrategy() const { return mScaleStrategy; }
1862   
1863   // setters:
1864   void setTickStep(double step);
1865   void setScaleStrategy(ScaleStrategy strategy);
1866   
1867 protected:
1868   // property members:
1869   double mTickStep;
1870   ScaleStrategy mScaleStrategy;
1871   
1872   // reimplemented virtual methods:
1873   virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE;
1874 };
1875 Q_DECLARE_METATYPE(QCPAxisTickerFixed::ScaleStrategy)
1876 
1877 /* end of 'src/axis/axistickerfixed.h' */
1878 
1879 
1880 /* including file 'src/axis/axistickertext.h' */
1881 /* modified 2021-03-29T02:30:44, size 3090    */
1882 
1883 class QCP_LIB_DECL QCPAxisTickerText : public QCPAxisTicker
1884 {
1885 public:
1886   QCPAxisTickerText();
1887   
1888   // getters:
1889   QMap<double, QString> &ticks() { return mTicks; }
1890   int subTickCount() const { return mSubTickCount; }
1891   
1892   // setters:
1893   void setTicks(const QMap<double, QString> &ticks);
1894   void setTicks(const QVector<double> &positions, const QVector<QString> &labels);
1895   void setSubTickCount(int subTicks);
1896   
1897   // non-virtual methods:
1898   void clear();
1899   void addTick(double position, const QString &label);
1900   void addTicks(const QMap<double, QString> &ticks);
1901   void addTicks(const QVector<double> &positions, const QVector<QString> &labels);
1902   
1903 protected:
1904   // property members:
1905   QMap<double, QString> mTicks;
1906   int mSubTickCount;
1907   
1908   // reimplemented virtual methods:
1909   virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE;
1910   virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE;
1911   virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE;
1912   virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE;
1913 };
1914 
1915 /* end of 'src/axis/axistickertext.h' */
1916 
1917 
1918 /* including file 'src/axis/axistickerpi.h' */
1919 /* modified 2021-03-29T02:30:44, size 3911  */
1920 
1921 class QCP_LIB_DECL QCPAxisTickerPi : public QCPAxisTicker
1922 {
1923   Q_GADGET
1924 public:
1925   /*!
1926     Defines how fractions should be displayed in tick labels.
1927     
1928     \see setFractionStyle
1929   */
1930   enum FractionStyle { fsFloatingPoint     ///< Fractions are displayed as regular decimal floating point numbers, e.g. "0.25" or "0.125".
1931                        ,fsAsciiFractions   ///< Fractions are written as rationals using ASCII characters only, e.g. "1/4" or "1/8"
1932                        ,fsUnicodeFractions ///< Fractions are written using sub- and superscript UTF-8 digits and the fraction symbol.
1933                      };
1934   Q_ENUMS(FractionStyle)
1935   
1936   QCPAxisTickerPi();
1937   
1938   // getters:
1939   QString piSymbol() const { return mPiSymbol; }
1940   double piValue() const { return mPiValue; }
1941   bool periodicity() const { return mPeriodicity; }
1942   FractionStyle fractionStyle() const { return mFractionStyle; }
1943   
1944   // setters:
1945   void setPiSymbol(QString symbol);
1946   void setPiValue(double pi);
1947   void setPeriodicity(int multiplesOfPi);
1948   void setFractionStyle(FractionStyle style);
1949   
1950 protected:
1951   // property members:
1952   QString mPiSymbol;
1953   double mPiValue;
1954   int mPeriodicity;
1955   FractionStyle mFractionStyle;
1956   
1957   // non-property members:
1958   double mPiTickStep; // size of one tick step in units of mPiValue
1959   
1960   // reimplemented virtual methods:
1961   virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE;
1962   virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE;
1963   virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE;
1964   
1965   // non-virtual methods:
1966   void simplifyFraction(int &numerator, int &denominator) const;
1967   QString fractionToString(int numerator, int denominator) const;
1968   QString unicodeFraction(int numerator, int denominator) const;
1969   QString unicodeSuperscript(int number) const;
1970   QString unicodeSubscript(int number) const;
1971 };
1972 Q_DECLARE_METATYPE(QCPAxisTickerPi::FractionStyle)
1973 
1974 /* end of 'src/axis/axistickerpi.h' */
1975 
1976 
1977 /* including file 'src/axis/axistickerlog.h' */
1978 /* modified 2021-03-29T02:30:44, size 2594   */
1979 
1980 class QCP_LIB_DECL QCPAxisTickerLog : public QCPAxisTicker
1981 {
1982 public:
1983   QCPAxisTickerLog();
1984   
1985   // getters:
1986   double logBase() const { return mLogBase; }
1987   int subTickCount() const { return mSubTickCount; }
1988   
1989   // setters:
1990   void setLogBase(double base);
1991   void setSubTickCount(int subTicks);
1992   
1993 protected:
1994   // property members:
1995   double mLogBase;
1996   int mSubTickCount;
1997   
1998   // non-property members:
1999   double mLogBaseLnInv;
2000   
2001   // reimplemented virtual methods:
2002   virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE;
2003   virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE;
2004 };
2005 
2006 /* end of 'src/axis/axistickerlog.h' */
2007 
2008 
2009 /* including file 'src/axis/axis.h'         */
2010 /* modified 2021-03-29T02:30:44, size 20913 */
2011 
2012 class QCP_LIB_DECL QCPGrid :public QCPLayerable
2013 {
2014   Q_OBJECT
2015   /// \cond INCLUDE_QPROPERTIES
2016   Q_PROPERTY(bool subGridVisible READ subGridVisible WRITE setSubGridVisible)
2017   Q_PROPERTY(bool antialiasedSubGrid READ antialiasedSubGrid WRITE setAntialiasedSubGrid)
2018   Q_PROPERTY(bool antialiasedZeroLine READ antialiasedZeroLine WRITE setAntialiasedZeroLine)
2019   Q_PROPERTY(QPen pen READ pen WRITE setPen)
2020   Q_PROPERTY(QPen subGridPen READ subGridPen WRITE setSubGridPen)
2021   Q_PROPERTY(QPen zeroLinePen READ zeroLinePen WRITE setZeroLinePen)
2022   /// \endcond
2023 public:
2024   explicit QCPGrid(QCPAxis *parentAxis);
2025   
2026   // getters:
2027   bool subGridVisible() const { return mSubGridVisible; }
2028   bool antialiasedSubGrid() const { return mAntialiasedSubGrid; }
2029   bool antialiasedZeroLine() const { return mAntialiasedZeroLine; }
2030   QPen pen() const { return mPen; }
2031   QPen subGridPen() const { return mSubGridPen; }
2032   QPen zeroLinePen() const { return mZeroLinePen; }
2033   
2034   // setters:
2035   void setSubGridVisible(bool visible);
2036   void setAntialiasedSubGrid(bool enabled);
2037   void setAntialiasedZeroLine(bool enabled);
2038   void setPen(const QPen &pen);
2039   void setSubGridPen(const QPen &pen);
2040   void setZeroLinePen(const QPen &pen);
2041   
2042 protected:
2043   // property members:
2044   bool mSubGridVisible;
2045   bool mAntialiasedSubGrid, mAntialiasedZeroLine;
2046   QPen mPen, mSubGridPen, mZeroLinePen;
2047   
2048   // non-property members:
2049   QCPAxis *mParentAxis;
2050   
2051   // reimplemented virtual methods:
2052   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
2053   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
2054   
2055   // non-virtual methods:
2056   void drawGridLines(QCPPainter *painter) const;
2057   void drawSubGridLines(QCPPainter *painter) const;
2058   
2059   friend class QCPAxis;
2060 };
2061 
2062 
2063 class QCP_LIB_DECL QCPAxis : public QCPLayerable
2064 {
2065   Q_OBJECT
2066   /// \cond INCLUDE_QPROPERTIES
2067   Q_PROPERTY(AxisType axisType READ axisType)
2068   Q_PROPERTY(QCPAxisRect* axisRect READ axisRect)
2069   Q_PROPERTY(ScaleType scaleType READ scaleType WRITE setScaleType NOTIFY scaleTypeChanged)
2070   Q_PROPERTY(QCPRange range READ range WRITE setRange NOTIFY rangeChanged)
2071   Q_PROPERTY(bool rangeReversed READ rangeReversed WRITE setRangeReversed)
2072   Q_PROPERTY(QSharedPointer<QCPAxisTicker> ticker READ ticker WRITE setTicker)
2073   Q_PROPERTY(bool ticks READ ticks WRITE setTicks)
2074   Q_PROPERTY(bool tickLabels READ tickLabels WRITE setTickLabels)
2075   Q_PROPERTY(int tickLabelPadding READ tickLabelPadding WRITE setTickLabelPadding)
2076   Q_PROPERTY(QFont tickLabelFont READ tickLabelFont WRITE setTickLabelFont)
2077   Q_PROPERTY(QColor tickLabelColor READ tickLabelColor WRITE setTickLabelColor)
2078   Q_PROPERTY(double tickLabelRotation READ tickLabelRotation WRITE setTickLabelRotation)
2079   Q_PROPERTY(LabelSide tickLabelSide READ tickLabelSide WRITE setTickLabelSide)
2080   Q_PROPERTY(QString numberFormat READ numberFormat WRITE setNumberFormat)
2081   Q_PROPERTY(int numberPrecision READ numberPrecision WRITE setNumberPrecision)
2082   Q_PROPERTY(QVector<double> tickVector READ tickVector)
2083   Q_PROPERTY(QVector<QString> tickVectorLabels READ tickVectorLabels)
2084   Q_PROPERTY(int tickLengthIn READ tickLengthIn WRITE setTickLengthIn)
2085   Q_PROPERTY(int tickLengthOut READ tickLengthOut WRITE setTickLengthOut)
2086   Q_PROPERTY(bool subTicks READ subTicks WRITE setSubTicks)
2087   Q_PROPERTY(int subTickLengthIn READ subTickLengthIn WRITE setSubTickLengthIn)
2088   Q_PROPERTY(int subTickLengthOut READ subTickLengthOut WRITE setSubTickLengthOut)
2089   Q_PROPERTY(QPen basePen READ basePen WRITE setBasePen)
2090   Q_PROPERTY(QPen tickPen READ tickPen WRITE setTickPen)
2091   Q_PROPERTY(QPen subTickPen READ subTickPen WRITE setSubTickPen)
2092   Q_PROPERTY(QFont labelFont READ labelFont WRITE setLabelFont)
2093   Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor)
2094   Q_PROPERTY(QString label READ label WRITE setLabel)
2095   Q_PROPERTY(int labelPadding READ labelPadding WRITE setLabelPadding)
2096   Q_PROPERTY(int padding READ padding WRITE setPadding)
2097   Q_PROPERTY(int offset READ offset WRITE setOffset)
2098   Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectionChanged)
2099   Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectableChanged)
2100   Q_PROPERTY(QFont selectedTickLabelFont READ selectedTickLabelFont WRITE setSelectedTickLabelFont)
2101   Q_PROPERTY(QFont selectedLabelFont READ selectedLabelFont WRITE setSelectedLabelFont)
2102   Q_PROPERTY(QColor selectedTickLabelColor READ selectedTickLabelColor WRITE setSelectedTickLabelColor)
2103   Q_PROPERTY(QColor selectedLabelColor READ selectedLabelColor WRITE setSelectedLabelColor)
2104   Q_PROPERTY(QPen selectedBasePen READ selectedBasePen WRITE setSelectedBasePen)
2105   Q_PROPERTY(QPen selectedTickPen READ selectedTickPen WRITE setSelectedTickPen)
2106   Q_PROPERTY(QPen selectedSubTickPen READ selectedSubTickPen WRITE setSelectedSubTickPen)
2107   Q_PROPERTY(QCPLineEnding lowerEnding READ lowerEnding WRITE setLowerEnding)
2108   Q_PROPERTY(QCPLineEnding upperEnding READ upperEnding WRITE setUpperEnding)
2109   Q_PROPERTY(QCPGrid* grid READ grid)
2110   /// \endcond
2111 public:
2112   /*!
2113     Defines at which side of the axis rect the axis will appear. This also affects how the tick
2114     marks are drawn, on which side the labels are placed etc.
2115   */
2116   enum AxisType { atLeft    = 0x01  ///< <tt>0x01</tt> Axis is vertical and on the left side of the axis rect
2117                   ,atRight  = 0x02  ///< <tt>0x02</tt> Axis is vertical and on the right side of the axis rect
2118                   ,atTop    = 0x04  ///< <tt>0x04</tt> Axis is horizontal and on the top side of the axis rect
2119                   ,atBottom = 0x08  ///< <tt>0x08</tt> Axis is horizontal and on the bottom side of the axis rect
2120                 };
2121   Q_ENUMS(AxisType)
2122   Q_FLAGS(AxisTypes)
2123   Q_DECLARE_FLAGS(AxisTypes, AxisType)
2124   /*!
2125     Defines on which side of the axis the tick labels (numbers) shall appear.
2126     
2127     \see setTickLabelSide
2128   */
2129   enum LabelSide { lsInside    ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect
2130                    ,lsOutside  ///< Tick labels will be displayed outside the axis rect
2131                  };
2132   Q_ENUMS(LabelSide)
2133   /*!
2134     Defines the scale of an axis.
2135     \see setScaleType
2136   */
2137   enum ScaleType { stLinear       ///< Linear scaling
2138                    ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed axis coordinates (possibly also \ref setTicker to a \ref QCPAxisTickerLog instance).
2139                  };
2140   Q_ENUMS(ScaleType)
2141   /*!
2142     Defines the selectable parts of an axis.
2143     \see setSelectableParts, setSelectedParts
2144   */
2145   enum SelectablePart { spNone        = 0      ///< None of the selectable parts
2146                         ,spAxis       = 0x001  ///< The axis backbone and tick marks
2147                         ,spTickLabels = 0x002  ///< Tick labels (numbers) of this axis (as a whole, not individually)
2148                         ,spAxisLabel  = 0x004  ///< The axis label
2149                       };
2150   Q_ENUMS(SelectablePart)
2151   Q_FLAGS(SelectableParts)
2152   Q_DECLARE_FLAGS(SelectableParts, SelectablePart)
2153   
2154   explicit QCPAxis(QCPAxisRect *parent, AxisType type);
2155   virtual ~QCPAxis() Q_DECL_OVERRIDE;
2156   
2157   // getters:
2158   AxisType axisType() const { return mAxisType; }
2159   QCPAxisRect *axisRect() const { return mAxisRect; }
2160   ScaleType scaleType() const { return mScaleType; }
2161   const QCPRange range() const { return mRange; }
2162   bool rangeReversed() const { return mRangeReversed; }
2163   QSharedPointer<QCPAxisTicker> ticker() const { return mTicker; }
2164   bool ticks() const { return mTicks; }
2165   bool tickLabels() const { return mTickLabels; }
2166   int tickLabelPadding() const;
2167   QFont tickLabelFont() const { return mTickLabelFont; }
2168   QColor tickLabelColor() const { return mTickLabelColor; }
2169   double tickLabelRotation() const;
2170   LabelSide tickLabelSide() const;
2171   QString numberFormat() const;
2172   int numberPrecision() const { return mNumberPrecision; }
2173   QVector<double> tickVector() const { return mTickVector; }
2174   QVector<QString> tickVectorLabels() const { return mTickVectorLabels; }
2175   int tickLengthIn() const;
2176   int tickLengthOut() const;
2177   bool subTicks() const { return mSubTicks; }
2178   int subTickLengthIn() const;
2179   int subTickLengthOut() const;
2180   QPen basePen() const { return mBasePen; }
2181   QPen tickPen() const { return mTickPen; }
2182   QPen subTickPen() const { return mSubTickPen; }
2183   QFont labelFont() const { return mLabelFont; }
2184   QColor labelColor() const { return mLabelColor; }
2185   QString label() const { return mLabel; }
2186   int labelPadding() const;
2187   int padding() const { return mPadding; }
2188   int offset() const;
2189   SelectableParts selectedParts() const { return mSelectedParts; }
2190   SelectableParts selectableParts() const { return mSelectableParts; }
2191   QFont selectedTickLabelFont() const { return mSelectedTickLabelFont; }
2192   QFont selectedLabelFont() const { return mSelectedLabelFont; }
2193   QColor selectedTickLabelColor() const { return mSelectedTickLabelColor; }
2194   QColor selectedLabelColor() const { return mSelectedLabelColor; }
2195   QPen selectedBasePen() const { return mSelectedBasePen; }
2196   QPen selectedTickPen() const { return mSelectedTickPen; }
2197   QPen selectedSubTickPen() const { return mSelectedSubTickPen; }
2198   QCPLineEnding lowerEnding() const;
2199   QCPLineEnding upperEnding() const;
2200   QCPGrid *grid() const { return mGrid; }
2201   
2202   // setters:
2203   Q_SLOT void setScaleType(QCPAxis::ScaleType type);
2204   Q_SLOT void setRange(const QCPRange &range);
2205   void setRange(double lower, double upper);
2206   void setRange(double position, double size, Qt::AlignmentFlag alignment);
2207   void setRangeLower(double lower);
2208   void setRangeUpper(double upper);
2209   void setRangeReversed(bool reversed);
2210   void setTicker(QSharedPointer<QCPAxisTicker> ticker);
2211   void setTicks(bool show);
2212   void setTickLabels(bool show);
2213   void setTickLabelPadding(int padding);
2214   void setTickLabelFont(const QFont &font);
2215   void setTickLabelColor(const QColor &color);
2216   void setTickLabelRotation(double degrees);
2217   void setTickLabelSide(LabelSide side);
2218   void setNumberFormat(const QString &formatCode);
2219   void setNumberPrecision(int precision);
2220   void setTickLength(int inside, int outside=0);
2221   void setTickLengthIn(int inside);
2222   void setTickLengthOut(int outside);
2223   void setSubTicks(bool show);
2224   void setSubTickLength(int inside, int outside=0);
2225   void setSubTickLengthIn(int inside);
2226   void setSubTickLengthOut(int outside);
2227   void setBasePen(const QPen &pen);
2228   void setTickPen(const QPen &pen);
2229   void setSubTickPen(const QPen &pen);
2230   void setLabelFont(const QFont &font);
2231   void setLabelColor(const QColor &color);
2232   void setLabel(const QString &str);
2233   void setLabelPadding(int padding);
2234   void setPadding(int padding);
2235   void setOffset(int offset);
2236   void setSelectedTickLabelFont(const QFont &font);
2237   void setSelectedLabelFont(const QFont &font);
2238   void setSelectedTickLabelColor(const QColor &color);
2239   void setSelectedLabelColor(const QColor &color);
2240   void setSelectedBasePen(const QPen &pen);
2241   void setSelectedTickPen(const QPen &pen);
2242   void setSelectedSubTickPen(const QPen &pen);
2243   Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts);
2244   Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts);
2245   void setLowerEnding(const QCPLineEnding &ending);
2246   void setUpperEnding(const QCPLineEnding &ending);
2247   
2248   // reimplemented virtual methods:
2249   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
2250   
2251   // non-property methods:
2252   Qt::Orientation orientation() const { return mOrientation; }
2253   int pixelOrientation() const { return rangeReversed() != (orientation()==Qt::Vertical) ? -1 : 1; }
2254   void moveRange(double diff);
2255   void scaleRange(double factor);
2256   void scaleRange(double factor, double center);
2257   void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0);
2258   void rescale(bool onlyVisiblePlottables=false);
2259   double pixelToCoord(double value) const;
2260   double coordToPixel(double value) const;
2261   SelectablePart getPartAt(const QPointF &pos) const;
2262   QList<QCPAbstractPlottable*> plottables() const;
2263   QList<QCPGraph*> graphs() const;
2264   QList<QCPAbstractItem*> items() const;
2265   
2266   static AxisType marginSideToAxisType(QCP::MarginSide side);
2267   static Qt::Orientation orientation(AxisType type) { return type==atBottom || type==atTop ? Qt::Horizontal : Qt::Vertical; }
2268   static AxisType opposite(AxisType type);
2269   
2270 signals:
2271   void rangeChanged(const QCPRange &newRange);
2272   void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange);
2273   void scaleTypeChanged(QCPAxis::ScaleType scaleType);
2274   void selectionChanged(const QCPAxis::SelectableParts &parts);
2275   void selectableChanged(const QCPAxis::SelectableParts &parts);
2276 
2277 protected:
2278   // property members:
2279   // axis base:
2280   AxisType mAxisType;
2281   QCPAxisRect *mAxisRect;
2282   //int mOffset; // in QCPAxisPainter
2283   int mPadding;
2284   Qt::Orientation mOrientation;
2285   SelectableParts mSelectableParts, mSelectedParts;
2286   QPen mBasePen, mSelectedBasePen;
2287   //QCPLineEnding mLowerEnding, mUpperEnding; // in QCPAxisPainter
2288   // axis label:
2289   //int mLabelPadding; // in QCPAxisPainter
2290   QString mLabel;
2291   QFont mLabelFont, mSelectedLabelFont;
2292   QColor mLabelColor, mSelectedLabelColor;
2293   // tick labels:
2294   //int mTickLabelPadding; // in QCPAxisPainter
2295   bool mTickLabels;
2296   //double mTickLabelRotation; // in QCPAxisPainter
2297   QFont mTickLabelFont, mSelectedTickLabelFont;
2298   QColor mTickLabelColor, mSelectedTickLabelColor;
2299   int mNumberPrecision;
2300   QLatin1Char mNumberFormatChar;
2301   bool mNumberBeautifulPowers;
2302   //bool mNumberMultiplyCross; // QCPAxisPainter
2303   // ticks and subticks:
2304   bool mTicks;
2305   bool mSubTicks;
2306   //int mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut; // QCPAxisPainter
2307   QPen mTickPen, mSelectedTickPen;
2308   QPen mSubTickPen, mSelectedSubTickPen;
2309   // scale and range:
2310   QCPRange mRange;
2311   bool mRangeReversed;
2312   ScaleType mScaleType;
2313   
2314   // non-property members:
2315   QCPGrid *mGrid;
2316   QCPAxisPainterPrivate *mAxisPainter;
2317   QSharedPointer<QCPAxisTicker> mTicker;
2318   QVector<double> mTickVector;
2319   QVector<QString> mTickVectorLabels;
2320   QVector<double> mSubTickVector;
2321   bool mCachedMarginValid;
2322   int mCachedMargin;
2323   bool mDragging;
2324   QCPRange mDragStartRange;
2325   QCP::AntialiasedElements mAADragBackup, mNotAADragBackup;
2326   
2327   // introduced virtual methods:
2328   virtual int calculateMargin();
2329   
2330   // reimplemented virtual methods:
2331   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
2332   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
2333   virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE;
2334   // events:
2335   virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
2336   virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE;
2337   // mouse events:
2338   virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE;
2339   virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE;
2340   virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE;
2341   virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
2342   
2343   // non-virtual methods:
2344   void setupTickVectors();
2345   QPen getBasePen() const;
2346   QPen getTickPen() const;
2347   QPen getSubTickPen() const;
2348   QFont getTickLabelFont() const;
2349   QFont getLabelFont() const;
2350   QColor getTickLabelColor() const;
2351   QColor getLabelColor() const;
2352   
2353 private:
2354   Q_DISABLE_COPY(QCPAxis)
2355   
2356   friend class QCustomPlot;
2357   friend class QCPGrid;
2358   friend class QCPAxisRect;
2359 };
2360 Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::SelectableParts)
2361 Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::AxisTypes)
2362 Q_DECLARE_METATYPE(QCPAxis::AxisType)
2363 Q_DECLARE_METATYPE(QCPAxis::LabelSide)
2364 Q_DECLARE_METATYPE(QCPAxis::ScaleType)
2365 Q_DECLARE_METATYPE(QCPAxis::SelectablePart)
2366 
2367 
2368 class QCPAxisPainterPrivate
2369 {
2370 public:
2371   explicit QCPAxisPainterPrivate(QCustomPlot *parentPlot);
2372   virtual ~QCPAxisPainterPrivate();
2373   
2374   virtual void draw(QCPPainter *painter);
2375   virtual int size();
2376   void clearCache();
2377   
2378   QRect axisSelectionBox() const { return mAxisSelectionBox; }
2379   QRect tickLabelsSelectionBox() const { return mTickLabelsSelectionBox; }
2380   QRect labelSelectionBox() const { return mLabelSelectionBox; }
2381   
2382   // public property members:
2383   QCPAxis::AxisType type;
2384   QPen basePen;
2385   QCPLineEnding lowerEnding, upperEnding; // directly accessed by QCPAxis setters/getters
2386   int labelPadding; // directly accessed by QCPAxis setters/getters
2387   QFont labelFont;
2388   QColor labelColor;
2389   QString label;
2390   int tickLabelPadding; // directly accessed by QCPAxis setters/getters
2391   double tickLabelRotation; // directly accessed by QCPAxis setters/getters
2392   QCPAxis::LabelSide tickLabelSide; // directly accessed by QCPAxis setters/getters
2393   bool substituteExponent;
2394   bool numberMultiplyCross; // directly accessed by QCPAxis setters/getters
2395   int tickLengthIn, tickLengthOut, subTickLengthIn, subTickLengthOut; // directly accessed by QCPAxis setters/getters
2396   QPen tickPen, subTickPen;
2397   QFont tickLabelFont;
2398   QColor tickLabelColor;
2399   QRect axisRect, viewportRect;
2400   int offset; // directly accessed by QCPAxis setters/getters
2401   bool abbreviateDecimalPowers;
2402   bool reversedEndings;
2403   
2404   QVector<double> subTickPositions;
2405   QVector<double> tickPositions;
2406   QVector<QString> tickLabels;
2407   
2408 protected:
2409   struct CachedLabel
2410   {
2411     QPointF offset;
2412     QPixmap pixmap;
2413   };
2414   struct TickLabelData
2415   {
2416     QString basePart, expPart, suffixPart;
2417     QRect baseBounds, expBounds, suffixBounds, totalBounds, rotatedTotalBounds;
2418     QFont baseFont, expFont;
2419   };
2420   QCustomPlot *mParentPlot;
2421   QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters
2422   QCache<QString, CachedLabel> mLabelCache;
2423   QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox;
2424   
2425   virtual QByteArray generateLabelParameterHash() const;
2426   
2427   virtual void placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize);
2428   virtual void drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const;
2429   virtual TickLabelData getTickLabelData(const QFont &font, const QString &text) const;
2430   virtual QPointF getTickLabelDrawOffset(const TickLabelData &labelData) const;
2431   virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const;
2432 };
2433 
2434 /* end of 'src/axis/axis.h' */
2435 
2436 
2437 /* including file 'src/scatterstyle.h'     */
2438 /* modified 2021-03-29T02:30:44, size 7275 */
2439 
2440 class QCP_LIB_DECL QCPScatterStyle
2441 {
2442   Q_GADGET
2443 public:
2444   /*!
2445     Represents the various properties of a scatter style instance. For example, this enum is used
2446     to specify which properties of \ref QCPSelectionDecorator::setScatterStyle will be used when
2447     highlighting selected data points.
2448 
2449     Specific scatter properties can be transferred between \ref QCPScatterStyle instances via \ref
2450     setFromOther.
2451   */
2452   enum ScatterProperty { spNone  = 0x00  ///< <tt>0x00</tt> None
2453                          ,spPen   = 0x01  ///< <tt>0x01</tt> The pen property, see \ref setPen
2454                          ,spBrush = 0x02  ///< <tt>0x02</tt> The brush property, see \ref setBrush
2455                          ,spSize  = 0x04  ///< <tt>0x04</tt> The size property, see \ref setSize
2456                          ,spShape = 0x08  ///< <tt>0x08</tt> The shape property, see \ref setShape
2457                          ,spAll   = 0xFF  ///< <tt>0xFF</tt> All properties
2458                        };
2459   Q_ENUMS(ScatterProperty)
2460   Q_FLAGS(ScatterProperties)
2461   Q_DECLARE_FLAGS(ScatterProperties, ScatterProperty)
2462 
2463   /*!
2464     Defines the shape used for scatter points.
2465 
2466     On plottables/items that draw scatters, the sizes of these visualizations (with exception of
2467     \ref ssDot and \ref ssPixmap) can be controlled with the \ref setSize function. Scatters are
2468     drawn with the pen and brush specified with \ref setPen and \ref setBrush.
2469   */
2470   enum ScatterShape { ssNone       ///< no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines)
2471                       ,ssDot       ///< \enumimage{ssDot.png} a single pixel (use \ref ssDisc or \ref ssCircle if you want a round shape with a certain radius)
2472                       ,ssCross     ///< \enumimage{ssCross.png} a cross
2473                       ,ssPlus      ///< \enumimage{ssPlus.png} a plus
2474                       ,ssCircle    ///< \enumimage{ssCircle.png} a circle
2475                       ,ssDisc      ///< \enumimage{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle)
2476                       ,ssSquare    ///< \enumimage{ssSquare.png} a square
2477                       ,ssDiamond   ///< \enumimage{ssDiamond.png} a diamond
2478                       ,ssStar      ///< \enumimage{ssStar.png} a star with eight arms, i.e. a combination of cross and plus
2479                       ,ssTriangle  ///< \enumimage{ssTriangle.png} an equilateral triangle, standing on baseline
2480                       ,ssTriangleInverted ///< \enumimage{ssTriangleInverted.png} an equilateral triangle, standing on corner
2481                       ,ssCrossSquare      ///< \enumimage{ssCrossSquare.png} a square with a cross inside
2482                       ,ssPlusSquare       ///< \enumimage{ssPlusSquare.png} a square with a plus inside
2483                       ,ssCrossCircle      ///< \enumimage{ssCrossCircle.png} a circle with a cross inside
2484                       ,ssPlusCircle       ///< \enumimage{ssPlusCircle.png} a circle with a plus inside
2485                       ,ssPeace     ///< \enumimage{ssPeace.png} a circle, with one vertical and two downward diagonal lines
2486                       ,ssPixmap    ///< a custom pixmap specified by \ref setPixmap, centered on the data point coordinates
2487                       ,ssCustom    ///< custom painter operations are performed per scatter (As QPainterPath, see \ref setCustomPath)
2488                     };
2489   Q_ENUMS(ScatterShape)
2490 
2491   QCPScatterStyle();
2492   QCPScatterStyle(ScatterShape shape, double size=6);
2493   QCPScatterStyle(ScatterShape shape, const QColor &color, double size);
2494   QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size);
2495   QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size);
2496   QCPScatterStyle(const QPixmap &pixmap);
2497   QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush=Qt::NoBrush, double size=6);
2498   
2499   // getters:
2500   double size() const { return mSize; }
2501   ScatterShape shape() const { return mShape; }
2502   QPen pen() const { return mPen; }
2503   QBrush brush() const { return mBrush; }
2504   QPixmap pixmap() const { return mPixmap; }
2505   QPainterPath customPath() const { return mCustomPath; }
2506 
2507   // setters:
2508   void setFromOther(const QCPScatterStyle &other, ScatterProperties properties);
2509   void setSize(double size);
2510   void setShape(ScatterShape shape);
2511   void setPen(const QPen &pen);
2512   void setBrush(const QBrush &brush);
2513   void setPixmap(const QPixmap &pixmap);
2514   void setCustomPath(const QPainterPath &customPath);
2515 
2516   // non-property methods:
2517   bool isNone() const { return mShape == ssNone; }
2518   bool isPenDefined() const { return mPenDefined; }
2519   void undefinePen();
2520   void applyTo(QCPPainter *painter, const QPen &defaultPen) const;
2521   void drawShape(QCPPainter *painter, const QPointF &pos) const;
2522   void drawShape(QCPPainter *painter, double x, double y) const;
2523 
2524 protected:
2525   // property members:
2526   double mSize;
2527   ScatterShape mShape;
2528   QPen mPen;
2529   QBrush mBrush;
2530   QPixmap mPixmap;
2531   QPainterPath mCustomPath;
2532   
2533   // non-property members:
2534   bool mPenDefined;
2535 };
2536 Q_DECLARE_TYPEINFO(QCPScatterStyle, Q_MOVABLE_TYPE);
2537 Q_DECLARE_OPERATORS_FOR_FLAGS(QCPScatterStyle::ScatterProperties)
2538 Q_DECLARE_METATYPE(QCPScatterStyle::ScatterProperty)
2539 Q_DECLARE_METATYPE(QCPScatterStyle::ScatterShape)
2540 
2541 /* end of 'src/scatterstyle.h' */
2542 
2543 
2544 /* including file 'src/datacontainer.h'     */
2545 /* modified 2021-03-29T02:30:44, size 34070 */
2546 
2547 /*! \relates QCPDataContainer
2548   Returns whether the sort key of \a a is less than the sort key of \a b.
2549 
2550   \see QCPDataContainer::sort
2551 */
2552 template <class DataType>
2553 inline bool qcpLessThanSortKey(const DataType &a, const DataType &b) { return a.sortKey() < b.sortKey(); }
2554 
2555 template <class DataType>
2556 class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp included below)
2557 {
2558 public:
2559   typedef typename QVector<DataType>::const_iterator const_iterator;
2560   typedef typename QVector<DataType>::iterator iterator;
2561   
2562   QCPDataContainer();
2563   
2564   // getters:
2565   int size() const { return mData.size()-mPreallocSize; }
2566   bool isEmpty() const { return size() == 0; }
2567   bool autoSqueeze() const { return mAutoSqueeze; }
2568   
2569   // setters:
2570   void setAutoSqueeze(bool enabled);
2571   
2572   // non-virtual methods:
2573   void set(const QCPDataContainer<DataType> &data);
2574   void set(const QVector<DataType> &data, bool alreadySorted=false);
2575   void add(const QCPDataContainer<DataType> &data);
2576   void add(const QVector<DataType> &data, bool alreadySorted=false);
2577   void add(const DataType &data);
2578   void removeBefore(double sortKey);
2579   void removeAfter(double sortKey);
2580   void remove(double sortKeyFrom, double sortKeyTo);
2581   void remove(double sortKey);
2582   void clear();
2583   void sort();
2584   void squeeze(bool preAllocation=true, bool postAllocation=true);
2585   
2586   const_iterator constBegin() const { return mData.constBegin()+mPreallocSize; }
2587   const_iterator constEnd() const { return mData.constEnd(); }
2588   iterator begin() { return mData.begin()+mPreallocSize; }
2589   iterator end() { return mData.end(); }
2590   const_iterator findBegin(double sortKey, bool expandedRange=true) const;
2591   const_iterator findEnd(double sortKey, bool expandedRange=true) const;
2592   const_iterator at(int index) const { return constBegin()+qBound(0, index, size()); }
2593   QCPRange keyRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth);
2594   QCPRange valueRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange());
2595   QCPDataRange dataRange() const { return QCPDataRange(0, size()); }
2596   void limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const;
2597   
2598 protected:
2599   // property members:
2600   bool mAutoSqueeze;
2601   
2602   // non-property memebers:
2603   QVector<DataType> mData;
2604   int mPreallocSize;
2605   int mPreallocIteration;
2606   
2607   // non-virtual methods:
2608   void preallocateGrow(int minimumPreallocSize);
2609   void performAutoSqueeze();
2610 };
2611 
2612 
2613 
2614 // include implementation in header since it is a class template:
2615 ////////////////////////////////////////////////////////////////////////////////////////////////////
2616 //////////////////// QCPDataContainer
2617 ////////////////////////////////////////////////////////////////////////////////////////////////////
2618 
2619 /*! \class QCPDataContainer
2620   \brief The generic data container for one-dimensional plottables
2621 
2622   This class template provides a fast container for data storage of one-dimensional data. The data
2623   type is specified as template parameter (called \a DataType in the following) and must provide
2624   some methods as described in the \ref qcpdatacontainer-datatype "next section".
2625 
2626   The data is stored in a sorted fashion, which allows very quick lookups by the sorted key as well
2627   as retrieval of ranges (see \ref findBegin, \ref findEnd, \ref keyRange) using binary search. The
2628   container uses a preallocation and a postallocation scheme, such that appending and prepending
2629   data (with respect to the sort key) is very fast and minimizes reallocations. If data is added
2630   which needs to be inserted between existing keys, the merge usually can be done quickly too,
2631   using the fact that existing data is always sorted. The user can further improve performance by
2632   specifying that added data is already itself sorted by key, if he can guarantee that this is the
2633   case (see for example \ref add(const QVector<DataType> &data, bool alreadySorted)).
2634 
2635   The data can be accessed with the provided const iterators (\ref constBegin, \ref constEnd). If
2636   it is necessary to alter existing data in-place, the non-const iterators can be used (\ref begin,
2637   \ref end). Changing data members that are not the sort key (for most data types called \a key) is
2638   safe from the container's perspective.
2639 
2640   Great care must be taken however if the sort key is modified through the non-const iterators. For
2641   performance reasons, the iterators don't automatically cause a re-sorting upon their
2642   manipulation. It is thus the responsibility of the user to leave the container in a sorted state
2643   when finished with the data manipulation, before calling any other methods on the container. A
2644   complete re-sort (e.g. after finishing all sort key manipulation) can be done by calling \ref
2645   sort. Failing to do so can not be detected by the container efficiently and will cause both
2646   rendering artifacts and potential data loss.
2647 
2648   Implementing one-dimensional plottables that make use of a \ref QCPDataContainer<T> is usually
2649   done by subclassing from \ref QCPAbstractPlottable1D "QCPAbstractPlottable1D<T>", which
2650   introduces an according \a mDataContainer member and some convenience methods.
2651 
2652   \section qcpdatacontainer-datatype Requirements for the DataType template parameter
2653 
2654   The template parameter <tt>DataType</tt> is the type of the stored data points. It must be
2655   trivially copyable and have the following public methods, preferably inline:
2656 
2657   \li <tt>double sortKey() const</tt>\n Returns the member variable of this data point that is the
2658   sort key, defining the ordering in the container. Often this variable is simply called \a key.
2659 
2660   \li <tt>static DataType fromSortKey(double sortKey)</tt>\n Returns a new instance of the data
2661   type initialized with its sort key set to \a sortKey.
2662 
2663   \li <tt>static bool sortKeyIsMainKey()</tt>\n Returns true if the sort key is equal to the main
2664   key (see method \c mainKey below). For most plottables this is the case. It is not the case for
2665   example for \ref QCPCurve, which uses \a t as sort key and \a key as main key. This is the reason
2666   why QCPCurve unlike QCPGraph can display parametric curves with loops.
2667 
2668   \li <tt>double mainKey() const</tt>\n Returns the variable of this data point considered the main
2669   key. This is commonly the variable that is used as the coordinate of this data point on the key
2670   axis of the plottable. This method is used for example when determining the automatic axis
2671   rescaling of key axes (\ref QCPAxis::rescale).
2672 
2673   \li <tt>double mainValue() const</tt>\n Returns the variable of this data point considered the
2674   main value. This is commonly the variable that is used as the coordinate of this data point on
2675   the value axis of the plottable.
2676 
2677   \li <tt>QCPRange valueRange() const</tt>\n Returns the range this data point spans in the value
2678   axis coordinate. If the data is single-valued (e.g. QCPGraphData), this is simply a range with
2679   both lower and upper set to the main data point value. However if the data points can represent
2680   multiple values at once (e.g QCPFinancialData with its \a high, \a low, \a open and \a close
2681   values at each \a key) this method should return the range those values span. This method is used
2682   for example when determining the automatic axis rescaling of value axes (\ref
2683   QCPAxis::rescale).
2684 */
2685 
2686 /* start documentation of inline functions */
2687 
2688 /*! \fn int QCPDataContainer<DataType>::size() const
2689   
2690   Returns the number of data points in the container.
2691 */
2692 
2693 /*! \fn bool QCPDataContainer<DataType>::isEmpty() const
2694   
2695   Returns whether this container holds no data points.
2696 */
2697 
2698 /*! \fn QCPDataContainer::const_iterator QCPDataContainer<DataType>::constBegin() const
2699   
2700   Returns a const iterator to the first data point in this container.
2701 */
2702 
2703 /*! \fn QCPDataContainer::const_iterator QCPDataContainer<DataType>::constEnd() const
2704   
2705   Returns a const iterator to the element past the last data point in this container.
2706 */
2707 
2708 /*! \fn QCPDataContainer::iterator QCPDataContainer<DataType>::begin() const
2709   
2710   Returns a non-const iterator to the first data point in this container.
2711 
2712   You can manipulate the data points in-place through the non-const iterators, but great care must
2713   be taken when manipulating the sort key of a data point, see \ref sort, or the detailed
2714   description of this class.
2715 */
2716 
2717 /*! \fn QCPDataContainer::iterator QCPDataContainer<DataType>::end() const
2718   
2719   Returns a non-const iterator to the element past the last data point in this container.
2720   
2721   You can manipulate the data points in-place through the non-const iterators, but great care must
2722   be taken when manipulating the sort key of a data point, see \ref sort, or the detailed
2723   description of this class.
2724 */
2725 
2726 /*! \fn QCPDataContainer::const_iterator QCPDataContainer<DataType>::at(int index) const
2727 
2728   Returns a const iterator to the element with the specified \a index. If \a index points beyond
2729   the available elements in this container, returns \ref constEnd, i.e. an iterator past the last
2730   valid element.
2731 
2732   You can use this method to easily obtain iterators from a \ref QCPDataRange, see the \ref
2733   dataselection-accessing "data selection page" for an example.
2734 */
2735 
2736 /*! \fn QCPDataRange QCPDataContainer::dataRange() const
2737 
2738   Returns a \ref QCPDataRange encompassing the entire data set of this container. This means the
2739   begin index of the returned range is 0, and the end index is \ref size.
2740 */
2741 
2742 /* end documentation of inline functions */
2743 
2744 /*!
2745   Constructs a QCPDataContainer used for plottable classes that represent a series of key-sorted
2746   data
2747 */
2748 template <class DataType>
2749 QCPDataContainer<DataType>::QCPDataContainer() :
2750   mAutoSqueeze(true),
2751   mPreallocSize(0),
2752   mPreallocIteration(0)
2753 {
2754 }
2755 
2756 /*!
2757   Sets whether the container automatically decides when to release memory from its post- and
2758   preallocation pools when data points are removed. By default this is enabled and for typical
2759   applications shouldn't be changed.
2760   
2761   If auto squeeze is disabled, you can manually decide when to release pre-/postallocation with
2762   \ref squeeze.
2763 */
2764 template <class DataType>
2765 void QCPDataContainer<DataType>::setAutoSqueeze(bool enabled)
2766 {
2767   if (mAutoSqueeze != enabled)
2768   {
2769     mAutoSqueeze = enabled;
2770     if (mAutoSqueeze)
2771       performAutoSqueeze();
2772   }
2773 }
2774 
2775 /*! \overload
2776   
2777   Replaces the current data in this container with the provided \a data.
2778   
2779   \see add, remove
2780 */
2781 template <class DataType>
2782 void QCPDataContainer<DataType>::set(const QCPDataContainer<DataType> &data)
2783 {
2784   clear();
2785   add(data);
2786 }
2787 
2788 /*! \overload
2789   
2790   Replaces the current data in this container with the provided \a data
2791 
2792   If you can guarantee that the data points in \a data have ascending order with respect to the
2793   DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run.
2794   
2795   \see add, remove
2796 */
2797 template <class DataType>
2798 void QCPDataContainer<DataType>::set(const QVector<DataType> &data, bool alreadySorted)
2799 {
2800   mData = data;
2801   mPreallocSize = 0;
2802   mPreallocIteration = 0;
2803   if (!alreadySorted)
2804     sort();
2805 }
2806 
2807 /*! \overload
2808   
2809   Adds the provided \a data to the current data in this container.
2810   
2811   \see set, remove
2812 */
2813 template <class DataType>
2814 void QCPDataContainer<DataType>::add(const QCPDataContainer<DataType> &data)
2815 {
2816   if (data.isEmpty())
2817     return;
2818   
2819   const int n = data.size();
2820   const int oldSize = size();
2821   
2822   if (oldSize > 0 && !qcpLessThanSortKey<DataType>(*constBegin(), *(data.constEnd()-1))) // prepend if new data keys are all smaller than or equal to existing ones
2823   {
2824     if (mPreallocSize < n)
2825       preallocateGrow(n);
2826     mPreallocSize -= n;
2827     std::copy(data.constBegin(), data.constEnd(), begin());
2828   } else // don't need to prepend, so append and merge if necessary
2829   {
2830     mData.resize(mData.size()+n);
2831     std::copy(data.constBegin(), data.constEnd(), end()-n);
2832     if (oldSize > 0 && !qcpLessThanSortKey<DataType>(*(constEnd()-n-1), *(constEnd()-n))) // if appended range keys aren't all greater than existing ones, merge the two partitions
2833       std::inplace_merge(begin(), end()-n, end(), qcpLessThanSortKey<DataType>);
2834   }
2835 }
2836 
2837 /*!
2838   Adds the provided data points in \a data to the current data.
2839   
2840   If you can guarantee that the data points in \a data have ascending order with respect to the
2841   DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run.
2842   
2843   \see set, remove
2844 */
2845 template <class DataType>
2846 void QCPDataContainer<DataType>::add(const QVector<DataType> &data, bool alreadySorted)
2847 {
2848   if (data.isEmpty())
2849     return;
2850   if (isEmpty())
2851   {
2852     set(data, alreadySorted);
2853     return;
2854   }
2855   
2856   const int n = data.size();
2857   const int oldSize = size();
2858   
2859   if (alreadySorted && oldSize > 0 && !qcpLessThanSortKey<DataType>(*constBegin(), *(data.constEnd()-1))) // prepend if new data is sorted and keys are all smaller than or equal to existing ones
2860   {
2861     if (mPreallocSize < n)
2862       preallocateGrow(n);
2863     mPreallocSize -= n;
2864     std::copy(data.constBegin(), data.constEnd(), begin());
2865   } else // don't need to prepend, so append and then sort and merge if necessary
2866   {
2867     mData.resize(mData.size()+n);
2868     std::copy(data.constBegin(), data.constEnd(), end()-n);
2869     if (!alreadySorted) // sort appended subrange if it wasn't already sorted
2870       std::sort(end()-n, end(), qcpLessThanSortKey<DataType>);
2871     if (oldSize > 0 && !qcpLessThanSortKey<DataType>(*(constEnd()-n-1), *(constEnd()-n))) // if appended range keys aren't all greater than existing ones, merge the two partitions
2872       std::inplace_merge(begin(), end()-n, end(), qcpLessThanSortKey<DataType>);
2873   }
2874 }
2875 
2876 /*! \overload
2877   
2878   Adds the provided single data point to the current data.
2879   
2880   \see remove
2881 */
2882 template <class DataType>
2883 void QCPDataContainer<DataType>::add(const DataType &data)
2884 {
2885   if (isEmpty() || !qcpLessThanSortKey<DataType>(data, *(constEnd()-1))) // quickly handle appends if new data key is greater or equal to existing ones
2886   {
2887     mData.append(data);
2888   } else if (qcpLessThanSortKey<DataType>(data, *constBegin()))  // quickly handle prepends using preallocated space
2889   {
2890     if (mPreallocSize < 1)
2891       preallocateGrow(1);
2892     --mPreallocSize;
2893     *begin() = data;
2894   } else // handle inserts, maintaining sorted keys
2895   {
2896     QCPDataContainer<DataType>::iterator insertionPoint = std::lower_bound(begin(), end(), data, qcpLessThanSortKey<DataType>);
2897     mData.insert(insertionPoint, data);
2898   }
2899 }
2900 
2901 /*!
2902   Removes all data points with (sort-)keys smaller than or equal to \a sortKey.
2903   
2904   \see removeAfter, remove, clear
2905 */
2906 template <class DataType>
2907 void QCPDataContainer<DataType>::removeBefore(double sortKey)
2908 {
2909   QCPDataContainer<DataType>::iterator it = begin();
2910   QCPDataContainer<DataType>::iterator itEnd = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
2911   mPreallocSize += int(itEnd-it); // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it)
2912   if (mAutoSqueeze)
2913     performAutoSqueeze();
2914 }
2915 
2916 /*!
2917   Removes all data points with (sort-)keys greater than or equal to \a sortKey.
2918 
2919   \see removeBefore, remove, clear
2920 */
2921 template <class DataType>
2922 void QCPDataContainer<DataType>::removeAfter(double sortKey)
2923 {
2924   QCPDataContainer<DataType>::iterator it = std::upper_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
2925   QCPDataContainer<DataType>::iterator itEnd = end();
2926   mData.erase(it, itEnd); // typically adds it to the postallocated block
2927   if (mAutoSqueeze)
2928     performAutoSqueeze();
2929 }
2930 
2931 /*!
2932   Removes all data points with (sort-)keys between \a sortKeyFrom and \a sortKeyTo. if \a
2933   sortKeyFrom is greater or equal to \a sortKeyTo, the function does nothing. To remove a single
2934   data point with known (sort-)key, use \ref remove(double sortKey).
2935   
2936   \see removeBefore, removeAfter, clear
2937 */
2938 template <class DataType>
2939 void QCPDataContainer<DataType>::remove(double sortKeyFrom, double sortKeyTo)
2940 {
2941   if (sortKeyFrom >= sortKeyTo || isEmpty())
2942     return;
2943   
2944   QCPDataContainer<DataType>::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKeyFrom), qcpLessThanSortKey<DataType>);
2945   QCPDataContainer<DataType>::iterator itEnd = std::upper_bound(it, end(), DataType::fromSortKey(sortKeyTo), qcpLessThanSortKey<DataType>);
2946   mData.erase(it, itEnd);
2947   if (mAutoSqueeze)
2948     performAutoSqueeze();
2949 }
2950 
2951 /*! \overload
2952   
2953   Removes a single data point at \a sortKey. If the position is not known with absolute (binary)
2954   precision, consider using \ref remove(double sortKeyFrom, double sortKeyTo) with a small
2955   fuzziness interval around the suspected position, depeding on the precision with which the
2956   (sort-)key is known.
2957   
2958   \see removeBefore, removeAfter, clear
2959 */
2960 template <class DataType>
2961 void QCPDataContainer<DataType>::remove(double sortKey)
2962 {
2963   QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
2964   if (it != end() && it->sortKey() == sortKey)
2965   {
2966     if (it == begin())
2967       ++mPreallocSize; // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it)
2968     else
2969       mData.erase(it);
2970   }
2971   if (mAutoSqueeze)
2972     performAutoSqueeze();
2973 }
2974 
2975 /*!
2976   Removes all data points.
2977   
2978   \see remove, removeAfter, removeBefore
2979 */
2980 template <class DataType>
2981 void QCPDataContainer<DataType>::clear()
2982 {
2983   mData.clear();
2984   mPreallocIteration = 0;
2985   mPreallocSize = 0;
2986 }
2987 
2988 /*!
2989   Re-sorts all data points in the container by their sort key.
2990 
2991   When setting, adding or removing points using the QCPDataContainer interface (\ref set, \ref add,
2992   \ref remove, etc.), the container makes sure to always stay in a sorted state such that a full
2993   resort is never necessary. However, if you choose to directly manipulate the sort key on data
2994   points by accessing and modifying it through the non-const iterators (\ref begin, \ref end), it
2995   is your responsibility to bring the container back into a sorted state before any other methods
2996   are called on it. This can be achieved by calling this method immediately after finishing the
2997   sort key manipulation.
2998 */
2999 template <class DataType>
3000 void QCPDataContainer<DataType>::sort()
3001 {
3002   std::sort(begin(), end(), qcpLessThanSortKey<DataType>);
3003 }
3004 
3005 /*!
3006   Frees all unused memory that is currently in the preallocation and postallocation pools.
3007   
3008   Note that QCPDataContainer automatically decides whether squeezing is necessary, if \ref
3009   setAutoSqueeze is left enabled. It should thus not be necessary to use this method for typical
3010   applications.
3011   
3012   The parameters \a preAllocation and \a postAllocation control whether pre- and/or post allocation
3013   should be freed, respectively.
3014 */
3015 template <class DataType>
3016 void QCPDataContainer<DataType>::squeeze(bool preAllocation, bool postAllocation)
3017 {
3018   if (preAllocation)
3019   {
3020     if (mPreallocSize > 0)
3021     {
3022       std::copy(begin(), end(), mData.begin());
3023       mData.resize(size());
3024       mPreallocSize = 0;
3025     }
3026     mPreallocIteration = 0;
3027   }
3028   if (postAllocation)
3029     mData.squeeze();
3030 }
3031 
3032 /*!
3033   Returns an iterator to the data point with a (sort-)key that is equal to, just below, or just
3034   above \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be
3035   considered, otherwise the one just above.
3036 
3037   This can be used in conjunction with \ref findEnd to iterate over data points within a given key
3038   range, including or excluding the bounding data points that are just beyond the specified range.
3039 
3040   If \a expandedRange is true but there are no data points below \a sortKey, \ref constBegin is
3041   returned.
3042 
3043   If the container is empty, returns \ref constEnd.
3044 
3045   \see findEnd, QCPPlottableInterface1D::findBegin
3046 */
3047 template <class DataType>
3048 typename QCPDataContainer<DataType>::const_iterator QCPDataContainer<DataType>::findBegin(double sortKey, bool expandedRange) const
3049 {
3050   if (isEmpty())
3051     return constEnd();
3052   
3053   QCPDataContainer<DataType>::const_iterator it = std::lower_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
3054   if (expandedRange && it != constBegin()) // also covers it == constEnd case, and we know --constEnd is valid because mData isn't empty
3055     --it;
3056   return it;
3057 }
3058 
3059 /*!
3060   Returns an iterator to the element after the data point with a (sort-)key that is equal to, just
3061   above or just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey
3062   will be considered, otherwise the one just below.
3063 
3064   This can be used in conjunction with \ref findBegin to iterate over data points within a given
3065   key range, including the bounding data points that are just below and above the specified range.
3066 
3067   If \a expandedRange is true but there are no data points above \a sortKey, \ref constEnd is
3068   returned.
3069 
3070   If the container is empty, \ref constEnd is returned.
3071 
3072   \see findBegin, QCPPlottableInterface1D::findEnd
3073 */
3074 template <class DataType>
3075 typename QCPDataContainer<DataType>::const_iterator QCPDataContainer<DataType>::findEnd(double sortKey, bool expandedRange) const
3076 {
3077   if (isEmpty())
3078     return constEnd();
3079   
3080   QCPDataContainer<DataType>::const_iterator it = std::upper_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
3081   if (expandedRange && it != constEnd())
3082     ++it;
3083   return it;
3084 }
3085 
3086 /*!
3087   Returns the range encompassed by the (main-)key coordinate of all data points. The output
3088   parameter \a foundRange indicates whether a sensible range was found. If this is false, you
3089   should not use the returned QCPRange (e.g. the data container is empty or all points have the
3090   same key).
3091   
3092   Use \a signDomain to control which sign of the key coordinates should be considered. This is
3093   relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a
3094   time.
3095   
3096   If the DataType reports that its main key is equal to the sort key (\a sortKeyIsMainKey), as is
3097   the case for most plottables, this method uses this fact and finds the range very quickly.
3098   
3099   \see valueRange
3100 */
3101 template <class DataType>
3102 QCPRange QCPDataContainer<DataType>::keyRange(bool &foundRange, QCP::SignDomain signDomain)
3103 {
3104   if (isEmpty())
3105   {
3106     foundRange = false;
3107     return QCPRange();
3108   }
3109   QCPRange range;
3110   bool haveLower = false;
3111   bool haveUpper = false;
3112   double current;
3113   
3114   QCPDataContainer<DataType>::const_iterator it = constBegin();
3115   QCPDataContainer<DataType>::const_iterator itEnd = constEnd();
3116   if (signDomain == QCP::sdBoth) // range may be anywhere
3117   {
3118     if (DataType::sortKeyIsMainKey()) // if DataType is sorted by main key (e.g. QCPGraph, but not QCPCurve), use faster algorithm by finding just first and last key with non-NaN value
3119     {
3120       while (it != itEnd) // find first non-nan going up from left
3121       {
3122         if (!qIsNaN(it->mainValue()))
3123         {
3124           range.lower = it->mainKey();
3125           haveLower = true;
3126           break;
3127         }
3128         ++it;
3129       }
3130       it = itEnd;
3131       while (it != constBegin()) // find first non-nan going down from right
3132       {
3133         --it;
3134         if (!qIsNaN(it->mainValue()))
3135         {
3136           range.upper = it->mainKey();
3137           haveUpper = true;
3138           break;
3139         }
3140       }
3141     } else // DataType is not sorted by main key, go through all data points and accordingly expand range
3142     {
3143       while (it != itEnd)
3144       {
3145         if (!qIsNaN(it->mainValue()))
3146         {
3147           current = it->mainKey();
3148           if (current < range.lower || !haveLower)
3149           {
3150             range.lower = current;
3151             haveLower = true;
3152           }
3153           if (current > range.upper || !haveUpper)
3154           {
3155             range.upper = current;
3156             haveUpper = true;
3157           }
3158         }
3159         ++it;
3160       }
3161     }
3162   } else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain
3163   {
3164     while (it != itEnd)
3165     {
3166       if (!qIsNaN(it->mainValue()))
3167       {
3168         current = it->mainKey();
3169         if ((current < range.lower || !haveLower) && current < 0)
3170         {
3171           range.lower = current;
3172           haveLower = true;
3173         }
3174         if ((current > range.upper || !haveUpper) && current < 0)
3175         {
3176           range.upper = current;
3177           haveUpper = true;
3178         }
3179       }
3180       ++it;
3181     }
3182   } else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain
3183   {
3184     while (it != itEnd)
3185     {
3186       if (!qIsNaN(it->mainValue()))
3187       {
3188         current = it->mainKey();
3189         if ((current < range.lower || !haveLower) && current > 0)
3190         {
3191           range.lower = current;
3192           haveLower = true;
3193         }
3194         if ((current > range.upper || !haveUpper) && current > 0)
3195         {
3196           range.upper = current;
3197           haveUpper = true;
3198         }
3199       }
3200       ++it;
3201     }
3202   }
3203   
3204   foundRange = haveLower && haveUpper;
3205   return range;
3206 }
3207 
3208 /*!
3209   Returns the range encompassed by the value coordinates of the data points in the specified key
3210   range (\a inKeyRange), using the full \a DataType::valueRange reported by the data points. The
3211   output parameter \a foundRange indicates whether a sensible range was found. If this is false,
3212   you should not use the returned QCPRange (e.g. the data container is empty or all points have the
3213   same value).
3214 
3215   If \a inKeyRange has both lower and upper bound set to zero (is equal to <tt>QCPRange()</tt>),
3216   all data points are considered, without any restriction on the keys.
3217 
3218   Use \a signDomain to control which sign of the value coordinates should be considered. This is
3219   relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a
3220   time.
3221 
3222   \see keyRange
3223 */
3224 template <class DataType>
3225 QCPRange QCPDataContainer<DataType>::valueRange(bool &foundRange, QCP::SignDomain signDomain, const QCPRange &inKeyRange)
3226 {
3227   if (isEmpty())
3228   {
3229     foundRange = false;
3230     return QCPRange();
3231   }
3232   QCPRange range;
3233   const bool restrictKeyRange = inKeyRange != QCPRange();
3234   bool haveLower = false;
3235   bool haveUpper = false;
3236   QCPRange current;
3237   QCPDataContainer<DataType>::const_iterator itBegin = constBegin();
3238   QCPDataContainer<DataType>::const_iterator itEnd = constEnd();
3239   if (DataType::sortKeyIsMainKey() && restrictKeyRange)
3240   {
3241     itBegin = findBegin(inKeyRange.lower, false);
3242     itEnd = findEnd(inKeyRange.upper, false);
3243   }
3244   if (signDomain == QCP::sdBoth) // range may be anywhere
3245   {
3246     for (QCPDataContainer<DataType>::const_iterator it = itBegin; it != itEnd; ++it)
3247     {
3248       if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper))
3249         continue;
3250       current = it->valueRange();
3251       if ((current.lower < range.lower || !haveLower) && !qIsNaN(current.lower))
3252       {
3253         range.lower = current.lower;
3254         haveLower = true;
3255       }
3256       if ((current.upper > range.upper || !haveUpper) && !qIsNaN(current.upper))
3257       {
3258         range.upper = current.upper;
3259         haveUpper = true;
3260       }
3261     }
3262   } else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain
3263   {
3264     for (QCPDataContainer<DataType>::const_iterator it = itBegin; it != itEnd; ++it)
3265     {
3266       if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper))
3267         continue;
3268       current = it->valueRange();
3269       if ((current.lower < range.lower || !haveLower) && current.lower < 0 && !qIsNaN(current.lower))
3270       {
3271         range.lower = current.lower;
3272         haveLower = true;
3273       }
3274       if ((current.upper > range.upper || !haveUpper) && current.upper < 0 && !qIsNaN(current.upper))
3275       {
3276         range.upper = current.upper;
3277         haveUpper = true;
3278       }
3279     }
3280   } else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain
3281   {
3282     for (QCPDataContainer<DataType>::const_iterator it = itBegin; it != itEnd; ++it)
3283     {
3284       if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper))
3285         continue;
3286       current = it->valueRange();
3287       if ((current.lower < range.lower || !haveLower) && current.lower > 0 && !qIsNaN(current.lower))
3288       {
3289         range.lower = current.lower;
3290         haveLower = true;
3291       }
3292       if ((current.upper > range.upper || !haveUpper) && current.upper > 0 && !qIsNaN(current.upper))
3293       {
3294         range.upper = current.upper;
3295         haveUpper = true;
3296       }
3297     }
3298   }
3299   
3300   foundRange = haveLower && haveUpper;
3301   return range;
3302 }
3303 
3304 /*!
3305   Makes sure \a begin and \a end mark a data range that is both within the bounds of this data
3306   container's data, as well as within the specified \a dataRange. The initial range described by
3307   the passed iterators \a begin and \a end is never expanded, only contracted if necessary.
3308   
3309   This function doesn't require for \a dataRange to be within the bounds of this data container's
3310   valid range.
3311 */
3312 template <class DataType>
3313 void QCPDataContainer<DataType>::limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const
3314 {
3315   QCPDataRange iteratorRange(int(begin-constBegin()), int(end-constBegin()));
3316   iteratorRange = iteratorRange.bounded(dataRange.bounded(this->dataRange()));
3317   begin = constBegin()+iteratorRange.begin();
3318   end = constBegin()+iteratorRange.end();
3319 }
3320 
3321 /*! \internal
3322   
3323   Increases the preallocation pool to have a size of at least \a minimumPreallocSize. Depending on
3324   the preallocation history, the container will grow by more than requested, to speed up future
3325   consecutive size increases.
3326   
3327   if \a minimumPreallocSize is smaller than or equal to the current preallocation pool size, this
3328   method does nothing.
3329 */
3330 template <class DataType>
3331 void QCPDataContainer<DataType>::preallocateGrow(int minimumPreallocSize)
3332 {
3333   if (minimumPreallocSize <= mPreallocSize)
3334     return;
3335   
3336   int newPreallocSize = minimumPreallocSize;
3337   newPreallocSize += (1u<<qBound(4, mPreallocIteration+4, 15)) - 12; // do 4 up to 32768-12 preallocation, doubling in each intermediate iteration
3338   ++mPreallocIteration;
3339   
3340   int sizeDifference = newPreallocSize-mPreallocSize;
3341   mData.resize(mData.size()+sizeDifference);
3342   std::copy_backward(mData.begin()+mPreallocSize, mData.end()-sizeDifference, mData.end());
3343   mPreallocSize = newPreallocSize;
3344 }
3345 
3346 /*! \internal
3347   
3348   This method decides, depending on the total allocation size and the size of the unused pre- and
3349   postallocation pools, whether it is sensible to reduce the pools in order to free up unused
3350   memory. It then possibly calls \ref squeeze to do the deallocation.
3351   
3352   If \ref setAutoSqueeze is enabled, this method is called automatically each time data points are
3353   removed from the container (e.g. \ref remove).
3354   
3355   \note when changing the decision parameters, care must be taken not to cause a back-and-forth
3356   between squeezing and reallocation due to the growth strategy of the internal QVector and \ref
3357   preallocateGrow. The hysteresis between allocation and deallocation should be made high enough
3358   (at the expense of possibly larger unused memory from time to time).
3359 */
3360 template <class DataType>
3361 void QCPDataContainer<DataType>::performAutoSqueeze()
3362 {
3363   const int totalAlloc = mData.capacity();
3364   const int postAllocSize = totalAlloc-mData.size();
3365   const int usedSize = size();
3366   bool shrinkPostAllocation = false;
3367   bool shrinkPreAllocation = false;
3368   if (totalAlloc > 650000) // if allocation is larger, shrink earlier with respect to total used size
3369   {
3370     shrinkPostAllocation = postAllocSize > usedSize*1.5; // QVector grow strategy is 2^n for static data. Watch out not to oscillate!
3371     shrinkPreAllocation = mPreallocSize*10 > usedSize;
3372   } else if (totalAlloc > 1000) // below 10 MiB raw data be generous with preallocated memory, below 1k points don't even bother
3373   {
3374     shrinkPostAllocation = postAllocSize > usedSize*5;
3375     shrinkPreAllocation = mPreallocSize > usedSize*1.5; // preallocation can grow into postallocation, so can be smaller
3376   }
3377   
3378   if (shrinkPreAllocation || shrinkPostAllocation)
3379     squeeze(shrinkPreAllocation, shrinkPostAllocation);
3380 }
3381 
3382 
3383 /* end of 'src/datacontainer.h' */
3384 
3385 
3386 /* including file 'src/plottable.h'        */
3387 /* modified 2021-03-29T02:30:44, size 8461 */
3388 
3389 class QCP_LIB_DECL QCPSelectionDecorator
3390 {
3391   Q_GADGET
3392 public:
3393   QCPSelectionDecorator();
3394   virtual ~QCPSelectionDecorator();
3395   
3396   // getters:
3397   QPen pen() const { return mPen; }
3398   QBrush brush() const { return mBrush; }
3399   QCPScatterStyle scatterStyle() const { return mScatterStyle; }
3400   QCPScatterStyle::ScatterProperties usedScatterProperties() const { return mUsedScatterProperties; }
3401   
3402   // setters:
3403   void setPen(const QPen &pen);
3404   void setBrush(const QBrush &brush);
3405   void setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties=QCPScatterStyle::spPen);
3406   void setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties);
3407   
3408   // non-virtual methods:
3409   void applyPen(QCPPainter *painter) const;
3410   void applyBrush(QCPPainter *painter) const;
3411   QCPScatterStyle getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const;
3412   
3413   // introduced virtual methods:
3414   virtual void copyFrom(const QCPSelectionDecorator *other);
3415   virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection);
3416   
3417 protected:
3418   // property members:
3419   QPen mPen;
3420   QBrush mBrush;
3421   QCPScatterStyle mScatterStyle;
3422   QCPScatterStyle::ScatterProperties mUsedScatterProperties;
3423   // non-property members:
3424   QCPAbstractPlottable *mPlottable;
3425   
3426   // introduced virtual methods:
3427   virtual bool registerWithPlottable(QCPAbstractPlottable *plottable);
3428   
3429 private:
3430   Q_DISABLE_COPY(QCPSelectionDecorator)
3431   friend class QCPAbstractPlottable;
3432 };
3433 Q_DECLARE_METATYPE(QCPSelectionDecorator*)
3434 
3435 
3436 class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable
3437 {
3438   Q_OBJECT
3439   /// \cond INCLUDE_QPROPERTIES
3440   Q_PROPERTY(QString name READ name WRITE setName)
3441   Q_PROPERTY(bool antialiasedFill READ antialiasedFill WRITE setAntialiasedFill)
3442   Q_PROPERTY(bool antialiasedScatters READ antialiasedScatters WRITE setAntialiasedScatters)
3443   Q_PROPERTY(QPen pen READ pen WRITE setPen)
3444   Q_PROPERTY(QBrush brush READ brush WRITE setBrush)
3445   Q_PROPERTY(QCPAxis* keyAxis READ keyAxis WRITE setKeyAxis)
3446   Q_PROPERTY(QCPAxis* valueAxis READ valueAxis WRITE setValueAxis)
3447   Q_PROPERTY(QCP::SelectionType selectable READ selectable WRITE setSelectable NOTIFY selectableChanged)
3448   Q_PROPERTY(QCPDataSelection selection READ selection WRITE setSelection NOTIFY selectionChanged)
3449   Q_PROPERTY(QCPSelectionDecorator* selectionDecorator READ selectionDecorator WRITE setSelectionDecorator)
3450   /// \endcond
3451 public:
3452   QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis);
3453   virtual ~QCPAbstractPlottable() Q_DECL_OVERRIDE;
3454   
3455   // getters:
3456   QString name() const { return mName; }
3457   bool antialiasedFill() const { return mAntialiasedFill; }
3458   bool antialiasedScatters() const { return mAntialiasedScatters; }
3459   QPen pen() const { return mPen; }
3460   QBrush brush() const { return mBrush; }
3461   QCPAxis *keyAxis() const { return mKeyAxis.data(); }
3462   QCPAxis *valueAxis() const { return mValueAxis.data(); }
3463   QCP::SelectionType selectable() const { return mSelectable; }
3464   bool selected() const { return !mSelection.isEmpty(); }
3465   QCPDataSelection selection() const { return mSelection; }
3466   QCPSelectionDecorator *selectionDecorator() const { return mSelectionDecorator; }
3467   
3468   // setters:
3469   void setName(const QString &name);
3470   void setAntialiasedFill(bool enabled);
3471   void setAntialiasedScatters(bool enabled);
3472   void setPen(const QPen &pen);
3473   void setBrush(const QBrush &brush);
3474   void setKeyAxis(QCPAxis *axis);
3475   void setValueAxis(QCPAxis *axis);
3476   Q_SLOT void setSelectable(QCP::SelectionType selectable);
3477   Q_SLOT void setSelection(QCPDataSelection selection);
3478   void setSelectionDecorator(QCPSelectionDecorator *decorator);
3479 
3480   // introduced virtual methods:
3481   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE = 0; // actually introduced in QCPLayerable as non-pure, but we want to force reimplementation for plottables
3482   virtual QCPPlottableInterface1D *interface1D() { return nullptr; }
3483   virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const = 0;
3484   virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const = 0;
3485   
3486   // non-property methods:
3487   void coordsToPixels(double key, double value, double &x, double &y) const;
3488   const QPointF coordsToPixels(double key, double value) const;
3489   void pixelsToCoords(double x, double y, double &key, double &value) const;
3490   void pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const;
3491   void rescaleAxes(bool onlyEnlarge=false) const;
3492   void rescaleKeyAxis(bool onlyEnlarge=false) const;
3493   void rescaleValueAxis(bool onlyEnlarge=false, bool inKeyRange=false) const;
3494   bool addToLegend(QCPLegend *legend);
3495   bool addToLegend();
3496   bool removeFromLegend(QCPLegend *legend) const;
3497   bool removeFromLegend() const;
3498   
3499 signals:
3500   void selectionChanged(bool selected);
3501   void selectionChanged(const QCPDataSelection &selection);
3502   void selectableChanged(QCP::SelectionType selectable);
3503   
3504 protected:
3505   // property members:
3506   QString mName;
3507   bool mAntialiasedFill, mAntialiasedScatters;
3508   QPen mPen;
3509   QBrush mBrush;
3510   QPointer<QCPAxis> mKeyAxis, mValueAxis;
3511   QCP::SelectionType mSelectable;
3512   QCPDataSelection mSelection;
3513   QCPSelectionDecorator *mSelectionDecorator;
3514   
3515   // reimplemented virtual methods:
3516   virtual QRect clipRect() const Q_DECL_OVERRIDE;
3517   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0;
3518   virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE;
3519   void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
3520   // events:
3521   virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
3522   virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE;
3523   
3524   // introduced virtual methods:
3525   virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const = 0;
3526   
3527   // non-virtual methods:
3528   void applyFillAntialiasingHint(QCPPainter *painter) const;
3529   void applyScattersAntialiasingHint(QCPPainter *painter) const;
3530 
3531 private:
3532   Q_DISABLE_COPY(QCPAbstractPlottable)
3533   
3534   friend class QCustomPlot;
3535   friend class QCPAxis;
3536   friend class QCPPlottableLegendItem;
3537 };
3538 
3539 
3540 /* end of 'src/plottable.h' */
3541 
3542 
3543 /* including file 'src/item.h'             */
3544 /* modified 2021-03-29T02:30:44, size 9425 */
3545 
3546 class QCP_LIB_DECL QCPItemAnchor
3547 {
3548   Q_GADGET
3549 public:
3550   QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId=-1);
3551   virtual ~QCPItemAnchor();
3552   
3553   // getters:
3554   QString name() const { return mName; }
3555   virtual QPointF pixelPosition() const;
3556   
3557 protected:
3558   // property members:
3559   QString mName;
3560   
3561   // non-property members:
3562   QCustomPlot *mParentPlot;
3563   QCPAbstractItem *mParentItem;
3564   int mAnchorId;
3565   QSet<QCPItemPosition*> mChildrenX, mChildrenY;
3566   
3567   // introduced virtual methods:
3568   virtual QCPItemPosition *toQCPItemPosition() { return nullptr; }
3569   
3570   // non-virtual methods:
3571   void addChildX(QCPItemPosition* pos); // called from pos when this anchor is set as parent
3572   void removeChildX(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted
3573   void addChildY(QCPItemPosition* pos); // called from pos when this anchor is set as parent
3574   void removeChildY(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted
3575   
3576 private:
3577   Q_DISABLE_COPY(QCPItemAnchor)
3578   
3579   friend class QCPItemPosition;
3580 };
3581 
3582 
3583 
3584 class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor
3585 {
3586   Q_GADGET
3587 public:
3588   /*!
3589     Defines the ways an item position can be specified. Thus it defines what the numbers passed to
3590     \ref setCoords actually mean.
3591     
3592     \see setType
3593   */
3594   enum PositionType { ptAbsolute        ///< Static positioning in pixels, starting from the top left corner of the viewport/widget.
3595                       ,ptViewportRatio  ///< Static positioning given by a fraction of the viewport size. For example, if you call setCoords(0, 0), the position will be at the top
3596                                         ///< left corner of the viewport/widget. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and
3597                                         ///< vertically at the top of the viewport/widget, etc.
3598                       ,ptAxisRectRatio  ///< Static positioning given by a fraction of the axis rect size (see \ref setAxisRect). For example, if you call setCoords(0, 0), the position will be at the top
3599                                         ///< left corner of the axis rect. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and
3600                                         ///< vertically at the top of the axis rect, etc. You can also go beyond the axis rect by providing negative coordinates or coordinates larger than 1.
3601                       ,ptPlotCoords     ///< Dynamic positioning at a plot coordinate defined by two axes (see \ref setAxes).
3602                     };
3603   Q_ENUMS(PositionType)
3604   
3605   QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name);
3606   virtual ~QCPItemPosition() Q_DECL_OVERRIDE;
3607   
3608   // getters:
3609   PositionType type() const { return typeX(); }
3610   PositionType typeX() const { return mPositionTypeX; }
3611   PositionType typeY() const { return mPositionTypeY; }
3612   QCPItemAnchor *parentAnchor() const { return parentAnchorX(); }
3613   QCPItemAnchor *parentAnchorX() const { return mParentAnchorX; }
3614   QCPItemAnchor *parentAnchorY() const { return mParentAnchorY; }
3615   double key() const { return mKey; }
3616   double value() const { return mValue; }
3617   QPointF coords() const { return QPointF(mKey, mValue); }
3618   QCPAxis *keyAxis() const { return mKeyAxis.data(); }
3619   QCPAxis *valueAxis() const { return mValueAxis.data(); }
3620   QCPAxisRect *axisRect() const;
3621   virtual QPointF pixelPosition() const Q_DECL_OVERRIDE;
3622   
3623   // setters:
3624   void setType(PositionType type);
3625   void setTypeX(PositionType type);
3626   void setTypeY(PositionType type);
3627   bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false);
3628   bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false);
3629   bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false);
3630   void setCoords(double key, double value);
3631   void setCoords(const QPointF &pos);
3632   void setAxes(QCPAxis* keyAxis, QCPAxis* valueAxis);
3633   void setAxisRect(QCPAxisRect *axisRect);
3634   void setPixelPosition(const QPointF &pixelPosition);
3635   
3636 protected:
3637   // property members:
3638   PositionType mPositionTypeX, mPositionTypeY;
3639   QPointer<QCPAxis> mKeyAxis, mValueAxis;
3640   QPointer<QCPAxisRect> mAxisRect;
3641   double mKey, mValue;
3642   QCPItemAnchor *mParentAnchorX, *mParentAnchorY;
3643   
3644   // reimplemented virtual methods:
3645   virtual QCPItemPosition *toQCPItemPosition() Q_DECL_OVERRIDE { return this; }
3646   
3647 private:
3648   Q_DISABLE_COPY(QCPItemPosition)
3649   
3650 };
3651 Q_DECLARE_METATYPE(QCPItemPosition::PositionType)
3652 
3653 
3654 class QCP_LIB_DECL QCPAbstractItem : public QCPLayerable
3655 {
3656   Q_OBJECT
3657   /// \cond INCLUDE_QPROPERTIES
3658   Q_PROPERTY(bool clipToAxisRect READ clipToAxisRect WRITE setClipToAxisRect)
3659   Q_PROPERTY(QCPAxisRect* clipAxisRect READ clipAxisRect WRITE setClipAxisRect)
3660   Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged)
3661   Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged)
3662   /// \endcond
3663 public:
3664   explicit QCPAbstractItem(QCustomPlot *parentPlot);
3665   virtual ~QCPAbstractItem() Q_DECL_OVERRIDE;
3666   
3667   // getters:
3668   bool clipToAxisRect() const { return mClipToAxisRect; }
3669   QCPAxisRect *clipAxisRect() const;
3670   bool selectable() const { return mSelectable; }
3671   bool selected() const { return mSelected; }
3672   
3673   // setters:
3674   void setClipToAxisRect(bool clip);
3675   void setClipAxisRect(QCPAxisRect *rect);
3676   Q_SLOT void setSelectable(bool selectable);
3677   Q_SLOT void setSelected(bool selected);
3678   
3679   // reimplemented virtual methods:
3680   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE = 0;
3681   
3682   // non-virtual methods:
3683   QList<QCPItemPosition*> positions() const { return mPositions; }
3684   QList<QCPItemAnchor*> anchors() const { return mAnchors; }
3685   QCPItemPosition *position(const QString &name) const;
3686   QCPItemAnchor *anchor(const QString &name) const;
3687   bool hasAnchor(const QString &name) const;
3688   
3689 signals:
3690   void selectionChanged(bool selected);
3691   void selectableChanged(bool selectable);
3692   
3693 protected:
3694   // property members:
3695   bool mClipToAxisRect;
3696   QPointer<QCPAxisRect> mClipAxisRect;
3697   QList<QCPItemPosition*> mPositions;
3698   QList<QCPItemAnchor*> mAnchors;
3699   bool mSelectable, mSelected;
3700   
3701   // reimplemented virtual methods:
3702   virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE;
3703   virtual QRect clipRect() const Q_DECL_OVERRIDE;
3704   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
3705   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0;
3706   // events:
3707   virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
3708   virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE;
3709   
3710   // introduced virtual methods:
3711   virtual QPointF anchorPixelPosition(int anchorId) const;
3712   
3713   // non-virtual methods:
3714   double rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const;
3715   QCPItemPosition *createPosition(const QString &name);
3716   QCPItemAnchor *createAnchor(const QString &name, int anchorId);
3717   
3718 private:
3719   Q_DISABLE_COPY(QCPAbstractItem)
3720   
3721   friend class QCustomPlot;
3722   friend class QCPItemAnchor;
3723 };
3724 
3725 /* end of 'src/item.h' */
3726 
3727 
3728 /* including file 'src/core.h'              */
3729 /* modified 2021-03-29T02:30:44, size 19304 */
3730 
3731 class QCP_LIB_DECL QCustomPlot : public QWidget
3732 {
3733   Q_OBJECT
3734   /// \cond INCLUDE_QPROPERTIES
3735   Q_PROPERTY(QRect viewport READ viewport WRITE setViewport)
3736   Q_PROPERTY(QPixmap background READ background WRITE setBackground)
3737   Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled)
3738   Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode)
3739   Q_PROPERTY(QCPLayoutGrid* plotLayout READ plotLayout)
3740   Q_PROPERTY(bool autoAddPlottableToLegend READ autoAddPlottableToLegend WRITE setAutoAddPlottableToLegend)
3741   Q_PROPERTY(int selectionTolerance READ selectionTolerance WRITE setSelectionTolerance)
3742   Q_PROPERTY(bool noAntialiasingOnDrag READ noAntialiasingOnDrag WRITE setNoAntialiasingOnDrag)
3743   Q_PROPERTY(Qt::KeyboardModifier multiSelectModifier READ multiSelectModifier WRITE setMultiSelectModifier)
3744   Q_PROPERTY(bool openGl READ openGl WRITE setOpenGl)
3745   /// \endcond
3746 public:
3747   /*!
3748     Defines how a layer should be inserted relative to an other layer.
3749 
3750     \see addLayer, moveLayer
3751   */
3752   enum LayerInsertMode { limBelow  ///< Layer is inserted below other layer
3753                          ,limAbove ///< Layer is inserted above other layer
3754                        };
3755   Q_ENUMS(LayerInsertMode)
3756   
3757   /*!
3758     Defines with what timing the QCustomPlot surface is refreshed after a replot.
3759 
3760     \see replot
3761   */
3762   enum RefreshPriority { rpImmediateRefresh ///< Replots immediately and repaints the widget immediately by calling QWidget::repaint() after the replot
3763                          ,rpQueuedRefresh   ///< Replots immediately, but queues the widget repaint, by calling QWidget::update() after the replot. This way multiple redundant widget repaints can be avoided.
3764                          ,rpRefreshHint     ///< Whether to use immediate or queued refresh depends on whether the plotting hint \ref QCP::phImmediateRefresh is set, see \ref setPlottingHints.
3765                          ,rpQueuedReplot    ///< Queues the entire replot for the next event loop iteration. This way multiple redundant replots can be avoided. The actual replot is then done with \ref rpRefreshHint priority.
3766                        };
3767   Q_ENUMS(RefreshPriority)
3768   
3769   explicit QCustomPlot(QWidget *parent = nullptr);
3770   virtual ~QCustomPlot() Q_DECL_OVERRIDE;
3771   
3772   // getters:
3773   QRect viewport() const { return mViewport; }
3774   double bufferDevicePixelRatio() const { return mBufferDevicePixelRatio; }
3775   QPixmap background() const { return mBackgroundPixmap; }
3776   bool backgroundScaled() const { return mBackgroundScaled; }
3777   Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; }
3778   QCPLayoutGrid *plotLayout() const { return mPlotLayout; }
3779   QCP::AntialiasedElements antialiasedElements() const { return mAntialiasedElements; }
3780   QCP::AntialiasedElements notAntialiasedElements() const { return mNotAntialiasedElements; }
3781   bool autoAddPlottableToLegend() const { return mAutoAddPlottableToLegend; }
3782   const QCP::Interactions interactions() const { return mInteractions; }
3783   int selectionTolerance() const { return mSelectionTolerance; }
3784   bool noAntialiasingOnDrag() const { return mNoAntialiasingOnDrag; }
3785   QCP::PlottingHints plottingHints() const { return mPlottingHints; }
3786   Qt::KeyboardModifier multiSelectModifier() const { return mMultiSelectModifier; }
3787   QCP::SelectionRectMode selectionRectMode() const { return mSelectionRectMode; }
3788   QCPSelectionRect *selectionRect() const { return mSelectionRect; }
3789   bool openGl() const { return mOpenGl; }
3790   
3791   // setters:
3792   void setViewport(const QRect &rect);
3793   void setBufferDevicePixelRatio(double ratio);
3794   void setBackground(const QPixmap &pm);
3795   void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding);
3796   void setBackground(const QBrush &brush);
3797   void setBackgroundScaled(bool scaled);
3798   void setBackgroundScaledMode(Qt::AspectRatioMode mode);
3799   void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements);
3800   void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true);
3801   void setNotAntialiasedElements(const QCP::AntialiasedElements &notAntialiasedElements);
3802   void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true);
3803   void setAutoAddPlottableToLegend(bool on);
3804   void setInteractions(const QCP::Interactions &interactions);
3805   void setInteraction(const QCP::Interaction &interaction, bool enabled=true);
3806   void setSelectionTolerance(int pixels);
3807   void setNoAntialiasingOnDrag(bool enabled);
3808   void setPlottingHints(const QCP::PlottingHints &hints);
3809   void setPlottingHint(QCP::PlottingHint hint, bool enabled=true);
3810   void setMultiSelectModifier(Qt::KeyboardModifier modifier);
3811   void setSelectionRectMode(QCP::SelectionRectMode mode);
3812   void setSelectionRect(QCPSelectionRect *selectionRect);
3813   void setOpenGl(bool enabled, int multisampling=16);
3814   
3815   // non-property methods:
3816   // plottable interface:
3817   QCPAbstractPlottable *plottable(int index);
3818   QCPAbstractPlottable *plottable();
3819   bool removePlottable(QCPAbstractPlottable *plottable);
3820   bool removePlottable(int index);
3821   int clearPlottables();
3822   int plottableCount() const;
3823   QList<QCPAbstractPlottable*> selectedPlottables() const;
3824   template<class PlottableType>
3825   PlottableType *plottableAt(const QPointF &pos, bool onlySelectable=false, int *dataIndex=nullptr) const;
3826   QCPAbstractPlottable *plottableAt(const QPointF &pos, bool onlySelectable=false, int *dataIndex=nullptr) const;
3827   bool hasPlottable(QCPAbstractPlottable *plottable) const;
3828  
3829   // specialized interface for QCPGraph:
3830   QCPGraph *graph(int index) const;
3831   QCPGraph *graph() const;
3832   QCPGraph *addGraph(QCPAxis *keyAxis=nullptr, QCPAxis *valueAxis=nullptr);
3833   bool removeGraph(QCPGraph *graph);
3834   bool removeGraph(int index);
3835   int clearGraphs();
3836   int graphCount() const;
3837   QList<QCPGraph*> selectedGraphs() const;
3838 
3839   // item interface:
3840   QCPAbstractItem *item(int index) const;
3841   QCPAbstractItem *item() const;
3842   bool removeItem(QCPAbstractItem *item);
3843   bool removeItem(int index);
3844   int clearItems();
3845   int itemCount() const;
3846   QList<QCPAbstractItem*> selectedItems() const;
3847   template<class ItemType>
3848   ItemType *itemAt(const QPointF &pos, bool onlySelectable=false) const;
3849   QCPAbstractItem *itemAt(const QPointF &pos, bool onlySelectable=false) const;
3850   bool hasItem(QCPAbstractItem *item) const;
3851   
3852   // layer interface:
3853   QCPLayer *layer(const QString &name) const;
3854   QCPLayer *layer(int index) const;
3855   QCPLayer *currentLayer() const;
3856   bool setCurrentLayer(const QString &name);
3857   bool setCurrentLayer(QCPLayer *layer);
3858   int layerCount() const;
3859   bool addLayer(const QString &name, QCPLayer *otherLayer=nullptr, LayerInsertMode insertMode=limAbove);
3860   bool removeLayer(QCPLayer *layer);
3861   bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove);
3862   
3863   // axis rect/layout interface:
3864   int axisRectCount() const;
3865   QCPAxisRect* axisRect(int index=0) const;
3866   QList<QCPAxisRect*> axisRects() const;
3867   QCPLayoutElement* layoutElementAt(const QPointF &pos) const;
3868   QCPAxisRect* axisRectAt(const QPointF &pos) const;
3869   Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false);
3870   
3871   QList<QCPAxis*> selectedAxes() const;
3872   QList<QCPLegend*> selectedLegends() const;
3873   Q_SLOT void deselectAll();
3874   
3875   bool savePdf(const QString &fileName, int width=0, int height=0, QCP::ExportPen exportPen=QCP::epAllowCosmetic, const QString &pdfCreator=QString(), const QString &pdfTitle=QString());
3876   bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch);
3877   bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch);
3878   bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch);
3879   bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch);
3880   QPixmap toPixmap(int width=0, int height=0, double scale=1.0);
3881   void toPainter(QCPPainter *painter, int width=0, int height=0);
3882   Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpRefreshHint);
3883   double replotTime(bool average=false) const;
3884   
3885   QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2;
3886   QCPLegend *legend;
3887   
3888 signals:
3889   void mouseDoubleClick(QMouseEvent *event);
3890   void mousePress(QMouseEvent *event);
3891   void mouseMove(QMouseEvent *event);
3892   void mouseRelease(QMouseEvent *event);
3893   void mouseWheel(QWheelEvent *event);
3894   
3895   void plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event);
3896   void plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event);
3897   void itemClick(QCPAbstractItem *item, QMouseEvent *event);
3898   void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event);
3899   void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event);
3900   void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event);
3901   void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event);
3902   void legendDoubleClick(QCPLegend *legend,  QCPAbstractLegendItem *item, QMouseEvent *event);
3903   
3904   void selectionChangedByUser();
3905   void beforeReplot();
3906   void afterLayout();
3907   void afterReplot();
3908   
3909 protected:
3910   // property members:
3911   QRect mViewport;
3912   double mBufferDevicePixelRatio;
3913   QCPLayoutGrid *mPlotLayout;
3914   bool mAutoAddPlottableToLegend;
3915   QList<QCPAbstractPlottable*> mPlottables;
3916   QList<QCPGraph*> mGraphs; // extra list of plottables also in mPlottables that are of type QCPGraph
3917   QList<QCPAbstractItem*> mItems;
3918   QList<QCPLayer*> mLayers;
3919   QCP::AntialiasedElements mAntialiasedElements, mNotAntialiasedElements;
3920   QCP::Interactions mInteractions;
3921   int mSelectionTolerance;
3922   bool mNoAntialiasingOnDrag;
3923   QBrush mBackgroundBrush;
3924   QPixmap mBackgroundPixmap;
3925   QPixmap mScaledBackgroundPixmap;
3926   bool mBackgroundScaled;
3927   Qt::AspectRatioMode mBackgroundScaledMode;
3928   QCPLayer *mCurrentLayer;
3929   QCP::PlottingHints mPlottingHints;
3930   Qt::KeyboardModifier mMultiSelectModifier;
3931   QCP::SelectionRectMode mSelectionRectMode;
3932   QCPSelectionRect *mSelectionRect;
3933   bool mOpenGl;
3934   
3935   // non-property members:
3936   QList<QSharedPointer<QCPAbstractPaintBuffer> > mPaintBuffers;
3937   QPoint mMousePressPos;
3938   bool mMouseHasMoved;
3939   QPointer<QCPLayerable> mMouseEventLayerable;
3940   QPointer<QCPLayerable> mMouseSignalLayerable;
3941   QVariant mMouseEventLayerableDetails;
3942   QVariant mMouseSignalLayerableDetails;
3943   bool mReplotting;
3944   bool mReplotQueued;
3945   double mReplotTime, mReplotTimeAverage;
3946   int mOpenGlMultisamples;
3947   QCP::AntialiasedElements mOpenGlAntialiasedElementsBackup;
3948   bool mOpenGlCacheLabelsBackup;
3949 #ifdef QCP_OPENGL_FBO
3950   QSharedPointer<QOpenGLContext> mGlContext;
3951   QSharedPointer<QSurface> mGlSurface;
3952   QSharedPointer<QOpenGLPaintDevice> mGlPaintDevice;
3953 #endif
3954   
3955   // reimplemented virtual methods:
3956   virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE;
3957   virtual QSize sizeHint() const Q_DECL_OVERRIDE;
3958   virtual void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
3959   virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
3960   virtual bool event( QEvent *event ) override;
3961   virtual void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
3962   virtual void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
3963   virtual void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
3964   virtual void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
3965   virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
3966   
3967   // introduced virtual methods:
3968   virtual void draw(QCPPainter *painter);
3969   virtual void updateLayout();
3970   virtual void axisRemoved(QCPAxis *axis);
3971   virtual void legendRemoved(QCPLegend *legend);
3972   Q_SLOT virtual void processRectSelection(QRect rect, QMouseEvent *event);
3973   Q_SLOT virtual void processRectZoom(QRect rect, QMouseEvent *event);
3974   Q_SLOT virtual void processPointSelection(QMouseEvent *event);
3975   
3976   // non-virtual methods:
3977   bool registerPlottable(QCPAbstractPlottable *plottable);
3978   bool registerGraph(QCPGraph *graph);
3979   bool registerItem(QCPAbstractItem* item);
3980   void updateLayerIndices() const;
3981   QCPLayerable *layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=nullptr) const;
3982   QList<QCPLayerable*> layerableListAt(const QPointF &pos, bool onlySelectable, QList<QVariant> *selectionDetails=nullptr) const;
3983   void drawBackground(QCPPainter *painter);
3984   void setupPaintBuffers();
3985   QCPAbstractPaintBuffer *createPaintBuffer();
3986   bool hasInvalidatedPaintBuffers();
3987   bool setupOpenGl();
3988   void freeOpenGl();
3989   
3990   friend class QCPLegend;
3991   friend class QCPAxis;
3992   friend class QCPLayer;
3993   friend class QCPAxisRect;
3994   friend class QCPAbstractPlottable;
3995   friend class QCPGraph;
3996   friend class QCPAbstractItem;
3997 };
3998 Q_DECLARE_METATYPE(QCustomPlot::LayerInsertMode)
3999 Q_DECLARE_METATYPE(QCustomPlot::RefreshPriority)
4000 
4001 
4002 // implementation of template functions:
4003 
4004 /*!
4005   Returns the plottable at the pixel position \a pos. The plottable type (a QCPAbstractPlottable
4006   subclass) that shall be taken into consideration can be specified via the template parameter.
4007 
4008   Plottables that only consist of single lines (like graphs) have a tolerance band around them, see
4009   \ref setSelectionTolerance. If multiple plottables come into consideration, the one closest to \a
4010   pos is returned.
4011   
4012   If \a onlySelectable is true, only plottables that are selectable
4013   (QCPAbstractPlottable::setSelectable) are considered.
4014   
4015   if \a dataIndex is non-null, it is set to the index of the plottable's data point that is closest
4016   to \a pos.
4017 
4018   If there is no plottable of the specified type at \a pos, returns \c nullptr.
4019   
4020   \see itemAt, layoutElementAt
4021 */
4022 template<class PlottableType>
4023 PlottableType *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable, int *dataIndex) const
4024 {
4025   PlottableType *resultPlottable = 0;
4026   QVariant resultDetails;
4027   double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value
4028   
4029   foreach (QCPAbstractPlottable *plottable, mPlottables)
4030   {
4031     PlottableType *currentPlottable = qobject_cast<PlottableType*>(plottable);
4032     if (!currentPlottable || (onlySelectable && !currentPlottable->selectable())) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPAbstractPlottable::selectable
4033       continue;
4034     if (currentPlottable->clipRect().contains(pos.toPoint())) // only consider clicks where the plottable is actually visible
4035     {
4036       QVariant details;
4037       double currentDistance = currentPlottable->selectTest(pos, false, dataIndex ? &details : nullptr);
4038       if (currentDistance >= 0 && currentDistance < resultDistance)
4039       {
4040         resultPlottable = currentPlottable;
4041         resultDetails = details;
4042         resultDistance = currentDistance;
4043       }
4044     }
4045   }
4046   
4047   if (resultPlottable && dataIndex)
4048   {
4049     QCPDataSelection sel = resultDetails.value<QCPDataSelection>();
4050     if (!sel.isEmpty())
4051       *dataIndex = sel.dataRange(0).begin();
4052   }
4053   return resultPlottable;
4054 }
4055 
4056 /*!
4057   Returns the item at the pixel position \a pos. The item type (a QCPAbstractItem subclass) that shall be
4058   taken into consideration can be specified via the template parameter. Items that only consist of single
4059   lines (e.g. \ref QCPItemLine or \ref QCPItemCurve) have a tolerance band around them, see \ref
4060   setSelectionTolerance. If multiple items come into consideration, the one closest to \a pos is returned.
4061   
4062   If \a onlySelectable is true, only items that are selectable (QCPAbstractItem::setSelectable) are
4063   considered.
4064   
4065   If there is no item at \a pos, returns \c nullptr.
4066   
4067   \see plottableAt, layoutElementAt
4068 */
4069 template<class ItemType>
4070 ItemType *QCustomPlot::itemAt(const QPointF &pos, bool onlySelectable) const
4071 {
4072   ItemType *resultItem = 0;
4073   double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value
4074   
4075   foreach (QCPAbstractItem *item, mItems)
4076   {
4077     ItemType *currentItem = qobject_cast<ItemType*>(item);
4078     if (!currentItem || (onlySelectable && !currentItem->selectable())) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPAbstractItem::selectable
4079       continue;
4080     if (!currentItem->clipToAxisRect() || currentItem->clipRect().contains(pos.toPoint())) // only consider clicks inside axis cliprect of the item if actually clipped to it
4081     {
4082       double currentDistance = currentItem->selectTest(pos, false);
4083       if (currentDistance >= 0 && currentDistance < resultDistance)
4084       {
4085         resultItem = currentItem;
4086         resultDistance = currentDistance;
4087       }
4088     }
4089   }
4090   
4091   return resultItem;
4092 }
4093 
4094 
4095 
4096 /* end of 'src/core.h' */
4097 
4098 
4099 /* including file 'src/plottable1d.h'       */
4100 /* modified 2021-03-29T02:30:44, size 25638 */
4101 
4102 class QCPPlottableInterface1D
4103 {
4104 public:
4105   virtual ~QCPPlottableInterface1D() = default;
4106   // introduced pure virtual methods:
4107   virtual int dataCount() const = 0;
4108   virtual double dataMainKey(int index) const = 0;
4109   virtual double dataSortKey(int index) const = 0;
4110   virtual double dataMainValue(int index) const = 0;
4111   virtual QCPRange dataValueRange(int index) const = 0;
4112   virtual QPointF dataPixelPosition(int index) const = 0;
4113   virtual bool sortKeyIsMainKey() const = 0;
4114   virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const = 0;
4115   virtual int findBegin(double sortKey, bool expandedRange=true) const = 0;
4116   virtual int findEnd(double sortKey, bool expandedRange=true) const = 0;
4117 };
4118 
4119 template <class DataType>
4120 class QCPAbstractPlottable1D : public QCPAbstractPlottable, public QCPPlottableInterface1D // no QCP_LIB_DECL, template class ends up in header (cpp included below)
4121 {
4122   // No Q_OBJECT macro due to template class
4123   
4124 public:
4125   QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis);
4126   virtual ~QCPAbstractPlottable1D() Q_DECL_OVERRIDE;
4127   
4128   // virtual methods of 1d plottable interface:
4129   virtual int dataCount() const Q_DECL_OVERRIDE;
4130   virtual double dataMainKey(int index) const Q_DECL_OVERRIDE;
4131   virtual double dataSortKey(int index) const Q_DECL_OVERRIDE;
4132   virtual double dataMainValue(int index) const Q_DECL_OVERRIDE;
4133   virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE;
4134   virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE;
4135   virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE;
4136   virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE;
4137   virtual int findBegin(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE;
4138   virtual int findEnd(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE;
4139   
4140   // reimplemented virtual methods:
4141   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
4142   virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; }
4143   
4144 protected:
4145   // property members:
4146   QSharedPointer<QCPDataContainer<DataType> > mDataContainer;
4147   
4148   // helpers for subclasses:
4149   void getDataSegments(QList<QCPDataRange> &selectedSegments, QList<QCPDataRange> &unselectedSegments) const;
4150   void drawPolyline(QCPPainter *painter, const QVector<QPointF> &lineData) const;
4151 
4152 private:
4153   Q_DISABLE_COPY(QCPAbstractPlottable1D)
4154   
4155 };
4156 
4157 
4158 
4159 // include implementation in header since it is a class template:
4160 ////////////////////////////////////////////////////////////////////////////////////////////////////
4161 //////////////////// QCPPlottableInterface1D
4162 ////////////////////////////////////////////////////////////////////////////////////////////////////
4163 
4164 /*! \class QCPPlottableInterface1D
4165   \brief Defines an abstract interface for one-dimensional plottables
4166 
4167   This class contains only pure virtual methods which define a common interface to the data
4168   of one-dimensional plottables.
4169 
4170   For example, it is implemented by the template class \ref QCPAbstractPlottable1D (the preferred
4171   base class for one-dimensional plottables). So if you use that template class as base class of
4172   your one-dimensional plottable, you won't have to care about implementing the 1d interface
4173   yourself.
4174 
4175   If your plottable doesn't derive from \ref QCPAbstractPlottable1D but still wants to provide a 1d
4176   interface (e.g. like \ref QCPErrorBars does), you should inherit from both \ref
4177   QCPAbstractPlottable and \ref QCPPlottableInterface1D and accordingly reimplement the pure
4178   virtual methods of the 1d interface, matching your data container. Also, reimplement \ref
4179   QCPAbstractPlottable::interface1D to return the \c this pointer.
4180 
4181   If you have a \ref QCPAbstractPlottable pointer, you can check whether it implements this
4182   interface by calling \ref QCPAbstractPlottable::interface1D and testing it for a non-zero return
4183   value. If it indeed implements this interface, you may use it to access the plottable's data
4184   without needing to know the exact type of the plottable or its data point type.
4185 */
4186 
4187 /* start documentation of pure virtual functions */
4188 
4189 /*! \fn virtual int QCPPlottableInterface1D::dataCount() const = 0;
4190   
4191   Returns the number of data points of the plottable.
4192 */
4193 
4194 /*! \fn virtual QCPDataSelection QCPPlottableInterface1D::selectTestRect(const QRectF &rect, bool onlySelectable) const = 0;
4195   
4196   Returns a data selection containing all the data points of this plottable which are contained (or
4197   hit by) \a rect. This is used mainly in the selection rect interaction for data selection (\ref
4198   dataselection "data selection mechanism").
4199   
4200   If \a onlySelectable is true, an empty QCPDataSelection is returned if this plottable is not
4201   selectable (i.e. if \ref QCPAbstractPlottable::setSelectable is \ref QCP::stNone).
4202   
4203   \note \a rect must be a normalized rect (positive or zero width and height). This is especially
4204   important when using the rect of \ref QCPSelectionRect::accepted, which is not necessarily
4205   normalized. Use <tt>QRect::normalized()</tt> when passing a rect which might not be normalized.
4206 */
4207 
4208 /*! \fn virtual double QCPPlottableInterface1D::dataMainKey(int index) const = 0
4209   
4210   Returns the main key of the data point at the given \a index.
4211   
4212   What the main key is, is defined by the plottable's data type. See the \ref
4213   qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4214   convention.
4215 */
4216 
4217 /*! \fn virtual double QCPPlottableInterface1D::dataSortKey(int index) const = 0
4218   
4219   Returns the sort key of the data point at the given \a index.
4220   
4221   What the sort key is, is defined by the plottable's data type. See the \ref
4222   qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4223   convention.
4224 */
4225 
4226 /*! \fn virtual double QCPPlottableInterface1D::dataMainValue(int index) const = 0
4227   
4228   Returns the main value of the data point at the given \a index.
4229   
4230   What the main value is, is defined by the plottable's data type. See the \ref
4231   qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4232   convention.
4233 */
4234 
4235 /*! \fn virtual QCPRange QCPPlottableInterface1D::dataValueRange(int index) const = 0
4236   
4237   Returns the value range of the data point at the given \a index.
4238   
4239   What the value range is, is defined by the plottable's data type. See the \ref
4240   qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4241   convention.
4242 */
4243 
4244 /*! \fn virtual QPointF QCPPlottableInterface1D::dataPixelPosition(int index) const = 0
4245 
4246   Returns the pixel position on the widget surface at which the data point at the given \a index
4247   appears.
4248 
4249   Usually this corresponds to the point of \ref dataMainKey/\ref dataMainValue, in pixel
4250   coordinates. However, depending on the plottable, this might be a different apparent position
4251   than just a coord-to-pixel transform of those values. For example, \ref QCPBars apparent data
4252   values can be shifted depending on their stacking, bar grouping or configured base value.
4253 */
4254 
4255 /*! \fn virtual bool QCPPlottableInterface1D::sortKeyIsMainKey() const = 0
4256 
4257   Returns whether the sort key (\ref dataSortKey) is identical to the main key (\ref dataMainKey).
4258 
4259   What the sort and main keys are, is defined by the plottable's data type. See the \ref
4260   qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4261   convention.
4262 */
4263 
4264 /*! \fn virtual int QCPPlottableInterface1D::findBegin(double sortKey, bool expandedRange) const = 0
4265 
4266   Returns the index of the data point with a (sort-)key that is equal to, just below, or just above
4267   \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be considered,
4268   otherwise the one just above.
4269 
4270   This can be used in conjunction with \ref findEnd to iterate over data points within a given key
4271   range, including or excluding the bounding data points that are just beyond the specified range.
4272 
4273   If \a expandedRange is true but there are no data points below \a sortKey, 0 is returned.
4274 
4275   If the container is empty, returns 0 (in that case, \ref findEnd will also return 0, so a loop
4276   using these methods will not iterate over the index 0).
4277 
4278   \see findEnd, QCPDataContainer::findBegin
4279 */
4280 
4281 /*! \fn virtual int QCPPlottableInterface1D::findEnd(double sortKey, bool expandedRange) const = 0
4282 
4283   Returns the index one after the data point with a (sort-)key that is equal to, just above, or
4284   just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey will be
4285   considered, otherwise the one just below.
4286 
4287   This can be used in conjunction with \ref findBegin to iterate over data points within a given
4288   key range, including the bounding data points that are just below and above the specified range.
4289 
4290   If \a expandedRange is true but there are no data points above \a sortKey, the index just above the
4291   highest data point is returned.
4292 
4293   If the container is empty, returns 0.
4294 
4295   \see findBegin, QCPDataContainer::findEnd
4296 */
4297 
4298 /* end documentation of pure virtual functions */
4299 
4300 
4301 ////////////////////////////////////////////////////////////////////////////////////////////////////
4302 //////////////////// QCPAbstractPlottable1D
4303 ////////////////////////////////////////////////////////////////////////////////////////////////////
4304 
4305 /*! \class QCPAbstractPlottable1D
4306   \brief A template base class for plottables with one-dimensional data
4307 
4308   This template class derives from \ref QCPAbstractPlottable and from the abstract interface \ref
4309   QCPPlottableInterface1D. It serves as a base class for all one-dimensional data (i.e. data with
4310   one key dimension), such as \ref QCPGraph and QCPCurve.
4311 
4312   The template parameter \a DataType is the type of the data points of this plottable (e.g. \ref
4313   QCPGraphData or \ref QCPCurveData). The main purpose of this base class is to provide the member
4314   \a mDataContainer (a shared pointer to a \ref QCPDataContainer "QCPDataContainer<DataType>") and
4315   implement the according virtual methods of the \ref QCPPlottableInterface1D, such that most
4316   subclassed plottables don't need to worry about this anymore.
4317 
4318   Further, it provides a convenience method for retrieving selected/unselected data segments via
4319   \ref getDataSegments. This is useful when subclasses implement their \ref draw method and need to
4320   draw selected segments with a different pen/brush than unselected segments (also see \ref
4321   QCPSelectionDecorator).
4322 
4323   This class implements basic functionality of \ref QCPAbstractPlottable::selectTest and \ref
4324   QCPPlottableInterface1D::selectTestRect, assuming point-like data points, based on the 1D data
4325   interface. In spite of that, most plottable subclasses will want to reimplement those methods
4326   again, to provide a more accurate hit test based on their specific data visualization geometry.
4327 */
4328 
4329 /* start documentation of inline functions */
4330 
4331 /*! \fn QCPPlottableInterface1D *QCPAbstractPlottable1D::interface1D()
4332   
4333   Returns a \ref QCPPlottableInterface1D pointer to this plottable, providing access to its 1D
4334   interface.
4335   
4336   \seebaseclassmethod
4337 */
4338 
4339 /* end documentation of inline functions */
4340 
4341 /*!
4342   Forwards \a keyAxis and \a valueAxis to the \ref QCPAbstractPlottable::QCPAbstractPlottable
4343   "QCPAbstractPlottable" constructor and allocates the \a mDataContainer.
4344 */
4345 template <class DataType>
4346 QCPAbstractPlottable1D<DataType>::QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis) :
4347   QCPAbstractPlottable(keyAxis, valueAxis),
4348   mDataContainer(new QCPDataContainer<DataType>)
4349 {
4350 }
4351 
4352 template <class DataType>
4353 QCPAbstractPlottable1D<DataType>::~QCPAbstractPlottable1D()
4354 {
4355 }
4356 
4357 /*!
4358   \copydoc QCPPlottableInterface1D::dataCount
4359 */
4360 template <class DataType>
4361 int QCPAbstractPlottable1D<DataType>::dataCount() const
4362 {
4363   return mDataContainer->size();
4364 }
4365 
4366 /*!
4367   \copydoc QCPPlottableInterface1D::dataMainKey
4368 */
4369 template <class DataType>
4370 double QCPAbstractPlottable1D<DataType>::dataMainKey(int index) const
4371 {
4372   if (index >= 0 && index < mDataContainer->size())
4373   {
4374     return (mDataContainer->constBegin()+index)->mainKey();
4375   } else
4376   {
4377     qDebug() << Q_FUNC_INFO << "Index out of bounds" << index;
4378     return 0;
4379   }
4380 }
4381 
4382 /*!
4383   \copydoc QCPPlottableInterface1D::dataSortKey
4384 */
4385 template <class DataType>
4386 double QCPAbstractPlottable1D<DataType>::dataSortKey(int index) const
4387 {
4388   if (index >= 0 && index < mDataContainer->size())
4389   {
4390     return (mDataContainer->constBegin()+index)->sortKey();
4391   } else
4392   {
4393     qDebug() << Q_FUNC_INFO << "Index out of bounds" << index;
4394     return 0;
4395   }
4396 }
4397 
4398 /*!
4399   \copydoc QCPPlottableInterface1D::dataMainValue
4400 */
4401 template <class DataType>
4402 double QCPAbstractPlottable1D<DataType>::dataMainValue(int index) const
4403 {
4404   if (index >= 0 && index < mDataContainer->size())
4405   {
4406     return (mDataContainer->constBegin()+index)->mainValue();
4407   } else
4408   {
4409     qDebug() << Q_FUNC_INFO << "Index out of bounds" << index;
4410     return 0;
4411   }
4412 }
4413 
4414 /*!
4415   \copydoc QCPPlottableInterface1D::dataValueRange
4416 */
4417 template <class DataType>
4418 QCPRange QCPAbstractPlottable1D<DataType>::dataValueRange(int index) const
4419 {
4420   if (index >= 0 && index < mDataContainer->size())
4421   {
4422     return (mDataContainer->constBegin()+index)->valueRange();
4423   } else
4424   {
4425     qDebug() << Q_FUNC_INFO << "Index out of bounds" << index;
4426     return QCPRange(0, 0);
4427   }
4428 }
4429 
4430 /*!
4431   \copydoc QCPPlottableInterface1D::dataPixelPosition
4432 */
4433 template <class DataType>
4434 QPointF QCPAbstractPlottable1D<DataType>::dataPixelPosition(int index) const
4435 {
4436   if (index >= 0 && index < mDataContainer->size())
4437   {
4438     const typename QCPDataContainer<DataType>::const_iterator it = mDataContainer->constBegin()+index;
4439     return coordsToPixels(it->mainKey(), it->mainValue());
4440   } else
4441   {
4442     qDebug() << Q_FUNC_INFO << "Index out of bounds" << index;
4443     return QPointF();
4444   }
4445 }
4446 
4447 /*!
4448   \copydoc QCPPlottableInterface1D::sortKeyIsMainKey
4449 */
4450 template <class DataType>
4451 bool QCPAbstractPlottable1D<DataType>::sortKeyIsMainKey() const
4452 {
4453   return DataType::sortKeyIsMainKey();
4454 }
4455 
4456 /*!
4457   Implements a rect-selection algorithm assuming the data (accessed via the 1D data interface) is
4458   point-like. Most subclasses will want to reimplement this method again, to provide a more
4459   accurate hit test based on the true data visualization geometry.
4460 
4461   \seebaseclassmethod
4462 */
4463 template <class DataType>
4464 QCPDataSelection QCPAbstractPlottable1D<DataType>::selectTestRect(const QRectF &rect, bool onlySelectable) const
4465 {
4466   QCPDataSelection result;
4467   if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty())
4468     return result;
4469   if (!mKeyAxis || !mValueAxis)
4470     return result;
4471   
4472   // convert rect given in pixels to ranges given in plot coordinates:
4473   double key1, value1, key2, value2;
4474   pixelsToCoords(rect.topLeft(), key1, value1);
4475   pixelsToCoords(rect.bottomRight(), key2, value2);
4476   QCPRange keyRange(key1, key2); // QCPRange normalizes internally so we don't have to care about whether key1 < key2
4477   QCPRange valueRange(value1, value2);
4478   typename QCPDataContainer<DataType>::const_iterator begin = mDataContainer->constBegin();
4479   typename QCPDataContainer<DataType>::const_iterator end = mDataContainer->constEnd();
4480   if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval:
4481   {
4482     begin = mDataContainer->findBegin(keyRange.lower, false);
4483     end = mDataContainer->findEnd(keyRange.upper, false);
4484   }
4485   if (begin == end)
4486     return result;
4487   
4488   int currentSegmentBegin = -1; // -1 means we're currently not in a segment that's contained in rect
4489   for (typename QCPDataContainer<DataType>::const_iterator it=begin; it!=end; ++it)
4490   {
4491     if (currentSegmentBegin == -1)
4492     {
4493       if (valueRange.contains(it->mainValue()) && keyRange.contains(it->mainKey())) // start segment
4494         currentSegmentBegin = int(it-mDataContainer->constBegin());
4495     } else if (!valueRange.contains(it->mainValue()) || !keyRange.contains(it->mainKey())) // segment just ended
4496     {
4497       result.addDataRange(QCPDataRange(currentSegmentBegin, int(it-mDataContainer->constBegin())), false);
4498       currentSegmentBegin = -1;
4499     }
4500   }
4501   // process potential last segment:
4502   if (currentSegmentBegin != -1)
4503     result.addDataRange(QCPDataRange(currentSegmentBegin, int(end-mDataContainer->constBegin())), false);
4504   
4505   result.simplify();
4506   return result;
4507 }
4508 
4509 /*!
4510   \copydoc QCPPlottableInterface1D::findBegin
4511 */
4512 template <class DataType>
4513 int QCPAbstractPlottable1D<DataType>::findBegin(double sortKey, bool expandedRange) const
4514 {
4515   return int(mDataContainer->findBegin(sortKey, expandedRange)-mDataContainer->constBegin());
4516 }
4517 
4518 /*!
4519   \copydoc QCPPlottableInterface1D::findEnd
4520 */
4521 template <class DataType>
4522 int QCPAbstractPlottable1D<DataType>::findEnd(double sortKey, bool expandedRange) const
4523 {
4524   return int(mDataContainer->findEnd(sortKey, expandedRange)-mDataContainer->constBegin());
4525 }
4526 
4527 /*!
4528   Implements a point-selection algorithm assuming the data (accessed via the 1D data interface) is
4529   point-like. Most subclasses will want to reimplement this method again, to provide a more
4530   accurate hit test based on the true data visualization geometry.
4531 
4532   If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data point
4533   to \a pos.
4534   
4535   \seebaseclassmethod
4536 */
4537 template <class DataType>
4538 double QCPAbstractPlottable1D<DataType>::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const
4539 {
4540   if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty())
4541     return -1;
4542   if (!mKeyAxis || !mValueAxis)
4543     return -1;
4544   
4545   QCPDataSelection selectionResult;
4546   double minDistSqr = (std::numeric_limits<double>::max)();
4547   int minDistIndex = mDataContainer->size();
4548   
4549   typename QCPDataContainer<DataType>::const_iterator begin = mDataContainer->constBegin();
4550   typename QCPDataContainer<DataType>::const_iterator end = mDataContainer->constEnd();
4551   if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval:
4552   {
4553     // determine which key range comes into question, taking selection tolerance around pos into account:
4554     double posKeyMin, posKeyMax, dummy;
4555     pixelsToCoords(pos-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy);
4556     pixelsToCoords(pos+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy);
4557     if (posKeyMin > posKeyMax)
4558       qSwap(posKeyMin, posKeyMax);
4559     begin = mDataContainer->findBegin(posKeyMin, true);
4560     end = mDataContainer->findEnd(posKeyMax, true);
4561   }
4562   if (begin == end)
4563     return -1;
4564   QCPRange keyRange(mKeyAxis->range());
4565   QCPRange valueRange(mValueAxis->range());
4566   for (typename QCPDataContainer<DataType>::const_iterator it=begin; it!=end; ++it)
4567   {
4568     const double mainKey = it->mainKey();
4569     const double mainValue = it->mainValue();
4570     if (keyRange.contains(mainKey) && valueRange.contains(mainValue)) // make sure data point is inside visible range, for speedup in cases where sort key isn't main key and we iterate over all points
4571     {
4572       const double currentDistSqr = QCPVector2D(coordsToPixels(mainKey, mainValue)-pos).lengthSquared();
4573       if (currentDistSqr < minDistSqr)
4574       {
4575         minDistSqr = currentDistSqr;
4576         minDistIndex = int(it-mDataContainer->constBegin());
4577       }
4578     }
4579   }
4580   if (minDistIndex != mDataContainer->size())
4581     selectionResult.addDataRange(QCPDataRange(minDistIndex, minDistIndex+1), false);
4582   
4583   selectionResult.simplify();
4584   if (details)
4585     details->setValue(selectionResult);
4586   return qSqrt(minDistSqr);
4587 }
4588 
4589 /*!
4590   Splits all data into selected and unselected segments and outputs them via \a selectedSegments
4591   and \a unselectedSegments, respectively.
4592 
4593   This is useful when subclasses implement their \ref draw method and need to draw selected
4594   segments with a different pen/brush than unselected segments (also see \ref
4595   QCPSelectionDecorator).
4596 
4597   \see setSelection
4598 */
4599 template <class DataType>
4600 void QCPAbstractPlottable1D<DataType>::getDataSegments(QList<QCPDataRange> &selectedSegments, QList<QCPDataRange> &unselectedSegments) const
4601 {
4602   selectedSegments.clear();
4603   unselectedSegments.clear();
4604   if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty
4605   {
4606     if (selected())
4607       selectedSegments << QCPDataRange(0, dataCount());
4608     else
4609       unselectedSegments << QCPDataRange(0, dataCount());
4610   } else
4611   {
4612     QCPDataSelection sel(selection());
4613     sel.simplify();
4614     selectedSegments = sel.dataRanges();
4615     unselectedSegments = sel.inverse(QCPDataRange(0, dataCount())).dataRanges();
4616   }
4617 }
4618 
4619 /*!
4620   A helper method which draws a line with the passed \a painter, according to the pixel data in \a
4621   lineData. NaN points create gaps in the line, as expected from QCustomPlot's plottables (this is
4622   the main difference to QPainter's regular drawPolyline, which handles NaNs by lagging or
4623   crashing).
4624 
4625   Further it uses a faster line drawing technique based on \ref QCPPainter::drawLine rather than \c
4626   QPainter::drawPolyline if the configured \ref QCustomPlot::setPlottingHints() and \a painter
4627   style allows.
4628 */
4629 template <class DataType>
4630 void QCPAbstractPlottable1D<DataType>::drawPolyline(QCPPainter *painter, const QVector<QPointF> &lineData) const
4631 {
4632   // if drawing lines in plot (instead of PDF), reduce 1px lines to cosmetic, because at least in
4633   // Qt6 drawing of "1px" width lines is much slower even though it has same appearance apart from
4634   // High-DPI. In High-DPI cases people must set a pen width slightly larger than 1.0 to get
4635   // correct DPI scaling of width, but of course with performance penalty.
4636   if (!painter->modes().testFlag(QCPPainter::pmVectorized) &&
4637       qFuzzyCompare(painter->pen().widthF(), 1.0))
4638   {
4639     QPen newPen = painter->pen();
4640     newPen.setWidth(0);
4641     painter->setPen(newPen);
4642   }
4643 
4644   // if drawing solid line and not in PDF, use much faster line drawing instead of polyline:
4645   if (mParentPlot->plottingHints().testFlag(QCP::phFastPolylines) &&
4646       painter->pen().style() == Qt::SolidLine &&
4647       !painter->modes().testFlag(QCPPainter::pmVectorized) &&
4648       !painter->modes().testFlag(QCPPainter::pmNoCaching))
4649   {
4650     int i = 0;
4651     bool lastIsNan = false;
4652     const int lineDataSize = lineData.size();
4653     while (i < lineDataSize && (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()))) // make sure first point is not NaN
4654       ++i;
4655     ++i; // because drawing works in 1 point retrospect
4656     while (i < lineDataSize)
4657     {
4658       if (!qIsNaN(lineData.at(i).y()) && !qIsNaN(lineData.at(i).x())) // NaNs create a gap in the line
4659       {
4660         if (!lastIsNan)
4661           painter->drawLine(lineData.at(i-1), lineData.at(i));
4662         else
4663           lastIsNan = false;
4664       } else
4665         lastIsNan = true;
4666       ++i;
4667     }
4668   } else
4669   {
4670     int segmentStart = 0;
4671     int i = 0;
4672     const int lineDataSize = lineData.size();
4673     while (i < lineDataSize)
4674     {
4675       if (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()) || qIsInf(lineData.at(i).y())) // NaNs create a gap in the line. Also filter Infs which make drawPolyline block
4676       {
4677         painter->drawPolyline(lineData.constData()+segmentStart, i-segmentStart); // i, because we don't want to include the current NaN point
4678         segmentStart = i+1;
4679       }
4680       ++i;
4681     }
4682     // draw last segment:
4683     painter->drawPolyline(lineData.constData()+segmentStart, lineDataSize-segmentStart);
4684   }
4685 }
4686 
4687 
4688 /* end of 'src/plottable1d.h' */
4689 
4690 
4691 /* including file 'src/colorgradient.h'    */
4692 /* modified 2021-03-29T02:30:44, size 7262 */
4693 
4694 class QCP_LIB_DECL QCPColorGradient
4695 {
4696   Q_GADGET
4697 public:
4698   /*!
4699     Defines the color spaces in which color interpolation between gradient stops can be performed.
4700     
4701     \see setColorInterpolation
4702   */
4703   enum ColorInterpolation { ciRGB  ///< Color channels red, green and blue are linearly interpolated
4704                             ,ciHSV ///< Color channels hue, saturation and value are linearly interpolated (The hue is interpolated over the shortest angle distance)
4705                           };
4706   Q_ENUMS(ColorInterpolation)
4707   
4708   /*!
4709     Defines how NaN data points shall appear in the plot.
4710     
4711     \see setNanHandling, setNanColor
4712   */
4713   enum NanHandling { nhNone ///< NaN data points are not explicitly handled and shouldn't occur in the data (this gives slight performance improvement)
4714                      ,nhLowestColor  ///< NaN data points appear as the lowest color defined in this QCPColorGradient
4715                      ,nhHighestColor ///< NaN data points appear as the highest color defined in this QCPColorGradient
4716                      ,nhTransparent ///< NaN data points appear transparent
4717                      ,nhNanColor ///< NaN data points appear as the color defined with \ref setNanColor
4718                    };
4719   Q_ENUMS(NanHandling)
4720   
4721   /*!
4722     Defines the available presets that can be loaded with \ref loadPreset. See the documentation
4723     there for an image of the presets.
4724   */
4725   enum GradientPreset { gpGrayscale  ///< Continuous lightness from black to white (suited for non-biased data representation)
4726                         ,gpHot       ///< Continuous lightness from black over firey colors to white (suited for non-biased data representation)
4727                         ,gpCold      ///< Continuous lightness from black over icey colors to white (suited for non-biased data representation)
4728                         ,gpNight     ///< Continuous lightness from black over weak blueish colors to white (suited for non-biased data representation)
4729                         ,gpCandy     ///< Blue over pink to white
4730                         ,gpGeography ///< Colors suitable to represent different elevations on geographical maps
4731                         ,gpIon       ///< Half hue spectrum from black over purple to blue and finally green (creates banding illusion but allows more precise magnitude estimates)
4732                         ,gpThermal   ///< Colors suitable for thermal imaging, ranging from dark blue over purple to orange, yellow and white
4733                         ,gpPolar     ///< Colors suitable to emphasize polarity around the center, with blue for negative, black in the middle and red for positive values
4734                         ,gpSpectrum  ///< An approximation of the visible light spectrum (creates banding illusion but allows more precise magnitude estimates)
4735                         ,gpJet       ///< Hue variation similar to a spectrum, often used in numerical visualization (creates banding illusion but allows more precise magnitude estimates)
4736                         ,gpHues      ///< Full hue cycle, with highest and lowest color red (suitable for periodic data, such as angles and phases, see \ref setPeriodic)
4737                       };
4738   Q_ENUMS(GradientPreset)
4739   
4740   QCPColorGradient();
4741   QCPColorGradient(GradientPreset preset);
4742   bool operator==(const QCPColorGradient &other) const;
4743   bool operator!=(const QCPColorGradient &other) const { return !(*this == other); }
4744   
4745   // getters:
4746   int levelCount() const { return mLevelCount; }
4747   QMap<double, QColor> colorStops() const { return mColorStops; }
4748   ColorInterpolation colorInterpolation() const { return mColorInterpolation; }
4749   NanHandling nanHandling() const { return mNanHandling; }
4750   QColor nanColor() const { return mNanColor; }
4751   bool periodic() const { return mPeriodic; }
4752   
4753   // setters:
4754   void setLevelCount(int n);
4755   void setColorStops(const QMap<double, QColor> &colorStops);
4756   void setColorStopAt(double position, const QColor &color);
4757   void setColorInterpolation(ColorInterpolation interpolation);
4758   void setNanHandling(NanHandling handling);
4759   void setNanColor(const QColor &color);
4760   void setPeriodic(bool enabled);
4761   
4762   // non-property methods:
4763   void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false);
4764   void colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false);
4765   QRgb color(double position, const QCPRange &range, bool logarithmic=false);
4766   void loadPreset(GradientPreset preset);
4767   void clearColorStops();
4768   QCPColorGradient inverted() const;
4769   
4770 protected:
4771   // property members:
4772   int mLevelCount;
4773   QMap<double, QColor> mColorStops;
4774   ColorInterpolation mColorInterpolation;
4775   NanHandling mNanHandling;
4776   QColor mNanColor;
4777   bool mPeriodic;
4778   
4779   // non-property members:
4780   QVector<QRgb> mColorBuffer; // have colors premultiplied with alpha (for usage with QImage::Format_ARGB32_Premultiplied)
4781   bool mColorBufferInvalidated;
4782   
4783   // non-virtual methods:
4784   bool stopsUseAlpha() const;
4785   void updateColorBuffer();
4786 };
4787 Q_DECLARE_METATYPE(QCPColorGradient::ColorInterpolation)
4788 Q_DECLARE_METATYPE(QCPColorGradient::NanHandling)
4789 Q_DECLARE_METATYPE(QCPColorGradient::GradientPreset)
4790 
4791 /* end of 'src/colorgradient.h' */
4792 
4793 
4794 /* including file 'src/selectiondecorator-bracket.h' */
4795 /* modified 2021-03-29T02:30:44, size 4458           */
4796 
4797 class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator
4798 {
4799   Q_GADGET
4800 public:
4801   
4802   /*!
4803     Defines which shape is drawn at the boundaries of selected data ranges.
4804     
4805     Some of the bracket styles further allow specifying a height and/or width, see \ref
4806     setBracketHeight and \ref setBracketWidth.
4807   */
4808   enum BracketStyle { bsSquareBracket ///< A square bracket is drawn.
4809                       ,bsHalfEllipse   ///< A half ellipse is drawn. The size of the ellipse is given by the bracket width/height properties.
4810                       ,bsEllipse       ///< An ellipse is drawn. The size of the ellipse is given by the bracket width/height properties.
4811                       ,bsPlus         ///< A plus is drawn.
4812                       ,bsUserStyle    ///< Start custom bracket styles at this index when subclassing and reimplementing \ref drawBracket.
4813   };
4814   Q_ENUMS(BracketStyle)
4815   
4816   QCPSelectionDecoratorBracket();
4817   virtual ~QCPSelectionDecoratorBracket() Q_DECL_OVERRIDE;
4818   
4819   // getters:
4820   QPen bracketPen() const { return mBracketPen; }
4821   QBrush bracketBrush() const { return mBracketBrush; }
4822   int bracketWidth() const { return mBracketWidth; }
4823   int bracketHeight() const { return mBracketHeight; }
4824   BracketStyle bracketStyle() const { return mBracketStyle; }
4825   bool tangentToData() const { return mTangentToData; }
4826   int tangentAverage() const { return mTangentAverage; }
4827   
4828   // setters:
4829   void setBracketPen(const QPen &pen);
4830   void setBracketBrush(const QBrush &brush);
4831   void setBracketWidth(int width);
4832   void setBracketHeight(int height);
4833   void setBracketStyle(BracketStyle style);
4834   void setTangentToData(bool enabled);
4835   void setTangentAverage(int pointCount);
4836   
4837   // introduced virtual methods:
4838   virtual void drawBracket(QCPPainter *painter, int direction) const;
4839   
4840   // virtual methods:
4841   virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection) Q_DECL_OVERRIDE;
4842   
4843 protected:
4844   // property members:
4845   QPen mBracketPen;
4846   QBrush mBracketBrush;
4847   int mBracketWidth;
4848   int mBracketHeight;
4849   BracketStyle mBracketStyle;
4850   bool mTangentToData;
4851   int mTangentAverage;
4852   
4853   // non-virtual methods:
4854   double getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const;
4855   QPointF getPixelCoordinates(const QCPPlottableInterface1D *interface1d, int dataIndex) const;
4856   
4857 };
4858 Q_DECLARE_METATYPE(QCPSelectionDecoratorBracket::BracketStyle)
4859 
4860 /* end of 'src/selectiondecorator-bracket.h' */
4861 
4862 
4863 /* including file 'src/layoutelements/layoutelement-axisrect.h' */
4864 /* modified 2021-03-29T02:30:44, size 7529                      */
4865 
4866 class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement
4867 {
4868   Q_OBJECT
4869   /// \cond INCLUDE_QPROPERTIES
4870   Q_PROPERTY(QPixmap background READ background WRITE setBackground)
4871   Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled)
4872   Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode)
4873   Q_PROPERTY(Qt::Orientations rangeDrag READ rangeDrag WRITE setRangeDrag)
4874   Q_PROPERTY(Qt::Orientations rangeZoom READ rangeZoom WRITE setRangeZoom)
4875   /// \endcond
4876 public:
4877   explicit QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes=true);
4878   virtual ~QCPAxisRect() Q_DECL_OVERRIDE;
4879   
4880   // getters:
4881   QPixmap background() const { return mBackgroundPixmap; }
4882   QBrush backgroundBrush() const { return mBackgroundBrush; }
4883   bool backgroundScaled() const { return mBackgroundScaled; }
4884   Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; }
4885   Qt::Orientations rangeDrag() const { return mRangeDrag; }
4886   Qt::Orientations rangeZoom() const { return mRangeZoom; }
4887   QCPAxis *rangeDragAxis(Qt::Orientation orientation);
4888   QCPAxis *rangeZoomAxis(Qt::Orientation orientation);
4889   QList<QCPAxis*> rangeDragAxes(Qt::Orientation orientation);
4890   QList<QCPAxis*> rangeZoomAxes(Qt::Orientation orientation);
4891   double rangeZoomFactor(Qt::Orientation orientation);
4892   
4893   // setters:
4894   void setBackground(const QPixmap &pm);
4895   void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding);
4896   void setBackground(const QBrush &brush);
4897   void setBackgroundScaled(bool scaled);
4898   void setBackgroundScaledMode(Qt::AspectRatioMode mode);
4899   void setRangeDrag(Qt::Orientations orientations);
4900   void setRangeZoom(Qt::Orientations orientations);
4901   void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical);
4902   void setRangeDragAxes(QList<QCPAxis*> axes);
4903   void setRangeDragAxes(QList<QCPAxis*> horizontal, QList<QCPAxis*> vertical);
4904   void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical);
4905   void setRangeZoomAxes(QList<QCPAxis*> axes);
4906   void setRangeZoomAxes(QList<QCPAxis*> horizontal, QList<QCPAxis*> vertical);
4907   void setRangeZoomFactor(double horizontalFactor, double verticalFactor);
4908   void setRangeZoomFactor(double factor);
4909   
4910   // non-property methods:
4911   int axisCount(QCPAxis::AxisType type) const;
4912   QCPAxis *axis(QCPAxis::AxisType type, int index=0) const;
4913   QList<QCPAxis*> axes(QCPAxis::AxisTypes types) const;
4914   QList<QCPAxis*> axes() const;
4915   QCPAxis *addAxis(QCPAxis::AxisType type, QCPAxis *axis=nullptr);
4916   QList<QCPAxis*> addAxes(QCPAxis::AxisTypes types);
4917   bool removeAxis(QCPAxis *axis);
4918   QCPLayoutInset *insetLayout() const { return mInsetLayout; }
4919   
4920   void zoom(const QRectF &pixelRect);
4921   void zoom(const QRectF &pixelRect, const QList<QCPAxis*> &affectedAxes);
4922   void setupFullAxesBox(bool connectRanges=false);
4923   QList<QCPAbstractPlottable*> plottables() const;
4924   QList<QCPGraph*> graphs() const;
4925   QList<QCPAbstractItem*> items() const;
4926   
4927   // read-only interface imitating a QRect:
4928   int left() const { return mRect.left(); }
4929   int right() const { return mRect.right(); }
4930   int top() const { return mRect.top(); }
4931   int bottom() const { return mRect.bottom(); }
4932   int width() const { return mRect.width(); }
4933   int height() const { return mRect.height(); }
4934   QSize size() const { return mRect.size(); }
4935   QPoint topLeft() const { return mRect.topLeft(); }
4936   QPoint topRight() const { return mRect.topRight(); }
4937   QPoint bottomLeft() const { return mRect.bottomLeft(); }
4938   QPoint bottomRight() const { return mRect.bottomRight(); }
4939   QPoint center() const { return mRect.center(); }
4940   
4941   // reimplemented virtual methods:
4942   virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE;
4943   virtual QList<QCPLayoutElement*> elements(bool recursive) const Q_DECL_OVERRIDE;
4944 
4945 protected:
4946   // property members:
4947   QBrush mBackgroundBrush;
4948   QPixmap mBackgroundPixmap;
4949   QPixmap mScaledBackgroundPixmap;
4950   bool mBackgroundScaled;
4951   Qt::AspectRatioMode mBackgroundScaledMode;
4952   QCPLayoutInset *mInsetLayout;
4953   Qt::Orientations mRangeDrag, mRangeZoom;
4954   QList<QPointer<QCPAxis> > mRangeDragHorzAxis, mRangeDragVertAxis;
4955   QList<QPointer<QCPAxis> > mRangeZoomHorzAxis, mRangeZoomVertAxis;
4956   double mRangeZoomFactorHorz, mRangeZoomFactorVert;
4957   
4958   // non-property members:
4959   QList<QCPRange> mDragStartHorzRange, mDragStartVertRange;
4960   QCP::AntialiasedElements mAADragBackup, mNotAADragBackup;
4961   bool mDragging;
4962   QHash<QCPAxis::AxisType, QList<QCPAxis*> > mAxes;
4963   
4964   // reimplemented virtual methods:
4965   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
4966   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
4967   virtual int calculateAutoMargin(QCP::MarginSide side) Q_DECL_OVERRIDE;
4968   virtual void layoutChanged() Q_DECL_OVERRIDE;
4969   // events:
4970   virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE;
4971   virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE;
4972   virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE;
4973   virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
4974   
4975   // non-property methods:
4976   void drawBackground(QCPPainter *painter);
4977   void updateAxesOffset(QCPAxis::AxisType type);
4978   
4979 private:
4980   Q_DISABLE_COPY(QCPAxisRect)
4981   
4982   friend class QCustomPlot;
4983 };
4984 
4985 
4986 /* end of 'src/layoutelements/layoutelement-axisrect.h' */
4987 
4988 
4989 /* including file 'src/layoutelements/layoutelement-legend.h' */
4990 /* modified 2021-03-29T02:30:44, size 10425                   */
4991 
4992 class QCP_LIB_DECL QCPAbstractLegendItem : public QCPLayoutElement
4993 {
4994   Q_OBJECT
4995   /// \cond INCLUDE_QPROPERTIES
4996   Q_PROPERTY(QCPLegend* parentLegend READ parentLegend)
4997   Q_PROPERTY(QFont font READ font WRITE setFont)
4998   Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor)
4999   Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont)
5000   Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor)
5001   Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectionChanged)
5002   Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectableChanged)
5003   /// \endcond
5004 public:
5005   explicit QCPAbstractLegendItem(QCPLegend *parent);
5006   
5007   // getters:
5008   QCPLegend *parentLegend() const { return mParentLegend; }
5009   QFont font() const { return mFont; }
5010   QColor textColor() const { return mTextColor; }
5011   QFont selectedFont() const { return mSelectedFont; }
5012   QColor selectedTextColor() const { return mSelectedTextColor; }
5013   bool selectable() const { return mSelectable; }
5014   bool selected() const { return mSelected; }
5015   
5016   // setters:
5017   void setFont(const QFont &font);
5018   void setTextColor(const QColor &color);
5019   void setSelectedFont(const QFont &font);
5020   void setSelectedTextColor(const QColor &color);
5021   Q_SLOT void setSelectable(bool selectable);
5022   Q_SLOT void setSelected(bool selected);
5023   
5024   // reimplemented virtual methods:
5025   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
5026   
5027 signals:
5028   void selectionChanged(bool selected);
5029   void selectableChanged(bool selectable);
5030   
5031 protected:
5032   // property members:
5033   QCPLegend *mParentLegend;
5034   QFont mFont;
5035   QColor mTextColor;
5036   QFont mSelectedFont;
5037   QColor mSelectedTextColor;
5038   bool mSelectable, mSelected;
5039   
5040   // reimplemented virtual methods:
5041   virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE;
5042   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
5043   virtual QRect clipRect() const Q_DECL_OVERRIDE;
5044   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0;
5045   // events:
5046   virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
5047   virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE;
5048   
5049 private:
5050   Q_DISABLE_COPY(QCPAbstractLegendItem)
5051   
5052   friend class QCPLegend;
5053 };
5054 
5055 
5056 class QCP_LIB_DECL QCPPlottableLegendItem : public QCPAbstractLegendItem
5057 {
5058   Q_OBJECT
5059 public:
5060   QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable);
5061   
5062   // getters:
5063   QCPAbstractPlottable *plottable() { return mPlottable; }
5064   
5065 protected:
5066   // property members:
5067   QCPAbstractPlottable *mPlottable;
5068   
5069   // reimplemented virtual methods:
5070   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
5071   virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE;
5072   
5073   // non-virtual methods:
5074   QPen getIconBorderPen() const;
5075   QColor getTextColor() const;
5076   QFont getFont() const;
5077 };
5078 
5079 
5080 class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid
5081 {
5082   Q_OBJECT
5083   /// \cond INCLUDE_QPROPERTIES
5084   Q_PROPERTY(QPen borderPen READ borderPen WRITE setBorderPen)
5085   Q_PROPERTY(QBrush brush READ brush WRITE setBrush)
5086   Q_PROPERTY(QFont font READ font WRITE setFont)
5087   Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor)
5088   Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
5089   Q_PROPERTY(int iconTextPadding READ iconTextPadding WRITE setIconTextPadding)
5090   Q_PROPERTY(QPen iconBorderPen READ iconBorderPen WRITE setIconBorderPen)
5091   Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectionChanged)
5092   Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectableChanged)
5093   Q_PROPERTY(QPen selectedBorderPen READ selectedBorderPen WRITE setSelectedBorderPen)
5094   Q_PROPERTY(QPen selectedIconBorderPen READ selectedIconBorderPen WRITE setSelectedIconBorderPen)
5095   Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush)
5096   Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont)
5097   Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor)
5098   /// \endcond
5099 public:
5100   /*!
5101     Defines the selectable parts of a legend
5102     
5103     \see setSelectedParts, setSelectableParts
5104   */
5105   enum SelectablePart { spNone        = 0x000 ///< <tt>0x000</tt> None
5106                         ,spLegendBox  = 0x001 ///< <tt>0x001</tt> The legend box (frame)
5107                         ,spItems      = 0x002 ///< <tt>0x002</tt> Legend items individually (see \ref selectedItems)
5108                       };
5109   Q_ENUMS(SelectablePart)
5110   Q_FLAGS(SelectableParts)
5111   Q_DECLARE_FLAGS(SelectableParts, SelectablePart)
5112   
5113   explicit QCPLegend();
5114   virtual ~QCPLegend() Q_DECL_OVERRIDE;
5115   
5116   // getters:
5117   QPen borderPen() const { return mBorderPen; }
5118   QBrush brush() const { return mBrush; }
5119   QFont font() const { return mFont; }
5120   QColor textColor() const { return mTextColor; }
5121   QSize iconSize() const { return mIconSize; }
5122   int iconTextPadding() const { return mIconTextPadding; }
5123   QPen iconBorderPen() const { return mIconBorderPen; }
5124   SelectableParts selectableParts() const { return mSelectableParts; }
5125   SelectableParts selectedParts() const;
5126   QPen selectedBorderPen() const { return mSelectedBorderPen; }
5127   QPen selectedIconBorderPen() const { return mSelectedIconBorderPen; }
5128   QBrush selectedBrush() const { return mSelectedBrush; }
5129   QFont selectedFont() const { return mSelectedFont; }
5130   QColor selectedTextColor() const { return mSelectedTextColor; }
5131   
5132   // setters:
5133   void setBorderPen(const QPen &pen);
5134   void setBrush(const QBrush &brush);
5135   void setFont(const QFont &font);
5136   void setTextColor(const QColor &color);
5137   void setIconSize(const QSize &size);
5138   void setIconSize(int width, int height);
5139   void setIconTextPadding(int padding);
5140   void setIconBorderPen(const QPen &pen);
5141   Q_SLOT void setSelectableParts(const SelectableParts &selectableParts);
5142   Q_SLOT void setSelectedParts(const SelectableParts &selectedParts);
5143   void setSelectedBorderPen(const QPen &pen);
5144   void setSelectedIconBorderPen(const QPen &pen);
5145   void setSelectedBrush(const QBrush &brush);
5146   void setSelectedFont(const QFont &font);
5147   void setSelectedTextColor(const QColor &color);
5148   
5149   // reimplemented virtual methods:
5150   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
5151   
5152   // non-virtual methods:
5153   QCPAbstractLegendItem *item(int index) const;
5154   QCPPlottableLegendItem *itemWithPlottable(const QCPAbstractPlottable *plottable) const;
5155   int itemCount() const;
5156   bool hasItem(QCPAbstractLegendItem *item) const;
5157   bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const;
5158   bool addItem(QCPAbstractLegendItem *item);
5159   bool removeItem(int index);
5160   bool removeItem(QCPAbstractLegendItem *item);
5161   void clearItems();
5162   QList<QCPAbstractLegendItem*> selectedItems() const;
5163   
5164 signals:
5165   void selectionChanged(QCPLegend::SelectableParts parts);
5166   void selectableChanged(QCPLegend::SelectableParts parts);
5167   
5168 protected:
5169   // property members:
5170   QPen mBorderPen, mIconBorderPen;
5171   QBrush mBrush;
5172   QFont mFont;
5173   QColor mTextColor;
5174   QSize mIconSize;
5175   int mIconTextPadding;
5176   SelectableParts mSelectedParts, mSelectableParts;
5177   QPen mSelectedBorderPen, mSelectedIconBorderPen;
5178   QBrush mSelectedBrush;
5179   QFont mSelectedFont;
5180   QColor mSelectedTextColor;
5181   
5182   // reimplemented virtual methods:
5183   virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE;
5184   virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE;
5185   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
5186   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
5187   // events:
5188   virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
5189   virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE;
5190   
5191   // non-virtual methods:
5192   QPen getBorderPen() const;
5193   QBrush getBrush() const;
5194   
5195 private:
5196   Q_DISABLE_COPY(QCPLegend)
5197   
5198   friend class QCustomPlot;
5199   friend class QCPAbstractLegendItem;
5200 };
5201 Q_DECLARE_OPERATORS_FOR_FLAGS(QCPLegend::SelectableParts)
5202 Q_DECLARE_METATYPE(QCPLegend::SelectablePart)
5203 
5204 /* end of 'src/layoutelements/layoutelement-legend.h' */
5205 
5206 
5207 /* including file 'src/layoutelements/layoutelement-textelement.h' */
5208 /* modified 2021-03-29T02:30:44, size 5359                         */
5209 
5210 class QCP_LIB_DECL QCPTextElement : public QCPLayoutElement
5211 {
5212   Q_OBJECT
5213   /// \cond INCLUDE_QPROPERTIES
5214   Q_PROPERTY(QString text READ text WRITE setText)
5215   Q_PROPERTY(QFont font READ font WRITE setFont)
5216   Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor)
5217   Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont)
5218   Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor)
5219   Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged)
5220   Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged)
5221   /// \endcond
5222 public:
5223   explicit QCPTextElement(QCustomPlot *parentPlot);
5224   QCPTextElement(QCustomPlot *parentPlot, const QString &text);
5225   QCPTextElement(QCustomPlot *parentPlot, const QString &text, double pointSize);
5226   QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QString &fontFamily, double pointSize);
5227   QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QFont &font);
5228   
5229   // getters:
5230   QString text() const { return mText; }
5231   int textFlags() const { return mTextFlags; }
5232   QFont font() const { return mFont; }
5233   QColor textColor() const { return mTextColor; }
5234   QFont selectedFont() const { return mSelectedFont; }
5235   QColor selectedTextColor() const { return mSelectedTextColor; }
5236   bool selectable() const { return mSelectable; }
5237   bool selected() const { return mSelected; }
5238   
5239   // setters:
5240   void setText(const QString &text);
5241   void setTextFlags(int flags);
5242   void setFont(const QFont &font);
5243   void setTextColor(const QColor &color);
5244   void setSelectedFont(const QFont &font);
5245   void setSelectedTextColor(const QColor &color);
5246   Q_SLOT void setSelectable(bool selectable);
5247   Q_SLOT void setSelected(bool selected);
5248   
5249   // reimplemented virtual methods:
5250   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
5251   virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE;
5252   virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE;
5253   virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE;
5254   
5255 signals:
5256   void selectionChanged(bool selected);
5257   void selectableChanged(bool selectable);
5258   void clicked(QMouseEvent *event);
5259   void doubleClicked(QMouseEvent *event);
5260   
5261 protected:
5262   // property members:
5263   QString mText;
5264   int mTextFlags;
5265   QFont mFont;
5266   QColor mTextColor;
5267   QFont mSelectedFont;
5268   QColor mSelectedTextColor;
5269   QRect mTextBoundingRect;
5270   bool mSelectable, mSelected;
5271   
5272   // reimplemented virtual methods:
5273   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
5274   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
5275   virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE;
5276   virtual QSize maximumOuterSizeHint() const Q_DECL_OVERRIDE;
5277   // events:
5278   virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
5279   virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE;
5280   
5281   // non-virtual methods:
5282   QFont mainFont() const;
5283   QColor mainTextColor() const;
5284   
5285 private:
5286   Q_DISABLE_COPY(QCPTextElement)
5287 };
5288 
5289 
5290 
5291 /* end of 'src/layoutelements/layoutelement-textelement.h' */
5292 
5293 
5294 /* including file 'src/layoutelements/layoutelement-colorscale.h' */
5295 /* modified 2021-03-29T02:30:44, size 5939                        */
5296 
5297 
5298 class QCPColorScaleAxisRectPrivate : public QCPAxisRect
5299 {
5300   Q_OBJECT
5301 public:
5302   explicit QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale);
5303 protected:
5304   QCPColorScale *mParentColorScale;
5305   QImage mGradientImage;
5306   bool mGradientImageInvalidated;
5307   // re-using some methods of QCPAxisRect to make them available to friend class QCPColorScale
5308   using QCPAxisRect::calculateAutoMargin;
5309   using QCPAxisRect::mousePressEvent;
5310   using QCPAxisRect::mouseMoveEvent;
5311   using QCPAxisRect::mouseReleaseEvent;
5312   using QCPAxisRect::wheelEvent;
5313   using QCPAxisRect::update;
5314   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
5315   void updateGradientImage();
5316   Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts);
5317   Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts);
5318   friend class QCPColorScale;
5319 };
5320 
5321 
5322 class QCP_LIB_DECL QCPColorScale : public QCPLayoutElement
5323 {
5324   Q_OBJECT
5325   /// \cond INCLUDE_QPROPERTIES
5326   Q_PROPERTY(QCPAxis::AxisType type READ type WRITE setType)
5327   Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged)
5328   Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged)
5329   Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged)
5330   Q_PROPERTY(QString label READ label WRITE setLabel)
5331   Q_PROPERTY(int barWidth READ barWidth WRITE setBarWidth)
5332   Q_PROPERTY(bool rangeDrag READ rangeDrag WRITE setRangeDrag)
5333   Q_PROPERTY(bool rangeZoom READ rangeZoom WRITE setRangeZoom)
5334   /// \endcond
5335 public:
5336   explicit QCPColorScale(QCustomPlot *parentPlot);
5337   virtual ~QCPColorScale() Q_DECL_OVERRIDE;
5338   
5339   // getters:
5340   QCPAxis *axis() const { return mColorAxis.data(); }
5341   QCPAxis::AxisType type() const { return mType; }
5342   QCPRange dataRange() const { return mDataRange; }
5343   QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; }
5344   QCPColorGradient gradient() const { return mGradient; }
5345   QString label() const;
5346   int barWidth () const { return mBarWidth; }
5347   bool rangeDrag() const;
5348   bool rangeZoom() const;
5349   
5350   // setters:
5351   void setType(QCPAxis::AxisType type);
5352   Q_SLOT void setDataRange(const QCPRange &dataRange);
5353   Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType);
5354   Q_SLOT void setGradient(const QCPColorGradient &gradient);
5355   void setLabel(const QString &str);
5356   void setBarWidth(int width);
5357   void setRangeDrag(bool enabled);
5358   void setRangeZoom(bool enabled);
5359   
5360   // non-property methods:
5361   QList<QCPColorMap*> colorMaps() const;
5362   void rescaleDataRange(bool onlyVisibleMaps);
5363   
5364   // reimplemented virtual methods:
5365   virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE;
5366   
5367 signals:
5368   void dataRangeChanged(const QCPRange &newRange);
5369   void dataScaleTypeChanged(QCPAxis::ScaleType scaleType);
5370   void gradientChanged(const QCPColorGradient &newGradient);
5371 
5372 protected:
5373   // property members:
5374   QCPAxis::AxisType mType;
5375   QCPRange mDataRange;
5376   QCPAxis::ScaleType mDataScaleType;
5377   QCPColorGradient mGradient;
5378   int mBarWidth;
5379   
5380   // non-property members:
5381   QPointer<QCPColorScaleAxisRectPrivate> mAxisRect;
5382   QPointer<QCPAxis> mColorAxis;
5383   
5384   // reimplemented virtual methods:
5385   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
5386   // events:
5387   virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE;
5388   virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE;
5389   virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE;
5390   virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
5391   
5392 private:
5393   Q_DISABLE_COPY(QCPColorScale)
5394   
5395   friend class QCPColorScaleAxisRectPrivate;
5396 };
5397 
5398 
5399 /* end of 'src/layoutelements/layoutelement-colorscale.h' */
5400 
5401 
5402 /* including file 'src/plottables/plottable-graph.h' */
5403 /* modified 2021-03-29T02:30:44, size 9316           */
5404 
5405 class QCP_LIB_DECL QCPGraphData
5406 {
5407 public:
5408   QCPGraphData();
5409   QCPGraphData(double key, double value);
5410   
5411   inline double sortKey() const { return key; }
5412   inline static QCPGraphData fromSortKey(double sortKey) { return QCPGraphData(sortKey, 0); }
5413   inline static bool sortKeyIsMainKey() { return true; }
5414   
5415   inline double mainKey() const { return key; }
5416   inline double mainValue() const { return value; }
5417   
5418   inline QCPRange valueRange() const { return QCPRange(value, value); }
5419   
5420   double key, value;
5421 };
5422 Q_DECLARE_TYPEINFO(QCPGraphData, Q_PRIMITIVE_TYPE);
5423 
5424 
5425 /*! \typedef QCPGraphDataContainer
5426   
5427   Container for storing \ref QCPGraphData points. The data is stored sorted by \a key.
5428   
5429   This template instantiation is the container in which QCPGraph holds its data. For details about
5430   the generic container, see the documentation of the class template \ref QCPDataContainer.
5431   
5432   \see QCPGraphData, QCPGraph::setData
5433 */
5434 typedef QCPDataContainer<QCPGraphData> QCPGraphDataContainer;
5435 
5436 class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable1D<QCPGraphData>
5437 {
5438   Q_OBJECT
5439   /// \cond INCLUDE_QPROPERTIES
5440   Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle)
5441   Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle)
5442   Q_PROPERTY(int scatterSkip READ scatterSkip WRITE setScatterSkip)
5443   Q_PROPERTY(QCPGraph* channelFillGraph READ channelFillGraph WRITE setChannelFillGraph)
5444   Q_PROPERTY(bool adaptiveSampling READ adaptiveSampling WRITE setAdaptiveSampling)
5445   /// \endcond
5446 public:
5447   /*!
5448     Defines how the graph's line is represented visually in the plot. The line is drawn with the
5449     current pen of the graph (\ref setPen).
5450     \see setLineStyle
5451   */
5452   enum LineStyle { lsNone        ///< data points are not connected with any lines (e.g. data only represented
5453                                  ///< with symbols according to the scatter style, see \ref setScatterStyle)
5454                    ,lsLine       ///< data points are connected by a straight line
5455                    ,lsStepLeft   ///< line is drawn as steps where the step height is the value of the left data point
5456                    ,lsStepRight  ///< line is drawn as steps where the step height is the value of the right data point
5457                    ,lsStepCenter ///< line is drawn as steps where the step is in between two data points
5458                    ,lsImpulse    ///< each data point is represented by a line parallel to the value axis, which reaches from the data point to the zero-value-line
5459                  };
5460   Q_ENUMS(LineStyle)
5461   
5462   explicit QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis);
5463   virtual ~QCPGraph() Q_DECL_OVERRIDE;
5464   
5465   // getters:
5466   QSharedPointer<QCPGraphDataContainer> data() const { return mDataContainer; }
5467   LineStyle lineStyle() const { return mLineStyle; }
5468   QCPScatterStyle scatterStyle() const { return mScatterStyle; }
5469   int scatterSkip() const { return mScatterSkip; }
5470   QCPGraph *channelFillGraph() const { return mChannelFillGraph.data(); }
5471   bool adaptiveSampling() const { return mAdaptiveSampling; }
5472   
5473   // setters:
5474   void setData(QSharedPointer<QCPGraphDataContainer> data);
5475   void setData(const QVector<double> &keys, const QVector<double> &values, bool alreadySorted=false);
5476   void setLineStyle(LineStyle ls);
5477   void setScatterStyle(const QCPScatterStyle &style);
5478   void setScatterSkip(int skip);
5479   void setChannelFillGraph(QCPGraph *targetGraph);
5480   void setAdaptiveSampling(bool enabled);
5481   
5482   // non-property methods:
5483   void addData(const QVector<double> &keys, const QVector<double> &values, bool alreadySorted=false);
5484   void addData(double key, double value);
5485   
5486   // reimplemented virtual methods:
5487   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
5488   virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE;
5489   virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE;
5490   
5491 protected:
5492   // property members:
5493   LineStyle mLineStyle;
5494   QCPScatterStyle mScatterStyle;
5495   int mScatterSkip;
5496   QPointer<QCPGraph> mChannelFillGraph;
5497   bool mAdaptiveSampling;
5498   
5499   // reimplemented virtual methods:
5500   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
5501   virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE;
5502   
5503   // introduced virtual methods:
5504   virtual void drawFill(QCPPainter *painter, QVector<QPointF> *lines) const;
5505   virtual void drawScatterPlot(QCPPainter *painter, const QVector<QPointF> &scatters, const QCPScatterStyle &style) const;
5506   virtual void drawLinePlot(QCPPainter *painter, const QVector<QPointF> &lines) const;
5507   virtual void drawImpulsePlot(QCPPainter *painter, const QVector<QPointF> &lines) const;
5508   
5509   virtual void getOptimizedLineData(QVector<QCPGraphData> *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const;
5510   virtual void getOptimizedScatterData(QVector<QCPGraphData> *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const;
5511   
5512   // non-virtual methods:
5513   void getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const;
5514   void getLines(QVector<QPointF> *lines, const QCPDataRange &dataRange) const;
5515   void getScatters(QVector<QPointF> *scatters, const QCPDataRange &dataRange) const;
5516   QVector<QPointF> dataToLines(const QVector<QCPGraphData> &data) const;
5517   QVector<QPointF> dataToStepLeftLines(const QVector<QCPGraphData> &data) const;
5518   QVector<QPointF> dataToStepRightLines(const QVector<QCPGraphData> &data) const;
5519   QVector<QPointF> dataToStepCenterLines(const QVector<QCPGraphData> &data) const;
5520   QVector<QPointF> dataToImpulseLines(const QVector<QCPGraphData> &data) const;
5521   QVector<QCPDataRange> getNonNanSegments(const QVector<QPointF> *lineData, Qt::Orientation keyOrientation) const;
5522   QVector<QPair<QCPDataRange, QCPDataRange> > getOverlappingSegments(QVector<QCPDataRange> thisSegments, const QVector<QPointF> *thisData, QVector<QCPDataRange> otherSegments, const QVector<QPointF> *otherData) const;
5523   bool segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, int &bPrecedence) const;
5524   QPointF getFillBasePoint(QPointF matchingDataPoint) const;
5525   const QPolygonF getFillPolygon(const QVector<QPointF> *lineData, QCPDataRange segment) const;
5526   const QPolygonF getChannelFillPolygon(const QVector<QPointF> *thisData, QCPDataRange thisSegment, const QVector<QPointF> *otherData, QCPDataRange otherSegment) const;
5527   int findIndexBelowX(const QVector<QPointF> *data, double x) const;
5528   int findIndexAboveX(const QVector<QPointF> *data, double x) const;
5529   int findIndexBelowY(const QVector<QPointF> *data, double y) const;
5530   int findIndexAboveY(const QVector<QPointF> *data, double y) const;
5531   double pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const;
5532   
5533   friend class QCustomPlot;
5534   friend class QCPLegend;
5535 };
5536 Q_DECLARE_METATYPE(QCPGraph::LineStyle)
5537 
5538 /* end of 'src/plottables/plottable-graph.h' */
5539 
5540 
5541 /* including file 'src/plottables/plottable-curve.h' */
5542 /* modified 2021-03-29T02:30:44, size 7434           */
5543 
5544 class QCP_LIB_DECL QCPCurveData
5545 {
5546 public:
5547   QCPCurveData();
5548   QCPCurveData(double t, double key, double value);
5549   
5550   inline double sortKey() const { return t; }
5551   inline static QCPCurveData fromSortKey(double sortKey) { return QCPCurveData(sortKey, 0, 0); }
5552   inline static bool sortKeyIsMainKey() { return false; }
5553   
5554   inline double mainKey() const { return key; }
5555   inline double mainValue() const { return value; }
5556   
5557   inline QCPRange valueRange() const { return QCPRange(value, value); }
5558   
5559   double t, key, value;
5560 };
5561 Q_DECLARE_TYPEINFO(QCPCurveData, Q_PRIMITIVE_TYPE);
5562 
5563 
5564 /*! \typedef QCPCurveDataContainer
5565   
5566   Container for storing \ref QCPCurveData points. The data is stored sorted by \a t, so the \a
5567   sortKey() (returning \a t) is different from \a mainKey() (returning \a key).
5568   
5569   This template instantiation is the container in which QCPCurve holds its data. For details about
5570   the generic container, see the documentation of the class template \ref QCPDataContainer.
5571   
5572   \see QCPCurveData, QCPCurve::setData
5573 */
5574 typedef QCPDataContainer<QCPCurveData> QCPCurveDataContainer;
5575 
5576 class QCP_LIB_DECL QCPCurve : public QCPAbstractPlottable1D<QCPCurveData>
5577 {
5578   Q_OBJECT
5579   /// \cond INCLUDE_QPROPERTIES
5580   Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle)
5581   Q_PROPERTY(int scatterSkip READ scatterSkip WRITE setScatterSkip)
5582   Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle)
5583   /// \endcond
5584 public:
5585   /*!
5586     Defines how the curve's line is represented visually in the plot. The line is drawn with the
5587     current pen of the curve (\ref setPen).
5588     \see setLineStyle
5589   */
5590   enum LineStyle { lsNone  ///< No line is drawn between data points (e.g. only scatters)
5591                    ,lsLine ///< Data points are connected with a straight line
5592                  };
5593   Q_ENUMS(LineStyle)
5594   
5595   explicit QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis);
5596   virtual ~QCPCurve() Q_DECL_OVERRIDE;
5597   
5598   // getters:
5599   QSharedPointer<QCPCurveDataContainer> data() const { return mDataContainer; }
5600   QCPScatterStyle scatterStyle() const { return mScatterStyle; }
5601   int scatterSkip() const { return mScatterSkip; }
5602   LineStyle lineStyle() const { return mLineStyle; }
5603   
5604   // setters:
5605   void setData(QSharedPointer<QCPCurveDataContainer> data);
5606   void setData(const QVector<double> &t, const QVector<double> &keys, const QVector<double> &values, bool alreadySorted=false);
5607   void setData(const QVector<double> &keys, const QVector<double> &values);
5608   void setScatterStyle(const QCPScatterStyle &style);
5609   void setScatterSkip(int skip);
5610   void setLineStyle(LineStyle style);
5611   
5612   // non-property methods:
5613   void addData(const QVector<double> &t, const QVector<double> &keys, const QVector<double> &values, bool alreadySorted=false);
5614   void addData(const QVector<double> &keys, const QVector<double> &values);
5615   void addData(double t, double key, double value);
5616   void addData(double key, double value);
5617   
5618   // reimplemented virtual methods:
5619   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
5620   virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE;
5621   virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE;
5622   
5623 protected:
5624   // property members:
5625   QCPScatterStyle mScatterStyle;
5626   int mScatterSkip;
5627   LineStyle mLineStyle;
5628   
5629   // reimplemented virtual methods:
5630   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
5631   virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE;
5632   
5633   // introduced virtual methods:
5634   virtual void drawCurveLine(QCPPainter *painter, const QVector<QPointF> &lines) const;
5635   virtual void drawScatterPlot(QCPPainter *painter, const QVector<QPointF> &points, const QCPScatterStyle &style) const;
5636   
5637   // non-virtual methods:
5638   void getCurveLines(QVector<QPointF> *lines, const QCPDataRange &dataRange, double penWidth) const;
5639   void getScatters(QVector<QPointF> *scatters, const QCPDataRange &dataRange, double scatterWidth) const;
5640   int getRegion(double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const;
5641   QPointF getOptimizedPoint(int otherRegion, double otherKey, double otherValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const;
5642   QVector<QPointF> getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const;
5643   bool mayTraverse(int prevRegion, int currentRegion) const;
5644   bool getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const;
5645   void getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector<QPointF> &beforeTraverse, QVector<QPointF> &afterTraverse) const;
5646   double pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const;
5647   
5648   friend class QCustomPlot;
5649   friend class QCPLegend;
5650 };
5651 Q_DECLARE_METATYPE(QCPCurve::LineStyle)
5652 
5653 /* end of 'src/plottables/plottable-curve.h' */
5654 
5655 
5656 /* including file 'src/plottables/plottable-bars.h' */
5657 /* modified 2021-03-29T02:30:44, size 8955          */
5658 
5659 class QCP_LIB_DECL QCPBarsGroup : public QObject
5660 {
5661   Q_OBJECT
5662   /// \cond INCLUDE_QPROPERTIES
5663   Q_PROPERTY(SpacingType spacingType READ spacingType WRITE setSpacingType)
5664   Q_PROPERTY(double spacing READ spacing WRITE setSpacing)
5665   /// \endcond
5666 public:
5667   /*!
5668     Defines the ways the spacing between bars in the group can be specified. Thus it defines what
5669     the number passed to \ref setSpacing actually means.
5670     
5671     \see setSpacingType, setSpacing
5672   */
5673   enum SpacingType { stAbsolute       ///< Bar spacing is in absolute pixels
5674                      ,stAxisRectRatio ///< Bar spacing is given by a fraction of the axis rect size
5675                      ,stPlotCoords    ///< Bar spacing is in key coordinates and thus scales with the key axis range
5676                    };
5677   Q_ENUMS(SpacingType)
5678   
5679   explicit QCPBarsGroup(QCustomPlot *parentPlot);
5680   virtual ~QCPBarsGroup();
5681   
5682   // getters:
5683   SpacingType spacingType() const { return mSpacingType; }
5684   double spacing() const { return mSpacing; }
5685   
5686   // setters:
5687   void setSpacingType(SpacingType spacingType);
5688   void setSpacing(double spacing);
5689   
5690   // non-virtual methods:
5691   QList<QCPBars*> bars() const { return mBars; }
5692   QCPBars* bars(int index) const;
5693   int size() const { return mBars.size(); }
5694   bool isEmpty() const { return mBars.isEmpty(); }
5695   void clear();
5696   bool contains(QCPBars *bars) const { return mBars.contains(bars); }
5697   void append(QCPBars *bars);
5698   void insert(int i, QCPBars *bars);
5699   void remove(QCPBars *bars);
5700   
5701 protected:
5702   // non-property members:
5703   QCustomPlot *mParentPlot;
5704   SpacingType mSpacingType;
5705   double mSpacing;
5706   QList<QCPBars*> mBars;
5707   
5708   // non-virtual methods:
5709   void registerBars(QCPBars *bars);
5710   void unregisterBars(QCPBars *bars);
5711   
5712   // virtual methods:
5713   double keyPixelOffset(const QCPBars *bars, double keyCoord);
5714   double getPixelSpacing(const QCPBars *bars, double keyCoord);
5715   
5716 private:
5717   Q_DISABLE_COPY(QCPBarsGroup)
5718   
5719   friend class QCPBars;
5720 };
5721 Q_DECLARE_METATYPE(QCPBarsGroup::SpacingType)
5722 
5723 
5724 class QCP_LIB_DECL QCPBarsData
5725 {
5726 public:
5727   QCPBarsData();
5728   QCPBarsData(double key, double value);
5729   
5730   inline double sortKey() const { return key; }
5731   inline static QCPBarsData fromSortKey(double sortKey) { return QCPBarsData(sortKey, 0); }
5732   inline static bool sortKeyIsMainKey() { return true; } 
5733   
5734   inline double mainKey() const { return key; }
5735   inline double mainValue() const { return value; }
5736   
5737   inline QCPRange valueRange() const { return QCPRange(value, value); } // note that bar base value isn't held in each QCPBarsData and thus can't/shouldn't be returned here
5738   
5739   double key, value;
5740 };
5741 Q_DECLARE_TYPEINFO(QCPBarsData, Q_PRIMITIVE_TYPE);
5742 
5743 
5744 /*! \typedef QCPBarsDataContainer
5745   
5746   Container for storing \ref QCPBarsData points. The data is stored sorted by \a key.
5747   
5748   This template instantiation is the container in which QCPBars holds its data. For details about
5749   the generic container, see the documentation of the class template \ref QCPDataContainer.
5750   
5751   \see QCPBarsData, QCPBars::setData
5752 */
5753 typedef QCPDataContainer<QCPBarsData> QCPBarsDataContainer;
5754 
5755 class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable1D<QCPBarsData>
5756 {
5757   Q_OBJECT
5758   /// \cond INCLUDE_QPROPERTIES
5759   Q_PROPERTY(double width READ width WRITE setWidth)
5760   Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType)
5761   Q_PROPERTY(QCPBarsGroup* barsGroup READ barsGroup WRITE setBarsGroup)
5762   Q_PROPERTY(double baseValue READ baseValue WRITE setBaseValue)
5763   Q_PROPERTY(double stackingGap READ stackingGap WRITE setStackingGap)
5764   Q_PROPERTY(QCPBars* barBelow READ barBelow)
5765   Q_PROPERTY(QCPBars* barAbove READ barAbove)
5766   /// \endcond
5767 public:
5768   /*!
5769     Defines the ways the width of the bar can be specified. Thus it defines what the number passed
5770     to \ref setWidth actually means.
5771     
5772     \see setWidthType, setWidth
5773   */
5774   enum WidthType { wtAbsolute       ///< Bar width is in absolute pixels
5775                    ,wtAxisRectRatio ///< Bar width is given by a fraction of the axis rect size
5776                    ,wtPlotCoords    ///< Bar width is in key coordinates and thus scales with the key axis range
5777                  };
5778   Q_ENUMS(WidthType)
5779   
5780   explicit QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis);
5781   virtual ~QCPBars() Q_DECL_OVERRIDE;
5782   
5783   // getters:
5784   double width() const { return mWidth; }
5785   WidthType widthType() const { return mWidthType; }
5786   QCPBarsGroup *barsGroup() const { return mBarsGroup; }
5787   double baseValue() const { return mBaseValue; }
5788   double stackingGap() const { return mStackingGap; }
5789   QCPBars *barBelow() const { return mBarBelow.data(); }
5790   QCPBars *barAbove() const { return mBarAbove.data(); }
5791   QSharedPointer<QCPBarsDataContainer> data() const { return mDataContainer; }
5792   
5793   // setters:
5794   void setData(QSharedPointer<QCPBarsDataContainer> data);
5795   void setData(const QVector<double> &keys, const QVector<double> &values, bool alreadySorted=false);
5796   void setWidth(double width);
5797   void setWidthType(WidthType widthType);
5798   void setBarsGroup(QCPBarsGroup *barsGroup);
5799   void setBaseValue(double baseValue);
5800   void setStackingGap(double pixels);
5801   
5802   // non-property methods:
5803   void addData(const QVector<double> &keys, const QVector<double> &values, bool alreadySorted=false);
5804   void addData(double key, double value);
5805   void moveBelow(QCPBars *bars);
5806   void moveAbove(QCPBars *bars);
5807   
5808   // reimplemented virtual methods:
5809   virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE;
5810   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
5811   virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE;
5812   virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE;
5813   virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE;
5814   
5815 protected:
5816   // property members:
5817   double mWidth;
5818   WidthType mWidthType;
5819   QCPBarsGroup *mBarsGroup;
5820   double mBaseValue;
5821   double mStackingGap;
5822   QPointer<QCPBars> mBarBelow, mBarAbove;
5823   
5824   // reimplemented virtual methods:
5825   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
5826   virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE;
5827   
5828   // non-virtual methods:
5829   void getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const;
5830   QRectF getBarRect(double key, double value) const;
5831   void getPixelWidth(double key, double &lower, double &upper) const;
5832   double getStackedBaseValue(double key, bool positive) const;
5833   static void connectBars(QCPBars* lower, QCPBars* upper);
5834   
5835   friend class QCustomPlot;
5836   friend class QCPLegend;
5837   friend class QCPBarsGroup;
5838 };
5839 Q_DECLARE_METATYPE(QCPBars::WidthType)
5840 
5841 /* end of 'src/plottables/plottable-bars.h' */
5842 
5843 
5844 /* including file 'src/plottables/plottable-statisticalbox.h' */
5845 /* modified 2021-03-29T02:30:44, size 7522                    */
5846 
5847 class QCP_LIB_DECL QCPStatisticalBoxData
5848 {
5849 public:
5850   QCPStatisticalBoxData();
5851   QCPStatisticalBoxData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector<double>& outliers=QVector<double>());
5852   
5853   inline double sortKey() const { return key; }
5854   inline static QCPStatisticalBoxData fromSortKey(double sortKey) { return QCPStatisticalBoxData(sortKey, 0, 0, 0, 0, 0); }
5855   inline static bool sortKeyIsMainKey() { return true; }
5856   
5857   inline double mainKey() const { return key; }
5858   inline double mainValue() const { return median; }
5859   
5860   inline QCPRange valueRange() const
5861   {
5862     QCPRange result(minimum, maximum);
5863     for (QVector<double>::const_iterator it = outliers.constBegin(); it != outliers.constEnd(); ++it)
5864       result.expand(*it);
5865     return result;
5866   }
5867   
5868   double key, minimum, lowerQuartile, median, upperQuartile, maximum;
5869   QVector<double> outliers;
5870 };
5871 Q_DECLARE_TYPEINFO(QCPStatisticalBoxData, Q_MOVABLE_TYPE);
5872 
5873 
5874 /*! \typedef QCPStatisticalBoxDataContainer
5875   
5876   Container for storing \ref QCPStatisticalBoxData points. The data is stored sorted by \a key.
5877   
5878   This template instantiation is the container in which QCPStatisticalBox holds its data. For
5879   details about the generic container, see the documentation of the class template \ref
5880   QCPDataContainer.
5881   
5882   \see QCPStatisticalBoxData, QCPStatisticalBox::setData
5883 */
5884 typedef QCPDataContainer<QCPStatisticalBoxData> QCPStatisticalBoxDataContainer;
5885 
5886 class QCP_LIB_DECL QCPStatisticalBox : public QCPAbstractPlottable1D<QCPStatisticalBoxData>
5887 {
5888   Q_OBJECT
5889   /// \cond INCLUDE_QPROPERTIES
5890   Q_PROPERTY(double width READ width WRITE setWidth)
5891   Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth)
5892   Q_PROPERTY(QPen whiskerPen READ whiskerPen WRITE setWhiskerPen)
5893   Q_PROPERTY(QPen whiskerBarPen READ whiskerBarPen WRITE setWhiskerBarPen)
5894   Q_PROPERTY(bool whiskerAntialiased READ whiskerAntialiased WRITE setWhiskerAntialiased)
5895   Q_PROPERTY(QPen medianPen READ medianPen WRITE setMedianPen)
5896   Q_PROPERTY(QCPScatterStyle outlierStyle READ outlierStyle WRITE setOutlierStyle)
5897   /// \endcond
5898 public:
5899   explicit QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis);
5900   
5901   // getters:
5902   QSharedPointer<QCPStatisticalBoxDataContainer> data() const { return mDataContainer; }
5903   double width() const { return mWidth; }
5904   double whiskerWidth() const { return mWhiskerWidth; }
5905   QPen whiskerPen() const { return mWhiskerPen; }
5906   QPen whiskerBarPen() const { return mWhiskerBarPen; }
5907   bool whiskerAntialiased() const { return mWhiskerAntialiased; }
5908   QPen medianPen() const { return mMedianPen; }
5909   QCPScatterStyle outlierStyle() const { return mOutlierStyle; }
5910 
5911   // setters:
5912   void setData(QSharedPointer<QCPStatisticalBoxDataContainer> data);
5913   void setData(const QVector<double> &keys, const QVector<double> &minimum, const QVector<double> &lowerQuartile, const QVector<double> &median, const QVector<double> &upperQuartile, const QVector<double> &maximum, bool alreadySorted=false);
5914   void setWidth(double width);
5915   void setWhiskerWidth(double width);
5916   void setWhiskerPen(const QPen &pen);
5917   void setWhiskerBarPen(const QPen &pen);
5918   void setWhiskerAntialiased(bool enabled);
5919   void setMedianPen(const QPen &pen);
5920   void setOutlierStyle(const QCPScatterStyle &style);
5921   
5922   // non-property methods:
5923   void addData(const QVector<double> &keys, const QVector<double> &minimum, const QVector<double> &lowerQuartile, const QVector<double> &median, const QVector<double> &upperQuartile, const QVector<double> &maximum, bool alreadySorted=false);
5924   void addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector<double> &outliers=QVector<double>());
5925   
5926   // reimplemented virtual methods:
5927   virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE;
5928   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
5929   virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE;
5930   virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE;
5931   
5932 protected:
5933   // property members:
5934   double mWidth;
5935   double mWhiskerWidth;
5936   QPen mWhiskerPen, mWhiskerBarPen;
5937   bool mWhiskerAntialiased;
5938   QPen mMedianPen;
5939   QCPScatterStyle mOutlierStyle;
5940   
5941   // reimplemented virtual methods:
5942   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
5943   virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE;
5944   
5945   // introduced virtual methods:
5946   virtual void drawStatisticalBox(QCPPainter *painter, QCPStatisticalBoxDataContainer::const_iterator it, const QCPScatterStyle &outlierStyle) const;
5947   
5948   // non-virtual methods:
5949   void getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, QCPStatisticalBoxDataContainer::const_iterator &end) const;
5950   QRectF getQuartileBox(QCPStatisticalBoxDataContainer::const_iterator it) const;
5951   QVector<QLineF> getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const;
5952   QVector<QLineF> getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const;
5953   
5954   friend class QCustomPlot;
5955   friend class QCPLegend;
5956 };
5957 
5958 /* end of 'src/plottables/plottable-statisticalbox.h' */
5959 
5960 
5961 /* including file 'src/plottables/plottable-colormap.h' */
5962 /* modified 2021-03-29T02:30:44, size 7092              */
5963 
5964 class QCP_LIB_DECL QCPColorMapData
5965 {
5966 public:
5967   QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange);
5968   ~QCPColorMapData();
5969   QCPColorMapData(const QCPColorMapData &other);
5970   QCPColorMapData &operator=(const QCPColorMapData &other);
5971   
5972   // getters:
5973   int keySize() const { return mKeySize; }
5974   int valueSize() const { return mValueSize; }
5975   QCPRange keyRange() const { return mKeyRange; }
5976   QCPRange valueRange() const { return mValueRange; }
5977   QCPRange dataBounds() const { return mDataBounds; }
5978   double data(double key, double value);
5979   double cell(int keyIndex, int valueIndex);
5980   unsigned char alpha(int keyIndex, int valueIndex);
5981   
5982   // setters:
5983   void setSize(int keySize, int valueSize);
5984   void setKeySize(int keySize);
5985   void setValueSize(int valueSize);
5986   void setRange(const QCPRange &keyRange, const QCPRange &valueRange);
5987   void setKeyRange(const QCPRange &keyRange);
5988   void setValueRange(const QCPRange &valueRange);
5989   void setData(double key, double value, double z);
5990   void setCell(int keyIndex, int valueIndex, double z);
5991   void setAlpha(int keyIndex, int valueIndex, unsigned char alpha);
5992   
5993   // non-property methods:
5994   void recalculateDataBounds();
5995   void clear();
5996   void clearAlpha();
5997   void fill(double z);
5998   void fillAlpha(unsigned char alpha);
5999   bool isEmpty() const { return mIsEmpty; }
6000   void coordToCell(double key, double value, int *keyIndex, int *valueIndex) const;
6001   void cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const;
6002   
6003 protected:
6004   // property members:
6005   int mKeySize, mValueSize;
6006   QCPRange mKeyRange, mValueRange;
6007   bool mIsEmpty;
6008   
6009   // non-property members:
6010   double *mData;
6011   unsigned char *mAlpha;
6012   QCPRange mDataBounds;
6013   bool mDataModified;
6014   
6015   bool createAlpha(bool initializeOpaque=true);
6016   
6017   friend class QCPColorMap;
6018 };
6019 
6020 
6021 class QCP_LIB_DECL QCPColorMap : public QCPAbstractPlottable
6022 {
6023   Q_OBJECT
6024   /// \cond INCLUDE_QPROPERTIES
6025   Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged)
6026   Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged)
6027   Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged)
6028   Q_PROPERTY(bool interpolate READ interpolate WRITE setInterpolate)
6029   Q_PROPERTY(bool tightBoundary READ tightBoundary WRITE setTightBoundary)
6030   Q_PROPERTY(QCPColorScale* colorScale READ colorScale WRITE setColorScale)
6031   /// \endcond
6032 public:
6033   explicit QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis);
6034   virtual ~QCPColorMap() Q_DECL_OVERRIDE;
6035   
6036   // getters:
6037   QCPColorMapData *data() const { return mMapData; }
6038   QCPRange dataRange() const { return mDataRange; }
6039   QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; }
6040   bool interpolate() const { return mInterpolate; }
6041   bool tightBoundary() const { return mTightBoundary; }
6042   QCPColorGradient gradient() const { return mGradient; }
6043   QCPColorScale *colorScale() const { return mColorScale.data(); }
6044   
6045   // setters:
6046   void setData(QCPColorMapData *data, bool copy=false);
6047   Q_SLOT void setDataRange(const QCPRange &dataRange);
6048   Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType);
6049   Q_SLOT void setGradient(const QCPColorGradient &gradient);
6050   void setInterpolate(bool enabled);
6051   void setTightBoundary(bool enabled);
6052   void setColorScale(QCPColorScale *colorScale);
6053   
6054   // non-property methods:
6055   void rescaleDataRange(bool recalculateDataBounds=false);
6056   Q_SLOT void updateLegendIcon(Qt::TransformationMode transformMode=Qt::SmoothTransformation, const QSize &thumbSize=QSize(32, 18));
6057   
6058   // reimplemented virtual methods:
6059   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
6060   virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE;
6061   virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE;
6062   
6063 signals:
6064   void dataRangeChanged(const QCPRange &newRange);
6065   void dataScaleTypeChanged(QCPAxis::ScaleType scaleType);
6066   void gradientChanged(const QCPColorGradient &newGradient);
6067   
6068 protected:
6069   // property members:
6070   QCPRange mDataRange;
6071   QCPAxis::ScaleType mDataScaleType;
6072   QCPColorMapData *mMapData;
6073   QCPColorGradient mGradient;
6074   bool mInterpolate;
6075   bool mTightBoundary;
6076   QPointer<QCPColorScale> mColorScale;
6077   
6078   // non-property members:
6079   QImage mMapImage, mUndersampledMapImage;
6080   QPixmap mLegendIcon;
6081   bool mMapImageInvalidated;
6082   
6083   // introduced virtual methods:
6084   virtual void updateMapImage();
6085   
6086   // reimplemented virtual methods:
6087   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
6088   virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE;
6089   
6090   friend class QCustomPlot;
6091   friend class QCPLegend;
6092 };
6093 
6094 /* end of 'src/plottables/plottable-colormap.h' */
6095 
6096 
6097 /* including file 'src/plottables/plottable-financial.h' */
6098 /* modified 2021-03-29T02:30:44, size 8644               */
6099 
6100 class QCP_LIB_DECL QCPFinancialData
6101 {
6102 public:
6103   QCPFinancialData();
6104   QCPFinancialData(double key, double open, double high, double low, double close);
6105   
6106   inline double sortKey() const { return key; }
6107   inline static QCPFinancialData fromSortKey(double sortKey) { return QCPFinancialData(sortKey, 0, 0, 0, 0); }
6108   inline static bool sortKeyIsMainKey() { return true; } 
6109   
6110   inline double mainKey() const { return key; }
6111   inline double mainValue() const { return open; }
6112   
6113   inline QCPRange valueRange() const { return QCPRange(low, high); } // open and close must lie between low and high, so we don't need to check them
6114   
6115   double key, open, high, low, close;
6116 };
6117 Q_DECLARE_TYPEINFO(QCPFinancialData, Q_PRIMITIVE_TYPE);
6118 
6119 
6120 /*! \typedef QCPFinancialDataContainer
6121   
6122   Container for storing \ref QCPFinancialData points. The data is stored sorted by \a key.
6123   
6124   This template instantiation is the container in which QCPFinancial holds its data. For details
6125   about the generic container, see the documentation of the class template \ref QCPDataContainer.
6126   
6127   \see QCPFinancialData, QCPFinancial::setData
6128 */
6129 typedef QCPDataContainer<QCPFinancialData> QCPFinancialDataContainer;
6130 
6131 class QCP_LIB_DECL QCPFinancial : public QCPAbstractPlottable1D<QCPFinancialData>
6132 {
6133   Q_OBJECT
6134   /// \cond INCLUDE_QPROPERTIES
6135   Q_PROPERTY(ChartStyle chartStyle READ chartStyle WRITE setChartStyle)
6136   Q_PROPERTY(double width READ width WRITE setWidth)
6137   Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType)
6138   Q_PROPERTY(bool twoColored READ twoColored WRITE setTwoColored)
6139   Q_PROPERTY(QBrush brushPositive READ brushPositive WRITE setBrushPositive)
6140   Q_PROPERTY(QBrush brushNegative READ brushNegative WRITE setBrushNegative)
6141   Q_PROPERTY(QPen penPositive READ penPositive WRITE setPenPositive)
6142   Q_PROPERTY(QPen penNegative READ penNegative WRITE setPenNegative)
6143   /// \endcond
6144 public:
6145   /*!
6146     Defines the ways the width of the financial bar can be specified. Thus it defines what the
6147     number passed to \ref setWidth actually means.
6148 
6149     \see setWidthType, setWidth
6150   */
6151   enum WidthType { wtAbsolute       ///< width is in absolute pixels
6152                    ,wtAxisRectRatio ///< width is given by a fraction of the axis rect size
6153                    ,wtPlotCoords    ///< width is in key coordinates and thus scales with the key axis range
6154                  };
6155   Q_ENUMS(WidthType)
6156   
6157   /*!
6158     Defines the possible representations of OHLC data in the plot.
6159     
6160     \see setChartStyle
6161   */
6162   enum ChartStyle { csOhlc         ///< Open-High-Low-Close bar representation
6163                    ,csCandlestick  ///< Candlestick representation
6164                   };
6165   Q_ENUMS(ChartStyle)
6166   
6167   explicit QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis);
6168   virtual ~QCPFinancial() Q_DECL_OVERRIDE;
6169   
6170   // getters:
6171   QSharedPointer<QCPFinancialDataContainer> data() const { return mDataContainer; }
6172   ChartStyle chartStyle() const { return mChartStyle; }
6173   double width() const { return mWidth; }
6174   WidthType widthType() const { return mWidthType; }
6175   bool twoColored() const { return mTwoColored; }
6176   QBrush brushPositive() const { return mBrushPositive; }
6177   QBrush brushNegative() const { return mBrushNegative; }
6178   QPen penPositive() const { return mPenPositive; }
6179   QPen penNegative() const { return mPenNegative; }
6180   
6181   // setters:
6182   void setData(QSharedPointer<QCPFinancialDataContainer> data);
6183   void setData(const QVector<double> &keys, const QVector<double> &open, const QVector<double> &high, const QVector<double> &low, const QVector<double> &close, bool alreadySorted=false);
6184   void setChartStyle(ChartStyle style);
6185   void setWidth(double width);
6186   void setWidthType(WidthType widthType);
6187   void setTwoColored(bool twoColored);
6188   void setBrushPositive(const QBrush &brush);
6189   void setBrushNegative(const QBrush &brush);
6190   void setPenPositive(const QPen &pen);
6191   void setPenNegative(const QPen &pen);
6192   
6193   // non-property methods:
6194   void addData(const QVector<double> &keys, const QVector<double> &open, const QVector<double> &high, const QVector<double> &low, const QVector<double> &close, bool alreadySorted=false);
6195   void addData(double key, double open, double high, double low, double close);
6196   
6197   // reimplemented virtual methods:
6198   virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE;
6199   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
6200   virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE;
6201   virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE;
6202   
6203   // static methods:
6204   static QCPFinancialDataContainer timeSeriesToOhlc(const QVector<double> &time, const QVector<double> &value, double timeBinSize, double timeBinOffset = 0);
6205   
6206 protected:
6207   // property members:
6208   ChartStyle mChartStyle;
6209   double mWidth;
6210   WidthType mWidthType;
6211   bool mTwoColored;
6212   QBrush mBrushPositive, mBrushNegative;
6213   QPen mPenPositive, mPenNegative;
6214   
6215   // reimplemented virtual methods:
6216   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
6217   virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE;
6218   
6219   // non-virtual methods:
6220   void drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected);
6221   void drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected);
6222   double getPixelWidth(double key, double keyPixel) const;
6223   double ohlcSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const;
6224   double candlestickSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const;
6225   void getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const;
6226   QRectF selectionHitBox(QCPFinancialDataContainer::const_iterator it) const;
6227   
6228   friend class QCustomPlot;
6229   friend class QCPLegend;
6230 };
6231 Q_DECLARE_METATYPE(QCPFinancial::ChartStyle)
6232 
6233 /* end of 'src/plottables/plottable-financial.h' */
6234 
6235 
6236 /* including file 'src/plottables/plottable-errorbar.h' */
6237 /* modified 2021-03-29T02:30:44, size 7749              */
6238 
6239 class QCP_LIB_DECL QCPErrorBarsData
6240 {
6241 public:
6242   QCPErrorBarsData();
6243   explicit QCPErrorBarsData(double error);
6244   QCPErrorBarsData(double errorMinus, double errorPlus);
6245   
6246   double errorMinus, errorPlus;
6247 };
6248 Q_DECLARE_TYPEINFO(QCPErrorBarsData, Q_PRIMITIVE_TYPE);
6249 
6250 
6251 /*! \typedef QCPErrorBarsDataContainer
6252 
6253   Container for storing \ref QCPErrorBarsData points. It is a typedef for <tt>QVector<\ref
6254   QCPErrorBarsData></tt>.
6255 
6256   This is the container in which \ref QCPErrorBars holds its data. Unlike most other data
6257   containers for plottables, it is not based on \ref QCPDataContainer. This is because the error
6258   bars plottable is special in that it doesn't store its own key and value coordinate per error
6259   bar. It adopts the key and value from the plottable to which the error bars shall be applied
6260   (\ref QCPErrorBars::setDataPlottable). So the stored \ref QCPErrorBarsData doesn't need a
6261   sortable key, but merely an index (as \c QVector provides), which maps one-to-one to the indices
6262   of the other plottable's data.
6263 
6264   \see QCPErrorBarsData, QCPErrorBars::setData
6265 */
6266 typedef QVector<QCPErrorBarsData> QCPErrorBarsDataContainer;
6267 
6268 class QCP_LIB_DECL QCPErrorBars : public QCPAbstractPlottable, public QCPPlottableInterface1D
6269 {
6270   Q_OBJECT
6271   /// \cond INCLUDE_QPROPERTIES
6272   Q_PROPERTY(QSharedPointer<QCPErrorBarsDataContainer> data READ data WRITE setData)
6273   Q_PROPERTY(QCPAbstractPlottable* dataPlottable READ dataPlottable WRITE setDataPlottable)
6274   Q_PROPERTY(ErrorType errorType READ errorType WRITE setErrorType)
6275   Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth)
6276   Q_PROPERTY(double symbolGap READ symbolGap WRITE setSymbolGap)
6277   /// \endcond
6278 public:
6279   
6280   /*!
6281     Defines in which orientation the error bars shall appear. If your data needs both error
6282     dimensions, create two \ref QCPErrorBars with different \ref ErrorType.
6283 
6284     \see setErrorType
6285   */
6286   enum ErrorType { etKeyError    ///< The errors are for the key dimension (bars appear parallel to the key axis)
6287                    ,etValueError ///< The errors are for the value dimension (bars appear parallel to the value axis)
6288   };
6289   Q_ENUMS(ErrorType)
6290   
6291   explicit QCPErrorBars(QCPAxis *keyAxis, QCPAxis *valueAxis);
6292   virtual ~QCPErrorBars() Q_DECL_OVERRIDE;
6293   // getters:
6294   QSharedPointer<QCPErrorBarsDataContainer> data() const { return mDataContainer; }
6295   QCPAbstractPlottable *dataPlottable() const { return mDataPlottable.data(); }
6296   ErrorType errorType() const { return mErrorType; }
6297   double whiskerWidth() const { return mWhiskerWidth; }
6298   double symbolGap() const { return mSymbolGap; }
6299   
6300   // setters:
6301   void setData(QSharedPointer<QCPErrorBarsDataContainer> data);
6302   void setData(const QVector<double> &error);
6303   void setData(const QVector<double> &errorMinus, const QVector<double> &errorPlus);
6304   void setDataPlottable(QCPAbstractPlottable* plottable);
6305   void setErrorType(ErrorType type);
6306   void setWhiskerWidth(double pixels);
6307   void setSymbolGap(double pixels);
6308   
6309   // non-property methods:
6310   void addData(const QVector<double> &error);
6311   void addData(const QVector<double> &errorMinus, const QVector<double> &errorPlus);
6312   void addData(double error);
6313   void addData(double errorMinus, double errorPlus);
6314   
6315   // virtual methods of 1d plottable interface:
6316   virtual int dataCount() const Q_DECL_OVERRIDE;
6317   virtual double dataMainKey(int index) const Q_DECL_OVERRIDE;
6318   virtual double dataSortKey(int index) const Q_DECL_OVERRIDE;
6319   virtual double dataMainValue(int index) const Q_DECL_OVERRIDE;
6320   virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE;
6321   virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE;
6322   virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE;
6323   virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE;
6324   virtual int findBegin(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE;
6325   virtual int findEnd(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE;
6326   
6327   // reimplemented virtual methods:
6328   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
6329   virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; }
6330   
6331 protected:
6332   // property members:
6333   QSharedPointer<QCPErrorBarsDataContainer> mDataContainer;
6334   QPointer<QCPAbstractPlottable> mDataPlottable;
6335   ErrorType mErrorType;
6336   double mWhiskerWidth;
6337   double mSymbolGap;
6338   
6339   // reimplemented virtual methods:
6340   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
6341   virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE;
6342   virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const Q_DECL_OVERRIDE;
6343   virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const Q_DECL_OVERRIDE;
6344   
6345   // non-virtual methods:
6346   void getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector<QLineF> &backbones, QVector<QLineF> &whiskers) const;
6347   void getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterator &begin, QCPErrorBarsDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const;
6348   double pointDistance(const QPointF &pixelPoint, QCPErrorBarsDataContainer::const_iterator &closestData) const;
6349   // helpers:
6350   void getDataSegments(QList<QCPDataRange> &selectedSegments, QList<QCPDataRange> &unselectedSegments) const;
6351   bool errorBarVisible(int index) const;
6352   bool rectIntersectsLine(const QRectF &pixelRect, const QLineF &line) const;
6353   
6354   friend class QCustomPlot;
6355   friend class QCPLegend;
6356 };
6357 
6358 /* end of 'src/plottables/plottable-errorbar.h' */
6359 
6360 
6361 /* including file 'src/items/item-straightline.h' */
6362 /* modified 2021-03-29T02:30:44, size 3137        */
6363 
6364 class QCP_LIB_DECL QCPItemStraightLine : public QCPAbstractItem
6365 {
6366   Q_OBJECT
6367   /// \cond INCLUDE_QPROPERTIES
6368   Q_PROPERTY(QPen pen READ pen WRITE setPen)
6369   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
6370   /// \endcond
6371 public:
6372   explicit QCPItemStraightLine(QCustomPlot *parentPlot);
6373   virtual ~QCPItemStraightLine() Q_DECL_OVERRIDE;
6374   
6375   // getters:
6376   QPen pen() const { return mPen; }
6377   QPen selectedPen() const { return mSelectedPen; }
6378   
6379   // setters;
6380   void setPen(const QPen &pen);
6381   void setSelectedPen(const QPen &pen);
6382   
6383   // reimplemented virtual methods:
6384   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
6385   
6386   QCPItemPosition * const point1;
6387   QCPItemPosition * const point2;
6388   
6389 protected:
6390   // property members:
6391   QPen mPen, mSelectedPen;
6392   
6393   // reimplemented virtual methods:
6394   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
6395   
6396   // non-virtual methods:
6397   QLineF getRectClippedStraightLine(const QCPVector2D &base, const QCPVector2D &vec, const QRect &rect) const;
6398   QPen mainPen() const;
6399 };
6400 
6401 /* end of 'src/items/item-straightline.h' */
6402 
6403 
6404 /* including file 'src/items/item-line.h'  */
6405 /* modified 2021-03-29T02:30:44, size 3429 */
6406 
6407 class QCP_LIB_DECL QCPItemLine : public QCPAbstractItem
6408 {
6409   Q_OBJECT
6410   /// \cond INCLUDE_QPROPERTIES
6411   Q_PROPERTY(QPen pen READ pen WRITE setPen)
6412   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
6413   Q_PROPERTY(QCPLineEnding head READ head WRITE setHead)
6414   Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail)
6415   /// \endcond
6416 public:
6417   explicit QCPItemLine(QCustomPlot *parentPlot);
6418   virtual ~QCPItemLine() Q_DECL_OVERRIDE;
6419   
6420   // getters:
6421   QPen pen() const { return mPen; }
6422   QPen selectedPen() const { return mSelectedPen; }
6423   QCPLineEnding head() const { return mHead; }
6424   QCPLineEnding tail() const { return mTail; }
6425   
6426   // setters;
6427   void setPen(const QPen &pen);
6428   void setSelectedPen(const QPen &pen);
6429   void setHead(const QCPLineEnding &head);
6430   void setTail(const QCPLineEnding &tail);
6431   
6432   // reimplemented virtual methods:
6433   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
6434   
6435   QCPItemPosition * const start;
6436   QCPItemPosition * const end;
6437   
6438 protected:
6439   // property members:
6440   QPen mPen, mSelectedPen;
6441   QCPLineEnding mHead, mTail;
6442   
6443   // reimplemented virtual methods:
6444   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
6445   
6446   // non-virtual methods:
6447   QLineF getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, const QRect &rect) const;
6448   QPen mainPen() const;
6449 };
6450 
6451 /* end of 'src/items/item-line.h' */
6452 
6453 
6454 /* including file 'src/items/item-curve.h' */
6455 /* modified 2021-03-29T02:30:44, size 3401 */
6456 
6457 class QCP_LIB_DECL QCPItemCurve : public QCPAbstractItem
6458 {
6459   Q_OBJECT
6460   /// \cond INCLUDE_QPROPERTIES
6461   Q_PROPERTY(QPen pen READ pen WRITE setPen)
6462   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
6463   Q_PROPERTY(QCPLineEnding head READ head WRITE setHead)
6464   Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail)
6465   /// \endcond
6466 public:
6467   explicit QCPItemCurve(QCustomPlot *parentPlot);
6468   virtual ~QCPItemCurve() Q_DECL_OVERRIDE;
6469   
6470   // getters:
6471   QPen pen() const { return mPen; }
6472   QPen selectedPen() const { return mSelectedPen; }
6473   QCPLineEnding head() const { return mHead; }
6474   QCPLineEnding tail() const { return mTail; }
6475   
6476   // setters;
6477   void setPen(const QPen &pen);
6478   void setSelectedPen(const QPen &pen);
6479   void setHead(const QCPLineEnding &head);
6480   void setTail(const QCPLineEnding &tail);
6481   
6482   // reimplemented virtual methods:
6483   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
6484   
6485   QCPItemPosition * const start;
6486   QCPItemPosition * const startDir;
6487   QCPItemPosition * const endDir;
6488   QCPItemPosition * const end;
6489   
6490 protected:
6491   // property members:
6492   QPen mPen, mSelectedPen;
6493   QCPLineEnding mHead, mTail;
6494   
6495   // reimplemented virtual methods:
6496   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
6497   
6498   // non-virtual methods:
6499   QPen mainPen() const;
6500 };
6501 
6502 /* end of 'src/items/item-curve.h' */
6503 
6504 
6505 /* including file 'src/items/item-rect.h'  */
6506 /* modified 2021-03-29T02:30:44, size 3710 */
6507 
6508 class QCP_LIB_DECL QCPItemRect : public QCPAbstractItem
6509 {
6510   Q_OBJECT
6511   /// \cond INCLUDE_QPROPERTIES
6512   Q_PROPERTY(QPen pen READ pen WRITE setPen)
6513   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
6514   Q_PROPERTY(QBrush brush READ brush WRITE setBrush)
6515   Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush)
6516   /// \endcond
6517 public:
6518   explicit QCPItemRect(QCustomPlot *parentPlot);
6519   virtual ~QCPItemRect() Q_DECL_OVERRIDE;
6520   
6521   // getters:
6522   QPen pen() const { return mPen; }
6523   QPen selectedPen() const { return mSelectedPen; }
6524   QBrush brush() const { return mBrush; }
6525   QBrush selectedBrush() const { return mSelectedBrush; }
6526   
6527   // setters;
6528   void setPen(const QPen &pen);
6529   void setSelectedPen(const QPen &pen);
6530   void setBrush(const QBrush &brush);
6531   void setSelectedBrush(const QBrush &brush);
6532   
6533   // reimplemented virtual methods:
6534   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
6535   
6536   QCPItemPosition * const topLeft;
6537   QCPItemPosition * const bottomRight;
6538   QCPItemAnchor * const top;
6539   QCPItemAnchor * const topRight;
6540   QCPItemAnchor * const right;
6541   QCPItemAnchor * const bottom;
6542   QCPItemAnchor * const bottomLeft;
6543   QCPItemAnchor * const left;
6544   
6545 protected:
6546   enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft};
6547   
6548   // property members:
6549   QPen mPen, mSelectedPen;
6550   QBrush mBrush, mSelectedBrush;
6551   
6552   // reimplemented virtual methods:
6553   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
6554   virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE;
6555   
6556   // non-virtual methods:
6557   QPen mainPen() const;
6558   QBrush mainBrush() const;
6559 };
6560 
6561 /* end of 'src/items/item-rect.h' */
6562 
6563 
6564 /* including file 'src/items/item-text.h'  */
6565 /* modified 2021-03-29T02:30:44, size 5576 */
6566 
6567 class QCP_LIB_DECL QCPItemText : public QCPAbstractItem
6568 {
6569   Q_OBJECT
6570   /// \cond INCLUDE_QPROPERTIES
6571   Q_PROPERTY(QColor color READ color WRITE setColor)
6572   Q_PROPERTY(QColor selectedColor READ selectedColor WRITE setSelectedColor)
6573   Q_PROPERTY(QPen pen READ pen WRITE setPen)
6574   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
6575   Q_PROPERTY(QBrush brush READ brush WRITE setBrush)
6576   Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush)
6577   Q_PROPERTY(QFont font READ font WRITE setFont)
6578   Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont)
6579   Q_PROPERTY(QString text READ text WRITE setText)
6580   Q_PROPERTY(Qt::Alignment positionAlignment READ positionAlignment WRITE setPositionAlignment)
6581   Q_PROPERTY(Qt::Alignment textAlignment READ textAlignment WRITE setTextAlignment)
6582   Q_PROPERTY(double rotation READ rotation WRITE setRotation)
6583   Q_PROPERTY(QMargins padding READ padding WRITE setPadding)
6584   /// \endcond
6585 public:
6586   explicit QCPItemText(QCustomPlot *parentPlot);
6587   virtual ~QCPItemText() Q_DECL_OVERRIDE;
6588   
6589   // getters:
6590   QColor color() const { return mColor; }
6591   QColor selectedColor() const { return mSelectedColor; }
6592   QPen pen() const { return mPen; }
6593   QPen selectedPen() const { return mSelectedPen; }
6594   QBrush brush() const { return mBrush; }
6595   QBrush selectedBrush() const { return mSelectedBrush; }
6596   QFont font() const { return mFont; }
6597   QFont selectedFont() const { return mSelectedFont; }
6598   QString text() const { return mText; }
6599   Qt::Alignment positionAlignment() const { return mPositionAlignment; }
6600   Qt::Alignment textAlignment() const { return mTextAlignment; }
6601   double rotation() const { return mRotation; }
6602   QMargins padding() const { return mPadding; }
6603   
6604   // setters;
6605   void setColor(const QColor &color);
6606   void setSelectedColor(const QColor &color);
6607   void setPen(const QPen &pen);
6608   void setSelectedPen(const QPen &pen);
6609   void setBrush(const QBrush &brush);
6610   void setSelectedBrush(const QBrush &brush);
6611   void setFont(const QFont &font);
6612   void setSelectedFont(const QFont &font);
6613   void setText(const QString &text);
6614   void setPositionAlignment(Qt::Alignment alignment);
6615   void setTextAlignment(Qt::Alignment alignment);
6616   void setRotation(double degrees);
6617   void setPadding(const QMargins &padding);
6618   
6619   // reimplemented virtual methods:
6620   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
6621   
6622   QCPItemPosition * const position;
6623   QCPItemAnchor * const topLeft;
6624   QCPItemAnchor * const top;
6625   QCPItemAnchor * const topRight;
6626   QCPItemAnchor * const right;
6627   QCPItemAnchor * const bottomRight;
6628   QCPItemAnchor * const bottom;
6629   QCPItemAnchor * const bottomLeft;
6630   QCPItemAnchor * const left;
6631   
6632 protected:
6633   enum AnchorIndex {aiTopLeft, aiTop, aiTopRight, aiRight, aiBottomRight, aiBottom, aiBottomLeft, aiLeft};
6634   
6635   // property members:
6636   QColor mColor, mSelectedColor;
6637   QPen mPen, mSelectedPen;
6638   QBrush mBrush, mSelectedBrush;
6639   QFont mFont, mSelectedFont;
6640   QString mText;
6641   Qt::Alignment mPositionAlignment;
6642   Qt::Alignment mTextAlignment;
6643   double mRotation;
6644   QMargins mPadding;
6645   
6646   // reimplemented virtual methods:
6647   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
6648   virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE;
6649   
6650   // non-virtual methods:
6651   QPointF getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const;
6652   QFont mainFont() const;
6653   QColor mainColor() const;
6654   QPen mainPen() const;
6655   QBrush mainBrush() const;
6656 };
6657 
6658 /* end of 'src/items/item-text.h' */
6659 
6660 
6661 /* including file 'src/items/item-ellipse.h' */
6662 /* modified 2021-03-29T02:30:44, size 3890   */
6663 
6664 class QCP_LIB_DECL QCPItemEllipse : public QCPAbstractItem
6665 {
6666   Q_OBJECT
6667   /// \cond INCLUDE_QPROPERTIES
6668   Q_PROPERTY(QPen pen READ pen WRITE setPen)
6669   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
6670   Q_PROPERTY(QBrush brush READ brush WRITE setBrush)
6671   Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush)
6672   /// \endcond
6673 public:
6674   explicit QCPItemEllipse(QCustomPlot *parentPlot);
6675   virtual ~QCPItemEllipse() Q_DECL_OVERRIDE;
6676   
6677   // getters:
6678   QPen pen() const { return mPen; }
6679   QPen selectedPen() const { return mSelectedPen; }
6680   QBrush brush() const { return mBrush; }
6681   QBrush selectedBrush() const { return mSelectedBrush; }
6682   
6683   // setters;
6684   void setPen(const QPen &pen);
6685   void setSelectedPen(const QPen &pen);
6686   void setBrush(const QBrush &brush);
6687   void setSelectedBrush(const QBrush &brush);
6688   
6689   // reimplemented virtual methods:
6690   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
6691   
6692   QCPItemPosition * const topLeft;
6693   QCPItemPosition * const bottomRight;
6694   QCPItemAnchor * const topLeftRim;
6695   QCPItemAnchor * const top;
6696   QCPItemAnchor * const topRightRim;
6697   QCPItemAnchor * const right;
6698   QCPItemAnchor * const bottomRightRim;
6699   QCPItemAnchor * const bottom;
6700   QCPItemAnchor * const bottomLeftRim;
6701   QCPItemAnchor * const left;
6702   QCPItemAnchor * const center;
6703   
6704 protected:
6705   enum AnchorIndex {aiTopLeftRim, aiTop, aiTopRightRim, aiRight, aiBottomRightRim, aiBottom, aiBottomLeftRim, aiLeft, aiCenter};
6706   
6707   // property members:
6708   QPen mPen, mSelectedPen;
6709   QBrush mBrush, mSelectedBrush;
6710   
6711   // reimplemented virtual methods:
6712   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
6713   virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE;
6714   
6715   // non-virtual methods:
6716   QPen mainPen() const;
6717   QBrush mainBrush() const;
6718 };
6719 
6720 /* end of 'src/items/item-ellipse.h' */
6721 
6722 
6723 /* including file 'src/items/item-pixmap.h' */
6724 /* modified 2021-03-29T02:30:44, size 4407  */
6725 
6726 class QCP_LIB_DECL QCPItemPixmap : public QCPAbstractItem
6727 {
6728   Q_OBJECT
6729   /// \cond INCLUDE_QPROPERTIES
6730   Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap)
6731   Q_PROPERTY(bool scaled READ scaled WRITE setScaled)
6732   Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode)
6733   Q_PROPERTY(Qt::TransformationMode transformationMode READ transformationMode)
6734   Q_PROPERTY(QPen pen READ pen WRITE setPen)
6735   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
6736   /// \endcond
6737 public:
6738   explicit QCPItemPixmap(QCustomPlot *parentPlot);
6739   virtual ~QCPItemPixmap() Q_DECL_OVERRIDE;
6740   
6741   // getters:
6742   QPixmap pixmap() const { return mPixmap; }
6743   bool scaled() const { return mScaled; }
6744   Qt::AspectRatioMode aspectRatioMode() const { return mAspectRatioMode; }
6745   Qt::TransformationMode transformationMode() const { return mTransformationMode; }
6746   QPen pen() const { return mPen; }
6747   QPen selectedPen() const { return mSelectedPen; }
6748   
6749   // setters;
6750   void setPixmap(const QPixmap &pixmap);
6751   void setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio, Qt::TransformationMode transformationMode=Qt::SmoothTransformation);
6752   void setPen(const QPen &pen);
6753   void setSelectedPen(const QPen &pen);
6754   
6755   // reimplemented virtual methods:
6756   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
6757   
6758   QCPItemPosition * const topLeft;
6759   QCPItemPosition * const bottomRight;
6760   QCPItemAnchor * const top;
6761   QCPItemAnchor * const topRight;
6762   QCPItemAnchor * const right;
6763   QCPItemAnchor * const bottom;
6764   QCPItemAnchor * const bottomLeft;
6765   QCPItemAnchor * const left;
6766   
6767 protected:
6768   enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft};
6769   
6770   // property members:
6771   QPixmap mPixmap;
6772   QPixmap mScaledPixmap;
6773   bool mScaled;
6774   bool mScaledPixmapInvalidated;
6775   Qt::AspectRatioMode mAspectRatioMode;
6776   Qt::TransformationMode mTransformationMode;
6777   QPen mPen, mSelectedPen;
6778   
6779   // reimplemented virtual methods:
6780   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
6781   virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE;
6782   
6783   // non-virtual methods:
6784   void updateScaledPixmap(QRect finalRect=QRect(), bool flipHorz=false, bool flipVert=false);
6785   QRect getFinalRect(bool *flippedHorz=nullptr, bool *flippedVert=nullptr) const;
6786   QPen mainPen() const;
6787 };
6788 
6789 /* end of 'src/items/item-pixmap.h' */
6790 
6791 
6792 /* including file 'src/items/item-tracer.h' */
6793 /* modified 2021-03-29T02:30:44, size 4811  */
6794 
6795 class QCP_LIB_DECL QCPItemTracer : public QCPAbstractItem
6796 {
6797   Q_OBJECT
6798   /// \cond INCLUDE_QPROPERTIES
6799   Q_PROPERTY(QPen pen READ pen WRITE setPen)
6800   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
6801   Q_PROPERTY(QBrush brush READ brush WRITE setBrush)
6802   Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush)
6803   Q_PROPERTY(double size READ size WRITE setSize)
6804   Q_PROPERTY(TracerStyle style READ style WRITE setStyle)
6805   Q_PROPERTY(QCPGraph* graph READ graph WRITE setGraph)
6806   Q_PROPERTY(double graphKey READ graphKey WRITE setGraphKey)
6807   Q_PROPERTY(bool interpolating READ interpolating WRITE setInterpolating)
6808   /// \endcond
6809 public:
6810   /*!
6811     The different visual appearances a tracer item can have. Some styles size may be controlled with \ref setSize.
6812     
6813     \see setStyle
6814   */
6815   enum TracerStyle { tsNone        ///< The tracer is not visible
6816                      ,tsPlus       ///< A plus shaped crosshair with limited size
6817                      ,tsCrosshair  ///< A plus shaped crosshair which spans the complete axis rect
6818                      ,tsCircle     ///< A circle
6819                      ,tsSquare     ///< A square
6820                    };
6821   Q_ENUMS(TracerStyle)
6822 
6823   explicit QCPItemTracer(QCustomPlot *parentPlot);
6824   virtual ~QCPItemTracer() Q_DECL_OVERRIDE;
6825 
6826   // getters:
6827   QPen pen() const { return mPen; }
6828   QPen selectedPen() const { return mSelectedPen; }
6829   QBrush brush() const { return mBrush; }
6830   QBrush selectedBrush() const { return mSelectedBrush; }
6831   double size() const { return mSize; }
6832   TracerStyle style() const { return mStyle; }
6833   QCPGraph *graph() const { return mGraph; }
6834   double graphKey() const { return mGraphKey; }
6835   bool interpolating() const { return mInterpolating; }
6836 
6837   // setters;
6838   void setPen(const QPen &pen);
6839   void setSelectedPen(const QPen &pen);
6840   void setBrush(const QBrush &brush);
6841   void setSelectedBrush(const QBrush &brush);
6842   void setSize(double size);
6843   void setStyle(TracerStyle style);
6844   void setGraph(QCPGraph *graph);
6845   void setGraphKey(double key);
6846   void setInterpolating(bool enabled);
6847 
6848   // reimplemented virtual methods:
6849   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
6850   
6851   // non-virtual methods:
6852   void updatePosition();
6853 
6854   QCPItemPosition * const position;
6855 
6856 protected:
6857   // property members:
6858   QPen mPen, mSelectedPen;
6859   QBrush mBrush, mSelectedBrush;
6860   double mSize;
6861   TracerStyle mStyle;
6862   QCPGraph *mGraph;
6863   double mGraphKey;
6864   bool mInterpolating;
6865 
6866   // reimplemented virtual methods:
6867   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
6868 
6869   // non-virtual methods:
6870   QPen mainPen() const;
6871   QBrush mainBrush() const;
6872 };
6873 Q_DECLARE_METATYPE(QCPItemTracer::TracerStyle)
6874 
6875 /* end of 'src/items/item-tracer.h' */
6876 
6877 
6878 /* including file 'src/items/item-bracket.h' */
6879 /* modified 2021-03-29T02:30:44, size 3991   */
6880 
6881 class QCP_LIB_DECL QCPItemBracket : public QCPAbstractItem
6882 {
6883   Q_OBJECT
6884   /// \cond INCLUDE_QPROPERTIES
6885   Q_PROPERTY(QPen pen READ pen WRITE setPen)
6886   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
6887   Q_PROPERTY(double length READ length WRITE setLength)
6888   Q_PROPERTY(BracketStyle style READ style WRITE setStyle)
6889   /// \endcond
6890 public:
6891   /*!
6892     Defines the various visual shapes of the bracket item. The appearance can be further modified
6893     by \ref setLength and \ref setPen.
6894     
6895     \see setStyle
6896   */
6897   enum BracketStyle { bsSquare  ///< A brace with angled edges
6898                       ,bsRound  ///< A brace with round edges
6899                       ,bsCurly  ///< A curly brace
6900                       ,bsCalligraphic ///< A curly brace with varying stroke width giving a calligraphic impression
6901   };
6902   Q_ENUMS(BracketStyle)
6903 
6904   explicit QCPItemBracket(QCustomPlot *parentPlot);
6905   virtual ~QCPItemBracket() Q_DECL_OVERRIDE;
6906   
6907   // getters:
6908   QPen pen() const { return mPen; }
6909   QPen selectedPen() const { return mSelectedPen; }
6910   double length() const { return mLength; }
6911   BracketStyle style() const { return mStyle; }
6912   
6913   // setters;
6914   void setPen(const QPen &pen);
6915   void setSelectedPen(const QPen &pen);
6916   void setLength(double length);
6917   void setStyle(BracketStyle style);
6918   
6919   // reimplemented virtual methods:
6920   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
6921   
6922   QCPItemPosition * const left;
6923   QCPItemPosition * const right;
6924   QCPItemAnchor * const center;
6925   
6926 protected:
6927   // property members:
6928   enum AnchorIndex {aiCenter};
6929   QPen mPen, mSelectedPen;
6930   double mLength;
6931   BracketStyle mStyle;
6932   
6933   // reimplemented virtual methods:
6934   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
6935   virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE;
6936   
6937   // non-virtual methods:
6938   QPen mainPen() const;
6939 };
6940 Q_DECLARE_METATYPE(QCPItemBracket::BracketStyle)
6941 
6942 /* end of 'src/items/item-bracket.h' */
6943 
6944 
6945 /* including file 'src/polar/radialaxis.h'  */
6946 /* modified 2021-03-29T02:30:44, size 12227 */
6947 
6948 
6949 class QCP_LIB_DECL QCPPolarAxisRadial : public QCPLayerable
6950 {
6951   Q_OBJECT
6952   /// \cond INCLUDE_QPROPERTIES
6953   
6954   /// \endcond
6955 public:
6956   /*!
6957     Defines the reference of the angle at which a radial axis is tilted (\ref setAngle).
6958   */
6959   enum AngleReference { arAbsolute    ///< The axis tilt is given in absolute degrees. The zero is to the right and positive angles are measured counter-clockwise.
6960                        ,arAngularAxis ///< The axis tilt is measured in the angular coordinate system given by the parent angular axis.
6961                       };
6962   Q_ENUMS(AngleReference)
6963   /*!
6964     Defines the scale of an axis.
6965     \see setScaleType
6966   */
6967   enum ScaleType { stLinear       ///< Linear scaling
6968                    ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed axis coordinates (possibly also \ref setTicker to a \ref QCPAxisTickerLog instance).
6969                  };
6970   Q_ENUMS(ScaleType)
6971   /*!
6972     Defines the selectable parts of an axis.
6973     \see setSelectableParts, setSelectedParts
6974   */
6975   enum SelectablePart { spNone        = 0      ///< None of the selectable parts
6976                         ,spAxis       = 0x001  ///< The axis backbone and tick marks
6977                         ,spTickLabels = 0x002  ///< Tick labels (numbers) of this axis (as a whole, not individually)
6978                         ,spAxisLabel  = 0x004  ///< The axis label
6979                       };
6980   Q_ENUMS(SelectablePart)
6981   Q_FLAGS(SelectableParts)
6982   Q_DECLARE_FLAGS(SelectableParts, SelectablePart)
6983   
6984   enum LabelMode { lmUpright   ///< 
6985                    ,lmRotated ///< 
6986                  };
6987   Q_ENUMS(LabelMode)
6988   
6989   explicit QCPPolarAxisRadial(QCPPolarAxisAngular *parent);
6990   virtual ~QCPPolarAxisRadial();
6991   
6992   // getters:
6993   bool rangeDrag() const { return mRangeDrag; }
6994   bool rangeZoom() const { return mRangeZoom; }
6995   double rangeZoomFactor() const { return mRangeZoomFactor; }
6996   
6997   QCPPolarAxisAngular *angularAxis() const { return mAngularAxis; }
6998   ScaleType scaleType() const { return mScaleType; }
6999   const QCPRange range() const { return mRange; }
7000   bool rangeReversed() const { return mRangeReversed; }
7001   double angle() const { return mAngle; }
7002   AngleReference angleReference() const { return mAngleReference; }
7003   QSharedPointer<QCPAxisTicker> ticker() const { return mTicker; }
7004   bool ticks() const { return mTicks; }
7005   bool tickLabels() const { return mTickLabels; }
7006   int tickLabelPadding() const { return mLabelPainter.padding(); }
7007   QFont tickLabelFont() const { return mTickLabelFont; }
7008   QColor tickLabelColor() const { return mTickLabelColor; }
7009   double tickLabelRotation() const { return mLabelPainter.rotation(); }
7010   LabelMode tickLabelMode() const;
7011   QString numberFormat() const;
7012   int numberPrecision() const { return mNumberPrecision; }
7013   QVector<double> tickVector() const { return mTickVector; }
7014   QVector<double> subTickVector() const { return mSubTickVector; }
7015   QVector<QString> tickVectorLabels() const { return mTickVectorLabels; }
7016   int tickLengthIn() const;
7017   int tickLengthOut() const;
7018   bool subTicks() const { return mSubTicks; }
7019   int subTickLengthIn() const;
7020   int subTickLengthOut() const;
7021   QPen basePen() const { return mBasePen; }
7022   QPen tickPen() const { return mTickPen; }
7023   QPen subTickPen() const { return mSubTickPen; }
7024   QFont labelFont() const { return mLabelFont; }
7025   QColor labelColor() const { return mLabelColor; }
7026   QString label() const { return mLabel; }
7027   int labelPadding() const;
7028   SelectableParts selectedParts() const { return mSelectedParts; }
7029   SelectableParts selectableParts() const { return mSelectableParts; }
7030   QFont selectedTickLabelFont() const { return mSelectedTickLabelFont; }
7031   QFont selectedLabelFont() const { return mSelectedLabelFont; }
7032   QColor selectedTickLabelColor() const { return mSelectedTickLabelColor; }
7033   QColor selectedLabelColor() const { return mSelectedLabelColor; }
7034   QPen selectedBasePen() const { return mSelectedBasePen; }
7035   QPen selectedTickPen() const { return mSelectedTickPen; }
7036   QPen selectedSubTickPen() const { return mSelectedSubTickPen; }
7037   
7038   // setters:
7039   void setRangeDrag(bool enabled);
7040   void setRangeZoom(bool enabled);
7041   void setRangeZoomFactor(double factor);
7042   
7043   Q_SLOT void setScaleType(QCPPolarAxisRadial::ScaleType type);
7044   Q_SLOT void setRange(const QCPRange &range);
7045   void setRange(double lower, double upper);
7046   void setRange(double position, double size, Qt::AlignmentFlag alignment);
7047   void setRangeLower(double lower);
7048   void setRangeUpper(double upper);
7049   void setRangeReversed(bool reversed);
7050   void setAngle(double degrees);
7051   void setAngleReference(AngleReference reference);
7052   void setTicker(QSharedPointer<QCPAxisTicker> ticker);
7053   void setTicks(bool show);
7054   void setTickLabels(bool show);
7055   void setTickLabelPadding(int padding);
7056   void setTickLabelFont(const QFont &font);
7057   void setTickLabelColor(const QColor &color);
7058   void setTickLabelRotation(double degrees);
7059   void setTickLabelMode(LabelMode mode);
7060   void setNumberFormat(const QString &formatCode);
7061   void setNumberPrecision(int precision);
7062   void setTickLength(int inside, int outside=0);
7063   void setTickLengthIn(int inside);
7064   void setTickLengthOut(int outside);
7065   void setSubTicks(bool show);
7066   void setSubTickLength(int inside, int outside=0);
7067   void setSubTickLengthIn(int inside);
7068   void setSubTickLengthOut(int outside);
7069   void setBasePen(const QPen &pen);
7070   void setTickPen(const QPen &pen);
7071   void setSubTickPen(const QPen &pen);
7072   void setLabelFont(const QFont &font);
7073   void setLabelColor(const QColor &color);
7074   void setLabel(const QString &str);
7075   void setLabelPadding(int padding);
7076   void setSelectedTickLabelFont(const QFont &font);
7077   void setSelectedLabelFont(const QFont &font);
7078   void setSelectedTickLabelColor(const QColor &color);
7079   void setSelectedLabelColor(const QColor &color);
7080   void setSelectedBasePen(const QPen &pen);
7081   void setSelectedTickPen(const QPen &pen);
7082   void setSelectedSubTickPen(const QPen &pen);
7083   Q_SLOT void setSelectableParts(const QCPPolarAxisRadial::SelectableParts &selectableParts);
7084   Q_SLOT void setSelectedParts(const QCPPolarAxisRadial::SelectableParts &selectedParts);
7085   
7086   // reimplemented virtual methods:
7087   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE;
7088   
7089   // non-property methods:
7090   void moveRange(double diff);
7091   void scaleRange(double factor);
7092   void scaleRange(double factor, double center);
7093   void rescale(bool onlyVisiblePlottables=false);
7094   void pixelToCoord(QPointF pixelPos, double &angleCoord, double &radiusCoord) const;
7095   QPointF coordToPixel(double angleCoord, double radiusCoord) const;
7096   double coordToRadius(double coord) const;
7097   double radiusToCoord(double radius) const;
7098   SelectablePart getPartAt(const QPointF &pos) const;
7099   
7100 signals:
7101   void rangeChanged(const QCPRange &newRange);
7102   void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange);
7103   void scaleTypeChanged(QCPPolarAxisRadial::ScaleType scaleType);
7104   void selectionChanged(const QCPPolarAxisRadial::SelectableParts &parts);
7105   void selectableChanged(const QCPPolarAxisRadial::SelectableParts &parts);
7106 
7107 protected:
7108   // property members:
7109   bool mRangeDrag;
7110   bool mRangeZoom;
7111   double mRangeZoomFactor;
7112   
7113   // axis base:
7114   QCPPolarAxisAngular *mAngularAxis;
7115   double mAngle;
7116   AngleReference mAngleReference;
7117   SelectableParts mSelectableParts, mSelectedParts;
7118   QPen mBasePen, mSelectedBasePen;
7119   // axis label:
7120   int mLabelPadding;
7121   QString mLabel;
7122   QFont mLabelFont, mSelectedLabelFont;
7123   QColor mLabelColor, mSelectedLabelColor;
7124   // tick labels:
7125   //int mTickLabelPadding; in label painter
7126   bool mTickLabels;
7127   //double mTickLabelRotation; in label painter
7128   QFont mTickLabelFont, mSelectedTickLabelFont;
7129   QColor mTickLabelColor, mSelectedTickLabelColor;
7130   int mNumberPrecision;
7131   QLatin1Char mNumberFormatChar;
7132   bool mNumberBeautifulPowers;
7133   bool mNumberMultiplyCross;
7134   // ticks and subticks:
7135   bool mTicks;
7136   bool mSubTicks;
7137   int mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut;
7138   QPen mTickPen, mSelectedTickPen;
7139   QPen mSubTickPen, mSelectedSubTickPen;
7140   // scale and range:
7141   QCPRange mRange;
7142   bool mRangeReversed;
7143   ScaleType mScaleType;
7144   
7145   // non-property members:
7146   QPointF mCenter;
7147   double mRadius;
7148   QSharedPointer<QCPAxisTicker> mTicker;
7149   QVector<double> mTickVector;
7150   QVector<QString> mTickVectorLabels;
7151   QVector<double> mSubTickVector;
7152   bool mDragging;
7153   QCPRange mDragStartRange;
7154   QCP::AntialiasedElements mAADragBackup, mNotAADragBackup;
7155   QCPLabelPainterPrivate mLabelPainter;
7156   
7157   // reimplemented virtual methods:
7158   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
7159   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
7160   virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE;
7161   // events:
7162   virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
7163   virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE;
7164   // mouse events:
7165   virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE;
7166   virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE;
7167   virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE;
7168   virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
7169   
7170   // non-virtual methods:
7171   void updateGeometry(const QPointF &center, double radius);
7172   void setupTickVectors();
7173   QPen getBasePen() const;
7174   QPen getTickPen() const;
7175   QPen getSubTickPen() const;
7176   QFont getTickLabelFont() const;
7177   QFont getLabelFont() const;
7178   QColor getTickLabelColor() const;
7179   QColor getLabelColor() const;
7180   
7181 private:
7182   Q_DISABLE_COPY(QCPPolarAxisRadial)
7183   
7184   friend class QCustomPlot;
7185   friend class QCPPolarAxisAngular;
7186 };
7187 Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPolarAxisRadial::SelectableParts)
7188 Q_DECLARE_METATYPE(QCPPolarAxisRadial::AngleReference)
7189 Q_DECLARE_METATYPE(QCPPolarAxisRadial::ScaleType)
7190 Q_DECLARE_METATYPE(QCPPolarAxisRadial::SelectablePart)
7191 
7192 
7193 
7194 /* end of 'src/polar/radialaxis.h' */
7195 
7196 
7197 /* including file 'src/polar/layoutelement-angularaxis.h' */
7198 /* modified 2021-03-29T02:30:44, size 13461               */
7199 
7200 class QCP_LIB_DECL QCPPolarAxisAngular : public QCPLayoutElement
7201 {
7202   Q_OBJECT
7203   /// \cond INCLUDE_QPROPERTIES
7204   
7205   /// \endcond
7206 public:
7207   /*!
7208     Defines the selectable parts of an axis.
7209     \see setSelectableParts, setSelectedParts
7210   */
7211   enum SelectablePart { spNone        = 0      ///< None of the selectable parts
7212                         ,spAxis       = 0x001  ///< The axis backbone and tick marks
7213                         ,spTickLabels = 0x002  ///< Tick labels (numbers) of this axis (as a whole, not individually)
7214                         ,spAxisLabel  = 0x004  ///< The axis label
7215                       };
7216   Q_ENUMS(SelectablePart)
7217   Q_FLAGS(SelectableParts)
7218   Q_DECLARE_FLAGS(SelectableParts, SelectablePart)
7219   
7220   /*!
7221     TODO
7222   */
7223   enum LabelMode { lmUpright   ///< 
7224                    ,lmRotated ///< 
7225                  };
7226   Q_ENUMS(LabelMode)
7227   
7228   explicit QCPPolarAxisAngular(QCustomPlot *parentPlot);
7229   virtual ~QCPPolarAxisAngular();
7230   
7231   // getters:
7232   QPixmap background() const { return mBackgroundPixmap; }
7233   QBrush backgroundBrush() const { return mBackgroundBrush; }
7234   bool backgroundScaled() const { return mBackgroundScaled; }
7235   Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; }
7236   bool rangeDrag() const { return mRangeDrag; }
7237   bool rangeZoom() const { return mRangeZoom; }
7238   double rangeZoomFactor() const { return mRangeZoomFactor; }
7239   
7240   const QCPRange range() const { return mRange; }
7241   bool rangeReversed() const { return mRangeReversed; }
7242   double angle() const { return mAngle; }
7243   QSharedPointer<QCPAxisTicker> ticker() const { return mTicker; }
7244   bool ticks() const { return mTicks; }
7245   bool tickLabels() const { return mTickLabels; }
7246   int tickLabelPadding() const { return mLabelPainter.padding(); }
7247   QFont tickLabelFont() const { return mTickLabelFont; }
7248   QColor tickLabelColor() const { return mTickLabelColor; }
7249   double tickLabelRotation() const { return mLabelPainter.rotation(); }
7250   LabelMode tickLabelMode() const;
7251   QString numberFormat() const;
7252   int numberPrecision() const { return mNumberPrecision; }
7253   QVector<double> tickVector() const { return mTickVector; }
7254   QVector<QString> tickVectorLabels() const { return mTickVectorLabels; }
7255   int tickLengthIn() const { return mTickLengthIn; }
7256   int tickLengthOut() const { return mTickLengthOut; }
7257   bool subTicks() const { return mSubTicks; }
7258   int subTickLengthIn() const { return mSubTickLengthIn; }
7259   int subTickLengthOut() const { return mSubTickLengthOut; }
7260   QPen basePen() const { return mBasePen; }
7261   QPen tickPen() const { return mTickPen; }
7262   QPen subTickPen() const { return mSubTickPen; }
7263   QFont labelFont() const { return mLabelFont; }
7264   QColor labelColor() const { return mLabelColor; }
7265   QString label() const { return mLabel; }
7266   int labelPadding() const { return mLabelPadding; }
7267   SelectableParts selectedParts() const { return mSelectedParts; }
7268   SelectableParts selectableParts() const { return mSelectableParts; }
7269   QFont selectedTickLabelFont() const { return mSelectedTickLabelFont; }
7270   QFont selectedLabelFont() const { return mSelectedLabelFont; }
7271   QColor selectedTickLabelColor() const { return mSelectedTickLabelColor; }
7272   QColor selectedLabelColor() const { return mSelectedLabelColor; }
7273   QPen selectedBasePen() const { return mSelectedBasePen; }
7274   QPen selectedTickPen() const { return mSelectedTickPen; }
7275   QPen selectedSubTickPen() const { return mSelectedSubTickPen; }
7276   QCPPolarGrid *grid() const { return mGrid; }
7277   
7278   // setters:
7279   void setBackground(const QPixmap &pm);
7280   void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding);
7281   void setBackground(const QBrush &brush);
7282   void setBackgroundScaled(bool scaled);
7283   void setBackgroundScaledMode(Qt::AspectRatioMode mode);
7284   void setRangeDrag(bool enabled);
7285   void setRangeZoom(bool enabled);
7286   void setRangeZoomFactor(double factor);
7287   
7288   Q_SLOT void setRange(const QCPRange &range);
7289   void setRange(double lower, double upper);
7290   void setRange(double position, double size, Qt::AlignmentFlag alignment);
7291   void setRangeLower(double lower);
7292   void setRangeUpper(double upper);
7293   void setRangeReversed(bool reversed);
7294   void setAngle(double degrees);
7295   void setTicker(QSharedPointer<QCPAxisTicker> ticker);
7296   void setTicks(bool show);
7297   void setTickLabels(bool show);
7298   void setTickLabelPadding(int padding);
7299   void setTickLabelFont(const QFont &font);
7300   void setTickLabelColor(const QColor &color);
7301   void setTickLabelRotation(double degrees);
7302   void setTickLabelMode(LabelMode mode);
7303   void setNumberFormat(const QString &formatCode);
7304   void setNumberPrecision(int precision);
7305   void setTickLength(int inside, int outside=0);
7306   void setTickLengthIn(int inside);
7307   void setTickLengthOut(int outside);
7308   void setSubTicks(bool show);
7309   void setSubTickLength(int inside, int outside=0);
7310   void setSubTickLengthIn(int inside);
7311   void setSubTickLengthOut(int outside);
7312   void setBasePen(const QPen &pen);
7313   void setTickPen(const QPen &pen);
7314   void setSubTickPen(const QPen &pen);
7315   void setLabelFont(const QFont &font);
7316   void setLabelColor(const QColor &color);
7317   void setLabel(const QString &str);
7318   void setLabelPadding(int padding);
7319   void setLabelPosition(Qt::AlignmentFlag position);
7320   void setSelectedTickLabelFont(const QFont &font);
7321   void setSelectedLabelFont(const QFont &font);
7322   void setSelectedTickLabelColor(const QColor &color);
7323   void setSelectedLabelColor(const QColor &color);
7324   void setSelectedBasePen(const QPen &pen);
7325   void setSelectedTickPen(const QPen &pen);
7326   void setSelectedSubTickPen(const QPen &pen);
7327   Q_SLOT void setSelectableParts(const QCPPolarAxisAngular::SelectableParts &selectableParts);
7328   Q_SLOT void setSelectedParts(const QCPPolarAxisAngular::SelectableParts &selectedParts);
7329   
7330   // reimplemented virtual methods:
7331   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const Q_DECL_OVERRIDE;
7332   virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE;
7333   virtual QList<QCPLayoutElement*> elements(bool recursive) const Q_DECL_OVERRIDE;
7334   
7335   // non-property methods:
7336   bool removeGraph(QCPPolarGraph *graph);
7337   int radialAxisCount() const;
7338   QCPPolarAxisRadial *radialAxis(int index=0) const;
7339   QList<QCPPolarAxisRadial*> radialAxes() const;
7340   QCPPolarAxisRadial *addRadialAxis(QCPPolarAxisRadial *axis=0);
7341   bool removeRadialAxis(QCPPolarAxisRadial *axis);
7342   QCPLayoutInset *insetLayout() const { return mInsetLayout; }
7343   QRegion exactClipRegion() const;
7344   
7345   void moveRange(double diff);
7346   void scaleRange(double factor);
7347   void scaleRange(double factor, double center);
7348   void rescale(bool onlyVisiblePlottables=false);
7349   double coordToAngleRad(double coord) const { return mAngleRad+(coord-mRange.lower)/mRange.size()*(mRangeReversed ? -2.0*M_PI : 2.0*M_PI); } // mention in doc that return doesn't wrap
7350   double angleRadToCoord(double angleRad) const { return mRange.lower+(angleRad-mAngleRad)/(mRangeReversed ? -2.0*M_PI : 2.0*M_PI)*mRange.size(); }
7351   void pixelToCoord(QPointF pixelPos, double &angleCoord, double &radiusCoord) const;
7352   QPointF coordToPixel(double angleCoord, double radiusCoord) const;
7353   SelectablePart getPartAt(const QPointF &pos) const;
7354   
7355   // read-only interface imitating a QRect:
7356   int left() const { return mRect.left(); }
7357   int right() const { return mRect.right(); }
7358   int top() const { return mRect.top(); }
7359   int bottom() const { return mRect.bottom(); }
7360   int width() const { return mRect.width(); }
7361   int height() const { return mRect.height(); }
7362   QSize size() const { return mRect.size(); }
7363   QPoint topLeft() const { return mRect.topLeft(); }
7364   QPoint topRight() const { return mRect.topRight(); }
7365   QPoint bottomLeft() const { return mRect.bottomLeft(); }
7366   QPoint bottomRight() const { return mRect.bottomRight(); }
7367   QPointF center() const { return mCenter; }
7368   double radius() const { return mRadius; }
7369   
7370 signals:
7371   void rangeChanged(const QCPRange &newRange);
7372   void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange);
7373   void selectionChanged(const QCPPolarAxisAngular::SelectableParts &parts);
7374   void selectableChanged(const QCPPolarAxisAngular::SelectableParts &parts);
7375   
7376 protected:
7377   // property members:
7378   QBrush mBackgroundBrush;
7379   QPixmap mBackgroundPixmap;
7380   QPixmap mScaledBackgroundPixmap;
7381   bool mBackgroundScaled;
7382   Qt::AspectRatioMode mBackgroundScaledMode;
7383   QCPLayoutInset *mInsetLayout;
7384   bool mRangeDrag;
7385   bool mRangeZoom;
7386   double mRangeZoomFactor;
7387   
7388   // axis base:
7389   double mAngle, mAngleRad;
7390   SelectableParts mSelectableParts, mSelectedParts;
7391   QPen mBasePen, mSelectedBasePen;
7392   // axis label:
7393   int mLabelPadding;
7394   QString mLabel;
7395   QFont mLabelFont, mSelectedLabelFont;
7396   QColor mLabelColor, mSelectedLabelColor;
7397   // tick labels:
7398   //int mTickLabelPadding; in label painter
7399   bool mTickLabels;
7400   //double mTickLabelRotation; in label painter
7401   QFont mTickLabelFont, mSelectedTickLabelFont;
7402   QColor mTickLabelColor, mSelectedTickLabelColor;
7403   int mNumberPrecision;
7404   QLatin1Char mNumberFormatChar;
7405   bool mNumberBeautifulPowers;
7406   bool mNumberMultiplyCross;
7407   // ticks and subticks:
7408   bool mTicks;
7409   bool mSubTicks;
7410   int mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut;
7411   QPen mTickPen, mSelectedTickPen;
7412   QPen mSubTickPen, mSelectedSubTickPen;
7413   // scale and range:
7414   QCPRange mRange;
7415   bool mRangeReversed;
7416   
7417   // non-property members:
7418   QPointF mCenter;
7419   double mRadius;
7420   QList<QCPPolarAxisRadial*> mRadialAxes;
7421   QCPPolarGrid *mGrid;
7422   QList<QCPPolarGraph*> mGraphs;
7423   QSharedPointer<QCPAxisTicker> mTicker;
7424   QVector<double> mTickVector;
7425   QVector<QString> mTickVectorLabels;
7426   QVector<QPointF> mTickVectorCosSin;
7427   QVector<double> mSubTickVector;
7428   QVector<QPointF> mSubTickVectorCosSin;
7429   bool mDragging;
7430   QCPRange mDragAngularStart;
7431   QList<QCPRange> mDragRadialStart;
7432   QCP::AntialiasedElements mAADragBackup, mNotAADragBackup;
7433   QCPLabelPainterPrivate mLabelPainter;
7434   
7435   // reimplemented virtual methods:
7436   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
7437   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
7438   virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE;
7439   // events:
7440   virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE;
7441   virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE;
7442   virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE;
7443   virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
7444   
7445   // non-virtual methods:
7446   bool registerPolarGraph(QCPPolarGraph *graph);
7447   void drawBackground(QCPPainter *painter, const QPointF &center, double radius);
7448   void setupTickVectors();
7449   QPen getBasePen() const;
7450   QPen getTickPen() const;
7451   QPen getSubTickPen() const;
7452   QFont getTickLabelFont() const;
7453   QFont getLabelFont() const;
7454   QColor getTickLabelColor() const;
7455   QColor getLabelColor() const;
7456   
7457 private:
7458   Q_DISABLE_COPY(QCPPolarAxisAngular)
7459   
7460   friend class QCustomPlot;
7461   friend class QCPPolarGrid;
7462   friend class QCPPolarGraph;
7463 };
7464 Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPolarAxisAngular::SelectableParts)
7465 Q_DECLARE_METATYPE(QCPPolarAxisAngular::SelectablePart)
7466 
7467 /* end of 'src/polar/layoutelement-angularaxis.h' */
7468 
7469 
7470 /* including file 'src/polar/polargrid.h'  */
7471 /* modified 2021-03-29T02:30:44, size 4506 */
7472 
7473 class QCP_LIB_DECL QCPPolarGrid :public QCPLayerable
7474 {
7475   Q_OBJECT
7476   /// \cond INCLUDE_QPROPERTIES
7477   
7478   /// \endcond
7479 public:
7480   /*!
7481     TODO
7482   */
7483   enum GridType { gtAngular = 0x01 ///< 
7484                   ,gtRadial = 0x02 ///< 
7485                   ,gtAll    = 0xFF ///< 
7486                   ,gtNone   = 0x00 ///< 
7487                 };
7488   Q_ENUMS(GridType)
7489   Q_FLAGS(GridTypes)
7490   Q_DECLARE_FLAGS(GridTypes, GridType)
7491   
7492   explicit QCPPolarGrid(QCPPolarAxisAngular *parentAxis);
7493   
7494   // getters:
7495   QCPPolarAxisRadial *radialAxis() const { return mRadialAxis.data(); }
7496   GridTypes type() const { return mType; }
7497   GridTypes subGridType() const { return mSubGridType; }
7498   bool antialiasedSubGrid() const { return mAntialiasedSubGrid; }
7499   bool antialiasedZeroLine() const { return mAntialiasedZeroLine; }
7500   QPen angularPen() const { return mAngularPen; }
7501   QPen angularSubGridPen() const { return mAngularSubGridPen; }
7502   QPen radialPen() const { return mRadialPen; }
7503   QPen radialSubGridPen() const { return mRadialSubGridPen; }
7504   QPen radialZeroLinePen() const { return mRadialZeroLinePen; }
7505   
7506   // setters:
7507   void setRadialAxis(QCPPolarAxisRadial *axis);
7508   void setType(GridTypes type);
7509   void setSubGridType(GridTypes type);
7510   void setAntialiasedSubGrid(bool enabled);
7511   void setAntialiasedZeroLine(bool enabled);
7512   void setAngularPen(const QPen &pen);
7513   void setAngularSubGridPen(const QPen &pen);
7514   void setRadialPen(const QPen &pen);
7515   void setRadialSubGridPen(const QPen &pen);
7516   void setRadialZeroLinePen(const QPen &pen);
7517   
7518 protected:
7519   // property members:
7520   GridTypes mType;
7521   GridTypes mSubGridType;
7522   bool mAntialiasedSubGrid, mAntialiasedZeroLine;
7523   QPen mAngularPen, mAngularSubGridPen;
7524   QPen mRadialPen, mRadialSubGridPen, mRadialZeroLinePen;
7525   
7526   // non-property members:
7527   QCPPolarAxisAngular *mParentAxis;
7528   QPointer<QCPPolarAxisRadial> mRadialAxis;
7529   
7530   // reimplemented virtual methods:
7531   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
7532   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
7533   
7534   // non-virtual methods:
7535   void drawRadialGrid(QCPPainter *painter, const QPointF &center, const QVector<double> &coords, const QPen &pen, const QPen &zeroPen=Qt::NoPen);
7536   void drawAngularGrid(QCPPainter *painter, const QPointF &center, double radius, const QVector<QPointF> &ticksCosSin, const QPen &pen);
7537   
7538 private:
7539   Q_DISABLE_COPY(QCPPolarGrid)
7540   
7541 };
7542 
7543 Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPolarGrid::GridTypes)
7544 Q_DECLARE_METATYPE(QCPPolarGrid::GridType)
7545 
7546 
7547 /* end of 'src/polar/polargrid.h' */
7548 
7549 
7550 /* including file 'src/polar/polargraph.h' */
7551 /* modified 2021-03-29T02:30:44, size 9606 */
7552 
7553 
7554 class QCP_LIB_DECL QCPPolarLegendItem : public QCPAbstractLegendItem
7555 {
7556   Q_OBJECT
7557 public:
7558   QCPPolarLegendItem(QCPLegend *parent, QCPPolarGraph *graph);
7559   
7560   // getters:
7561   QCPPolarGraph *polarGraph() { return mPolarGraph; }
7562   
7563 protected:
7564   // property members:
7565   QCPPolarGraph *mPolarGraph;
7566   
7567   // reimplemented virtual methods:
7568   virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
7569   virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE;
7570   
7571   // non-virtual methods:
7572   QPen getIconBorderPen() const;
7573   QColor getTextColor() const;
7574   QFont getFont() const;
7575 };
7576 
7577 
7578 class QCP_LIB_DECL QCPPolarGraph : public QCPLayerable
7579 {
7580   Q_OBJECT
7581   /// \cond INCLUDE_QPROPERTIES
7582   
7583   /// \endcond
7584 public:
7585   /*!
7586     Defines how the graph's line is represented visually in the plot. The line is drawn with the
7587     current pen of the graph (\ref setPen).
7588     \see setLineStyle
7589   */
7590   enum LineStyle { lsNone        ///< data points are not connected with any lines (e.g. data only represented
7591                                  ///< with symbols according to the scatter style, see \ref setScatterStyle)
7592                    ,lsLine       ///< data points are connected by a straight line
7593                  };
7594   Q_ENUMS(LineStyle)
7595   
7596   QCPPolarGraph(QCPPolarAxisAngular *keyAxis, QCPPolarAxisRadial *valueAxis);
7597   virtual ~QCPPolarGraph();
7598   
7599   // getters:
7600   QString name() const { return mName; }
7601   bool antialiasedFill() const { return mAntialiasedFill; }
7602   bool antialiasedScatters() const { return mAntialiasedScatters; }
7603   QPen pen() const { return mPen; }
7604   QBrush brush() const { return mBrush; }
7605   bool periodic() const { return mPeriodic; }
7606   QCPPolarAxisAngular *keyAxis() const { return mKeyAxis.data(); }
7607   QCPPolarAxisRadial *valueAxis() const { return mValueAxis.data(); }
7608   QCP::SelectionType selectable() const { return mSelectable; }
7609   bool selected() const { return !mSelection.isEmpty(); }
7610   QCPDataSelection selection() const { return mSelection; }
7611   //QCPSelectionDecorator *selectionDecorator() const { return mSelectionDecorator; }
7612   QSharedPointer<QCPGraphDataContainer> data() const { return mDataContainer; }
7613   LineStyle lineStyle() const { return mLineStyle; }
7614   QCPScatterStyle scatterStyle() const { return mScatterStyle; }
7615   
7616   // setters:
7617   void setName(const QString &name);
7618   void setAntialiasedFill(bool enabled);
7619   void setAntialiasedScatters(bool enabled);
7620   void setPen(const QPen &pen);
7621   void setBrush(const QBrush &brush);
7622   void setPeriodic(bool enabled);
7623   void setKeyAxis(QCPPolarAxisAngular *axis);
7624   void setValueAxis(QCPPolarAxisRadial *axis);
7625   Q_SLOT void setSelectable(QCP::SelectionType selectable);
7626   Q_SLOT void setSelection(QCPDataSelection selection);
7627   //void setSelectionDecorator(QCPSelectionDecorator *decorator);
7628   void setData(QSharedPointer<QCPGraphDataContainer> data);
7629   void setData(const QVector<double> &keys, const QVector<double> &values, bool alreadySorted=false);
7630   void setLineStyle(LineStyle ls);
7631   void setScatterStyle(const QCPScatterStyle &style);
7632 
7633   // non-property methods:
7634   void addData(const QVector<double> &keys, const QVector<double> &values, bool alreadySorted=false);
7635   void addData(double key, double value);
7636   void coordsToPixels(double key, double value, double &x, double &y) const;
7637   const QPointF coordsToPixels(double key, double value) const;
7638   void pixelsToCoords(double x, double y, double &key, double &value) const;
7639   void pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const;
7640   void rescaleAxes(bool onlyEnlarge=false) const;
7641   void rescaleKeyAxis(bool onlyEnlarge=false) const;
7642   void rescaleValueAxis(bool onlyEnlarge=false, bool inKeyRange=false) const;
7643   bool addToLegend(QCPLegend *legend);
7644   bool addToLegend();
7645   bool removeFromLegend(QCPLegend *legend) const;
7646   bool removeFromLegend() const;
7647   
7648   // introduced virtual methods:
7649   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const override; // actually introduced in QCPLayerable as non-pure, but we want to force reimplementation for plottables
7650   virtual QCPPlottableInterface1D *interface1D() { return 0; } // TODO: return this later, when QCPAbstractPolarPlottable is created
7651   virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const;
7652   virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const;
7653   
7654 signals:
7655   void selectionChanged(bool selected);
7656   void selectionChanged(const QCPDataSelection &selection);
7657   void selectableChanged(QCP::SelectionType selectable);
7658   
7659 protected:
7660   // property members:
7661   QSharedPointer<QCPGraphDataContainer> mDataContainer;
7662   LineStyle mLineStyle;
7663   QCPScatterStyle mScatterStyle;
7664   QString mName;
7665   bool mAntialiasedFill, mAntialiasedScatters;
7666   QPen mPen;
7667   QBrush mBrush;
7668   bool mPeriodic;
7669   QPointer<QCPPolarAxisAngular> mKeyAxis;
7670   QPointer<QCPPolarAxisRadial> mValueAxis;
7671   QCP::SelectionType mSelectable;
7672   QCPDataSelection mSelection;
7673   //QCPSelectionDecorator *mSelectionDecorator;
7674   
7675   // introduced virtual methods (later reimplemented TODO from QCPAbstractPolarPlottable):
7676   virtual QRect clipRect() const override;
7677   virtual void draw(QCPPainter *painter) override;
7678   virtual QCP::Interaction selectionCategory() const override;
7679   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const override;
7680   // events:
7681   virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) override;
7682   virtual void deselectEvent(bool *selectionStateChanged) override;
7683   // virtual drawing helpers:
7684   virtual void drawLinePlot(QCPPainter *painter, const QVector<QPointF> &lines) const;
7685   virtual void drawFill(QCPPainter *painter, QVector<QPointF> *lines) const;
7686   virtual void drawScatterPlot(QCPPainter *painter, const QVector<QPointF> &scatters, const QCPScatterStyle &style) const;
7687   
7688   // introduced virtual methods:
7689   virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const;
7690   
7691   // non-virtual methods:
7692   void applyFillAntialiasingHint(QCPPainter *painter) const;
7693   void applyScattersAntialiasingHint(QCPPainter *painter) const;
7694   double pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const;
7695   // drawing helpers:
7696   virtual int dataCount() const;
7697   void getDataSegments(QList<QCPDataRange> &selectedSegments, QList<QCPDataRange> &unselectedSegments) const;
7698   void drawPolyline(QCPPainter *painter, const QVector<QPointF> &lineData) const;
7699   void getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const;
7700   void getLines(QVector<QPointF> *lines, const QCPDataRange &dataRange) const;
7701   void getScatters(QVector<QPointF> *scatters, const QCPDataRange &dataRange) const;
7702   void getOptimizedLineData(QVector<QCPGraphData> *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const;
7703   void getOptimizedScatterData(QVector<QCPGraphData> *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const;
7704   QVector<QPointF> dataToLines(const QVector<QCPGraphData> &data) const;
7705 
7706 private:
7707   Q_DISABLE_COPY(QCPPolarGraph)
7708   
7709   friend class QCPPolarLegendItem;
7710 };
7711 
7712 /* end of 'src/polar/polargraph.h' */
7713 
7714 
7715 #endif // QCUSTOMPLOT_H
7716