1 /***************************************************************************
2 **                                                                        **
3 **  QCustomPlot, an easy to use, modern plotting widget for Qt            **
4 **  Copyright (C) 2011-2015 Emanuel Eichhammer                            **
5 **                                                                        **
6 **  This program is free software: you can redistribute it and/or modify  **
7 **  it under the terms of the GNU General Public License as published by  **
8 **  the Free Software Foundation, either version 2 of the License, or     **
9 **  (at your option) any later version.                                   **
10 **                                                                        **
11 **  This program is distributed in the hope that it will be useful,       **
12 **  but WITHOUT ANY WARRANTY; without even the implied warranty of        **
13 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         **
14 **  GNU General Public License for more details.                          **
15 **                                                                        **
16 **  You should have received a copy of the GNU General Public License     **
17 **  along with this program.  If not, see http://www.gnu.org/licenses/.   **
18 **                                                                        **
19 ****************************************************************************
20 **           Author: Emanuel Eichhammer                                   **
21 **  Website/Contact: http://www.qcustomplot.com/                          **
22 **             Date: 22.12.15                                             **
23 **          Version: 1.3.2                                                **
24 ****************************************************************************/
25 
26 #ifndef QCUSTOMPLOT_H
27 #define QCUSTOMPLOT_H
28 
29 #include <QObject>
30 #include <QPointer>
31 #include <QWidget>
32 #include <QPainter>
33 #include <QPaintEvent>
34 #include <QMouseEvent>
35 #include <QPixmap>
36 #include <QVector>
37 #include <QString>
38 #include <QDateTime>
39 #include <QMultiMap>
40 #include <QFlags>
41 #include <QDebug>
42 #include <QVector2D>
43 #include <QStack>
44 #include <QCache>
45 #include <QMargins>
46 #include <qmath.h>
47 #include <limits>
48 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
49 #  include <qnumeric.h>
50 #  include <QPrinter>
51 #  include <QPrintEngine>
52 #else
53 #  include <QtNumeric>
54 #  include <QtPrintSupport/QtPrintSupport>
55 #endif
56 
57 class QCPPainter;
58 class QCustomPlot;
59 class QCPLayerable;
60 class QCPLayoutElement;
61 class QCPLayout;
62 class QCPAxis;
63 class QCPAxisRect;
64 class QCPAxisPainterPrivate;
65 class QCPAbstractPlottable;
66 class QCPGraph;
67 class QCPAbstractItem;
68 class QCPItemPosition;
69 class QCPLayer;
70 class QCPPlotTitle;
71 class QCPLegend;
72 class QCPAbstractLegendItem;
73 class QCPColorMap;
74 class QCPColorScale;
75 class QCPBars;
76 
77 
78 /*! \file */
79 
80 
81 // decl definitions for shared library compilation/usage:
82 #if defined(QCUSTOMPLOT_COMPILE_LIBRARY)
83 #  define QCP_LIB_DECL Q_DECL_EXPORT
84 #elif defined(QCUSTOMPLOT_USE_LIBRARY)
85 #  define QCP_LIB_DECL Q_DECL_IMPORT
86 #else
87 #  define QCP_LIB_DECL
88 #endif
89 
90 /*!
91   The QCP Namespace contains general enums and QFlags used throughout the QCustomPlot library
92 */
93 namespace QCP
94 {
95 /*!
96   Defines the sides of a rectangular entity to which margins can be applied.
97 
98   \see QCPLayoutElement::setAutoMargins, QCPAxisRect::setAutoMargins
99 */
100 enum MarginSide { msLeft     = 0x01 ///< <tt>0x01</tt> left margin
101                   ,msRight   = 0x02 ///< <tt>0x02</tt> right margin
102                   ,msTop     = 0x04 ///< <tt>0x04</tt> top margin
103                   ,msBottom  = 0x08 ///< <tt>0x08</tt> bottom margin
104                   ,msAll     = 0xFF ///< <tt>0xFF</tt> all margins
105                   ,msNone    = 0x00 ///< <tt>0x00</tt> no margin
106                 };
107 Q_DECLARE_FLAGS(MarginSides, MarginSide)
108 
109 /*!
110   Defines what objects of a plot can be forcibly drawn antialiased/not antialiased. If an object is
111   neither forcibly drawn antialiased nor forcibly drawn not antialiased, it is up to the respective
112   element how it is drawn. Typically it provides a \a setAntialiased function for this.
113 
114   \c AntialiasedElements is a flag of or-combined elements of this enum type.
115 
116   \see QCustomPlot::setAntialiasedElements, QCustomPlot::setNotAntialiasedElements
117 */
118 enum AntialiasedElement { aeAxes           = 0x0001 ///< <tt>0x0001</tt> Axis base line and tick marks
119                           ,aeGrid          = 0x0002 ///< <tt>0x0002</tt> Grid lines
120                           ,aeSubGrid       = 0x0004 ///< <tt>0x0004</tt> Sub grid lines
121                           ,aeLegend        = 0x0008 ///< <tt>0x0008</tt> Legend box
122                           ,aeLegendItems   = 0x0010 ///< <tt>0x0010</tt> Legend items
123                           ,aePlottables    = 0x0020 ///< <tt>0x0020</tt> Main lines of plottables (excluding error bars, see element \ref aeErrorBars)
124                           ,aeItems         = 0x0040 ///< <tt>0x0040</tt> Main lines of items
125                           ,aeScatters      = 0x0080 ///< <tt>0x0080</tt> Scatter symbols of plottables (excluding scatter symbols of type ssPixmap)
126                           ,aeErrorBars     = 0x0100 ///< <tt>0x0100</tt> Error bars
127                           ,aeFills         = 0x0200 ///< <tt>0x0200</tt> Borders of fills (e.g. under or between graphs)
128                           ,aeZeroLine      = 0x0400 ///< <tt>0x0400</tt> Zero-lines, see \ref QCPGrid::setZeroLinePen
129                           ,aeAll           = 0xFFFF ///< <tt>0xFFFF</tt> All elements
130                           ,aeNone          = 0x0000 ///< <tt>0x0000</tt> No elements
131                         };
132 Q_DECLARE_FLAGS(AntialiasedElements, AntialiasedElement)
133 
134 /*!
135   Defines plotting hints that control various aspects of the quality and speed of plotting.
136 
137   \see QCustomPlot::setPlottingHints
138 */
139 enum PlottingHint { phNone            = 0x000 ///< <tt>0x000</tt> No hints are set
140                     ,phFastPolylines  = 0x001 ///< <tt>0x001</tt> Graph/Curve lines are drawn with a faster method. This reduces the quality
141                                               ///<                especially of the line segment joins. (Only relevant for solid line pens.)
142                     ,phForceRepaint   = 0x002 ///< <tt>0x002</tt> causes an immediate repaint() instead of a soft update() when QCustomPlot::replot() is called with parameter \ref QCustomPlot::rpHint.
143                                               ///<                This is set by default to prevent the plot from freezing on fast consecutive replots (e.g. user drags ranges with mouse).
144                     ,phCacheLabels    = 0x004 ///< <tt>0x004</tt> axis (tick) labels will be cached as pixmaps, increasing replot performance.
145                   };
146 Q_DECLARE_FLAGS(PlottingHints, PlottingHint)
147 
148 /*!
149   Defines the mouse interactions possible with QCustomPlot.
150 
151   \c Interactions is a flag of or-combined elements of this enum type.
152 
153   \see QCustomPlot::setInteractions
154 */
155 enum Interaction { iRangeDrag         = 0x001 ///< <tt>0x001</tt> Axis ranges are draggable (see \ref QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeDragAxes)
156                    ,iRangeZoom        = 0x002 ///< <tt>0x002</tt> Axis ranges are zoomable with the mouse wheel (see \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeZoomAxes)
157                    ,iMultiSelect      = 0x004 ///< <tt>0x004</tt> The user can select multiple objects by holding the modifier set by \ref QCustomPlot::setMultiSelectModifier while clicking
158                    ,iSelectPlottables = 0x008 ///< <tt>0x008</tt> Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable)
159                    ,iSelectAxes       = 0x010 ///< <tt>0x010</tt> Axes are selectable (or parts of them, see QCPAxis::setSelectableParts)
160                    ,iSelectLegend     = 0x020 ///< <tt>0x020</tt> Legends are selectable (or their child items, see QCPLegend::setSelectableParts)
161                    ,iSelectItems      = 0x040 ///< <tt>0x040</tt> Items are selectable (Rectangles, Arrows, Textitems, etc. see \ref QCPAbstractItem)
162                    ,iSelectOther      = 0x080 ///< <tt>0x080</tt> All other objects are selectable (e.g. your own derived layerables, the plot title,...)
163                  };
Q_DECLARE_FLAGS(Interactions,Interaction)164 Q_DECLARE_FLAGS(Interactions, Interaction)
165 
166 /*! \internal
167 
168   Returns whether the specified \a value is considered an invalid data value for plottables (i.e.
169   is \e nan or \e +/-inf). This function is used to check data validity upon replots, when the
170   compiler flag \c QCUSTOMPLOT_CHECK_DATA is set.
171 */
172 inline bool isInvalidData(double value)
173 {
174   return qIsNaN(value) || qIsInf(value);
175 }
176 
177 /*! \internal
178   \overload
179 
180   Checks two arguments instead of one.
181 */
isInvalidData(double value1,double value2)182 inline bool isInvalidData(double value1, double value2)
183 {
184   return isInvalidData(value1) || isInvalidData(value2);
185 }
186 
187 /*! \internal
188 
189   Sets the specified \a side of \a margins to \a value
190 
191   \see getMarginValue
192 */
setMarginValue(QMargins & margins,QCP::MarginSide side,int value)193 inline void setMarginValue(QMargins &margins, QCP::MarginSide side, int value)
194 {
195   switch (side)
196   {
197     case QCP::msLeft: margins.setLeft(value); break;
198     case QCP::msRight: margins.setRight(value); break;
199     case QCP::msTop: margins.setTop(value); break;
200     case QCP::msBottom: margins.setBottom(value); break;
201     case QCP::msAll: margins = QMargins(value, value, value, value); break;
202     default: break;
203   }
204 }
205 
206 /*! \internal
207 
208   Returns the value of the specified \a side of \a margins. If \a side is \ref QCP::msNone or
209   \ref QCP::msAll, returns 0.
210 
211   \see setMarginValue
212 */
getMarginValue(const QMargins & margins,QCP::MarginSide side)213 inline int getMarginValue(const QMargins &margins, QCP::MarginSide side)
214 {
215   switch (side)
216   {
217     case QCP::msLeft: return margins.left();
218     case QCP::msRight: return margins.right();
219     case QCP::msTop: return margins.top();
220     case QCP::msBottom: return margins.bottom();
221     default: break;
222   }
223   return 0;
224 }
225 
226 } // end of namespace QCP
227 
228 Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::AntialiasedElements)
Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::PlottingHints)229 Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::PlottingHints)
230 Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::MarginSides)
231 Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::Interactions)
232 
233 
234 class QCP_LIB_DECL QCPScatterStyle
235 {
236   Q_GADGET
237 public:
238   /*!
239     Defines the shape used for scatter points.
240 
241     On plottables/items that draw scatters, the sizes of these visualizations (with exception of
242     \ref ssDot and \ref ssPixmap) can be controlled with the \ref setSize function. Scatters are
243     drawn with the pen and brush specified with \ref setPen and \ref setBrush.
244   */
245   enum ScatterShape { ssNone       ///< no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines)
246                       ,ssDot       ///< \enumimage{ssDot.png} a single pixel (use \ref ssDisc or \ref ssCircle if you want a round shape with a certain radius)
247                       ,ssCross     ///< \enumimage{ssCross.png} a cross
248                       ,ssPlus      ///< \enumimage{ssPlus.png} a plus
249                       ,ssCircle    ///< \enumimage{ssCircle.png} a circle
250                       ,ssDisc      ///< \enumimage{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle)
251                       ,ssSquare    ///< \enumimage{ssSquare.png} a square
252                       ,ssDiamond   ///< \enumimage{ssDiamond.png} a diamond
253                       ,ssStar      ///< \enumimage{ssStar.png} a star with eight arms, i.e. a combination of cross and plus
254                       ,ssTriangle  ///< \enumimage{ssTriangle.png} an equilateral triangle, standing on baseline
255                       ,ssTriangleInverted ///< \enumimage{ssTriangleInverted.png} an equilateral triangle, standing on corner
256                       ,ssCrossSquare      ///< \enumimage{ssCrossSquare.png} a square with a cross inside
257                       ,ssPlusSquare       ///< \enumimage{ssPlusSquare.png} a square with a plus inside
258                       ,ssCrossCircle      ///< \enumimage{ssCrossCircle.png} a circle with a cross inside
259                       ,ssPlusCircle       ///< \enumimage{ssPlusCircle.png} a circle with a plus inside
260                       ,ssPeace     ///< \enumimage{ssPeace.png} a circle, with one vertical and two downward diagonal lines
261                       ,ssPixmap    ///< a custom pixmap specified by \ref setPixmap, centered on the data point coordinates
262                       ,ssCustom    ///< custom painter operations are performed per scatter (As QPainterPath, see \ref setCustomPath)
263                     };
264   Q_ENUM(ScatterShape)
265 
266   QCPScatterStyle();
267   QCPScatterStyle(ScatterShape shape, double size=6);
268   QCPScatterStyle(ScatterShape shape, const QColor &color, double size);
269   QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size);
270   QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size);
271   QCPScatterStyle(const QPixmap &pixmap);
272   QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush=Qt::NoBrush, double size=6);
273 
274   // getters:
275   double size() const { return mSize; }
276   ScatterShape shape() const { return mShape; }
277   QPen pen() const { return mPen; }
278   QBrush brush() const { return mBrush; }
279   QPixmap pixmap() const { return mPixmap; }
280   QPainterPath customPath() const { return mCustomPath; }
281 
282   // setters:
283   void setSize(double size);
284   void setShape(ScatterShape shape);
285   void setPen(const QPen &pen);
286   void setBrush(const QBrush &brush);
287   void setPixmap(const QPixmap &pixmap);
288   void setCustomPath(const QPainterPath &customPath);
289 
290   // non-property methods:
291   bool isNone() const { return mShape == ssNone; }
292   bool isPenDefined() const { return mPenDefined; }
293   void applyTo(QCPPainter *painter, const QPen &defaultPen) const;
294   void drawShape(QCPPainter *painter, QPointF pos) const;
295   void drawShape(QCPPainter *painter, double x, double y) const;
296 
297 protected:
298   // property members:
299   double mSize;
300   ScatterShape mShape;
301   QPen mPen;
302   QBrush mBrush;
303   QPixmap mPixmap;
304   QPainterPath mCustomPath;
305 
306   // non-property members:
307   bool mPenDefined;
308 };
309 Q_DECLARE_TYPEINFO(QCPScatterStyle, Q_MOVABLE_TYPE);
310 
311 
312 class QCP_LIB_DECL QCPPainter : public QPainter
313 {
314   Q_GADGET
315 public:
316   /*!
317     Defines special modes the painter can operate in. They disable or enable certain subsets of features/fixes/workarounds,
318     depending on whether they are wanted on the respective output device.
319   */
320   enum PainterMode { pmDefault       = 0x00   ///< <tt>0x00</tt> Default mode for painting on screen devices
321                      ,pmVectorized   = 0x01   ///< <tt>0x01</tt> Mode for vectorized painting (e.g. PDF export). For example, this prevents some antialiasing fixes.
322                      ,pmNoCaching    = 0x02   ///< <tt>0x02</tt> Mode for all sorts of exports (e.g. PNG, PDF,...). For example, this prevents using cached pixmap labels
323                      ,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.)
324                    };
325   Q_FLAGS(PainterMode PainterModes)
326   Q_DECLARE_FLAGS(PainterModes, PainterMode)
327 
328   QCPPainter();
329   QCPPainter(QPaintDevice *device);
330   ~QCPPainter();
331 
332   // getters:
antialiasing()333   bool antialiasing() const { return testRenderHint(QPainter::Antialiasing); }
modes()334   PainterModes modes() const { return mModes; }
335 
336   // setters:
337   void setAntialiasing(bool enabled);
338   void setMode(PainterMode mode, bool enabled=true);
339   void setModes(PainterModes modes);
340 
341   // methods hiding non-virtual base class functions (QPainter bug workarounds):
342   bool begin(QPaintDevice *device);
343   void setPen(const QPen &pen);
344   void setPen(const QColor &color);
345   void setPen(Qt::PenStyle penStyle);
346   void drawLine(const QLineF &line);
drawLine(const QPointF & p1,const QPointF & p2)347   void drawLine(const QPointF &p1, const QPointF &p2) {drawLine(QLineF(p1, p2));}
348   void save();
349   void restore();
350 
351   // non-virtual methods:
352   void makeNonCosmetic();
353 
354 protected:
355   // property members:
356   PainterModes mModes;
357   bool mIsAntialiasing;
358 
359   // non-property members:
360   QStack<bool> mAntialiasingStack;
361 };
Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPainter::PainterModes)362 Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPainter::PainterModes)
363 
364 
365 class QCP_LIB_DECL QCPLayer : public QObject
366 {
367   Q_OBJECT
368   /// \cond INCLUDE_QPROPERTIES
369   Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot)
370   Q_PROPERTY(QString name READ name)
371   Q_PROPERTY(int index READ index)
372   Q_PROPERTY(QList<QCPLayerable*> children READ children)
373   Q_PROPERTY(bool visible READ visible WRITE setVisible)
374   /// \endcond
375 public:
376   QCPLayer(QCustomPlot* parentPlot, const QString &layerName);
377   ~QCPLayer();
378 
379   // getters:
380   QCustomPlot *parentPlot() const { return mParentPlot; }
381   QString name() const { return mName; }
382   int index() const { return mIndex; }
383   QList<QCPLayerable*> children() const { return mChildren; }
384   bool visible() const { return mVisible; }
385 
386   // setters:
387   void setVisible(bool visible);
388 
389 protected:
390   // property members:
391   QCustomPlot *mParentPlot;
392   QString mName;
393   int mIndex;
394   QList<QCPLayerable*> mChildren;
395   bool mVisible;
396 
397   // non-virtual methods:
398   void addChild(QCPLayerable *layerable, bool prepend);
399   void removeChild(QCPLayerable *layerable);
400 
401 private:
402   Q_DISABLE_COPY(QCPLayer)
403 
404   friend class QCustomPlot;
405   friend class QCPLayerable;
406 };
407 
408 class QCP_LIB_DECL QCPLayerable : public QObject
409 {
410   Q_OBJECT
411   /// \cond INCLUDE_QPROPERTIES
412   Q_PROPERTY(bool visible READ visible WRITE setVisible)
413   Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot)
414   Q_PROPERTY(QCPLayerable* parentLayerable READ parentLayerable)
415   Q_PROPERTY(QCPLayer* layer READ layer WRITE setLayer NOTIFY layerChanged)
416   Q_PROPERTY(bool antialiased READ antialiased WRITE setAntialiased)
417   /// \endcond
418 public:
419   QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=Q_NULLPTR);
420   ~QCPLayerable();
421 
422   // getters:
visible()423   bool visible() const { return mVisible; }
parentPlot()424   QCustomPlot *parentPlot() const { return mParentPlot; }
parentLayerable()425   QCPLayerable *parentLayerable() const { return mParentLayerable.data(); }
layer()426   QCPLayer *layer() const { return mLayer; }
antialiased()427   bool antialiased() const { return mAntialiased; }
428 
429   // setters:
430   void setVisible(bool on);
431   Q_SLOT bool setLayer(QCPLayer *layer);
432   bool setLayer(const QString &layerName);
433   void setAntialiased(bool enabled);
434 
435   // introduced virtual methods:
436   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
437 
438   // non-property methods:
439   bool realVisibility() const;
440 
441 signals:
442   void layerChanged(QCPLayer *newLayer);
443 
444 protected:
445   // property members:
446   bool mVisible;
447   QCustomPlot *mParentPlot;
448   QPointer<QCPLayerable> mParentLayerable;
449   QCPLayer *mLayer;
450   bool mAntialiased;
451 
452   // introduced virtual methods:
453   virtual void parentPlotInitialized(QCustomPlot *parentPlot);
454   virtual QCP::Interaction selectionCategory() const;
455   virtual QRect clipRect() const;
456   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const = 0;
457   virtual void draw(QCPPainter *painter) = 0;
458   // events:
459   virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged);
460   virtual void deselectEvent(bool *selectionStateChanged);
461 
462   // non-property methods:
463   void initializeParentPlot(QCustomPlot *parentPlot);
464   void setParentLayerable(QCPLayerable* parentLayerable);
465   bool moveToLayer(QCPLayer *layer, bool prepend);
466   void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const;
467 
468 private:
469   Q_DISABLE_COPY(QCPLayerable)
470 
471   friend class QCustomPlot;
472   friend class QCPAxisRect;
473 };
474 
475 
476 class QCP_LIB_DECL QCPRange
477 {
478 public:
479   double lower, upper;
480 
481   QCPRange();
482   QCPRange(double lower, double upper);
483 
484   bool operator==(const QCPRange& other) const { return lower == other.lower && upper == other.upper; }
485   bool operator!=(const QCPRange& other) const { return !(*this == other); }
486 
487   QCPRange &operator+=(const double& value) { lower+=value; upper+=value; return *this; }
488   QCPRange &operator-=(const double& value) { lower-=value; upper-=value; return *this; }
489   QCPRange &operator*=(const double& value) { lower*=value; upper*=value; return *this; }
490   QCPRange &operator/=(const double& value) { lower/=value; upper/=value; return *this; }
491   friend inline const QCPRange operator+(const QCPRange&, double);
492   friend inline const QCPRange operator+(double, const QCPRange&);
493   friend inline const QCPRange operator-(const QCPRange& range, double value);
494   friend inline const QCPRange operator*(const QCPRange& range, double value);
495   friend inline const QCPRange operator*(double value, const QCPRange& range);
496   friend inline const QCPRange operator/(const QCPRange& range, double value);
497 
498   double size() const;
499   double center() const;
500   void normalize();
501   void expand(const QCPRange &otherRange);
502   QCPRange expanded(const QCPRange &otherRange) const;
503   QCPRange sanitizedForLogScale() const;
504   QCPRange sanitizedForLinScale() const;
505   bool contains(double value) const;
506 
507   static bool validRange(double lower, double upper);
508   static bool validRange(const QCPRange &range);
509   static const double minRange; //1e-280;
510   static const double maxRange; //1e280;
511 };
512 Q_DECLARE_TYPEINFO(QCPRange, Q_MOVABLE_TYPE);
513 
514 /* documentation of inline functions */
515 
516 /*! \fn QCPRange &QCPRange::operator+=(const double& value)
517 
518   Adds \a value to both boundaries of the range.
519 */
520 
521 /*! \fn QCPRange &QCPRange::operator-=(const double& value)
522 
523   Subtracts \a value from both boundaries of the range.
524 */
525 
526 /*! \fn QCPRange &QCPRange::operator*=(const double& value)
527 
528   Multiplies both boundaries of the range by \a value.
529 */
530 
531 /*! \fn QCPRange &QCPRange::operator/=(const double& value)
532 
533   Divides both boundaries of the range by \a value.
534 */
535 
536 /* end documentation of inline functions */
537 
538 /*!
539   Adds \a value to both boundaries of the range.
540 */
541 inline const QCPRange operator+(const QCPRange& range, double value)
542 {
543   QCPRange result(range);
544   result += value;
545   return result;
546 }
547 
548 /*!
549   Adds \a value to both boundaries of the range.
550 */
551 inline const QCPRange operator+(double value, const QCPRange& range)
552 {
553   QCPRange result(range);
554   result += value;
555   return result;
556 }
557 
558 /*!
559   Subtracts \a value from both boundaries of the range.
560 */
561 inline const QCPRange operator-(const QCPRange& range, double value)
562 {
563   QCPRange result(range);
564   result -= value;
565   return result;
566 }
567 
568 /*!
569   Multiplies both boundaries of the range by \a value.
570 */
571 inline const QCPRange operator*(const QCPRange& range, double value)
572 {
573   QCPRange result(range);
574   result *= value;
575   return result;
576 }
577 
578 /*!
579   Multiplies both boundaries of the range by \a value.
580 */
581 inline const QCPRange operator*(double value, const QCPRange& range)
582 {
583   QCPRange result(range);
584   result *= value;
585   return result;
586 }
587 
588 /*!
589   Divides both boundaries of the range by \a value.
590 */
591 inline const QCPRange operator/(const QCPRange& range, double value)
592 {
593   QCPRange result(range);
594   result /= value;
595   return result;
596 }
597 
598 
599 class QCP_LIB_DECL QCPMarginGroup : public QObject
600 {
601   Q_OBJECT
602 public:
603   QCPMarginGroup(QCustomPlot *parentPlot);
604   ~QCPMarginGroup();
605 
606   // non-virtual methods:
elements(QCP::MarginSide side)607   QList<QCPLayoutElement*> elements(QCP::MarginSide side) const { return mChildren.value(side); }
608   bool isEmpty() const;
609   void clear();
610 
611 protected:
612   // non-property members:
613   QCustomPlot *mParentPlot;
614   QHash<QCP::MarginSide, QList<QCPLayoutElement*> > mChildren;
615 
616   // non-virtual methods:
617   int commonMargin(QCP::MarginSide side) const;
618   void addChild(QCP::MarginSide side, QCPLayoutElement *element);
619   void removeChild(QCP::MarginSide side, QCPLayoutElement *element);
620 
621 private:
622   Q_DISABLE_COPY(QCPMarginGroup)
623 
624   friend class QCPLayoutElement;
625 };
626 
627 
628 class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable
629 {
630   Q_OBJECT
631   /// \cond INCLUDE_QPROPERTIES
632   Q_PROPERTY(QCPLayout* layout READ layout)
633   Q_PROPERTY(QRect rect READ rect)
634   Q_PROPERTY(QRect outerRect READ outerRect WRITE setOuterRect)
635   Q_PROPERTY(QMargins margins READ margins WRITE setMargins)
636   Q_PROPERTY(QMargins minimumMargins READ minimumMargins WRITE setMinimumMargins)
637   Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize)
638   Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize)
639   /// \endcond
640 public:
641   /*!
642     Defines the phases of the update process, that happens just before a replot. At each phase,
643     \ref update is called with the according UpdatePhase value.
644   */
645   enum UpdatePhase { upPreparation ///< Phase used for any type of preparation that needs to be done before margin calculation and layout
646                      ,upMargins    ///< Phase in which the margins are calculated and set
647                      ,upLayout     ///< Final phase in which the layout system places the rects of the elements
648                    };
649   Q_ENUM(UpdatePhase)
650 
651   explicit QCPLayoutElement(QCustomPlot *parentPlot=Q_NULLPTR);
652   virtual ~QCPLayoutElement();
653 
654   // getters:
655   QCPLayout *layout() const { return mParentLayout; }
656   QRect rect() const { return mRect; }
657   QRect outerRect() const { return mOuterRect; }
658   QMargins margins() const { return mMargins; }
659   QMargins minimumMargins() const { return mMinimumMargins; }
660   QCP::MarginSides autoMargins() const { return mAutoMargins; }
661   QSize minimumSize() const { return mMinimumSize; }
662   QSize maximumSize() const { return mMaximumSize; }
663   QCPMarginGroup *marginGroup(QCP::MarginSide side) const { return mMarginGroups.value(side, static_cast<QCPMarginGroup*>(Q_NULLPTR)); }
664   QHash<QCP::MarginSide, QCPMarginGroup*> marginGroups() const { return mMarginGroups; }
665 
666   // setters:
667   void setOuterRect(const QRect &rect);
668   void setMargins(const QMargins &margins);
669   void setMinimumMargins(const QMargins &margins);
670   void setAutoMargins(QCP::MarginSides sides);
671   void setMinimumSize(const QSize &size);
672   void setMinimumSize(int width, int height);
673   void setMaximumSize(const QSize &size);
674   void setMaximumSize(int width, int height);
675   void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group);
676 
677   // introduced virtual methods:
678   virtual void update(UpdatePhase phase);
679   virtual QSize minimumSizeHint() const;
680   virtual QSize maximumSizeHint() const;
681   virtual QList<QCPLayoutElement*> elements(bool recursive) const;
682 
683   // reimplemented virtual methods:
684   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
685 
686 protected:
687   // property members:
688   QCPLayout *mParentLayout;
689   QSize mMinimumSize, mMaximumSize;
690   QRect mRect, mOuterRect;
691   QMargins mMargins, mMinimumMargins;
692   QCP::MarginSides mAutoMargins;
693   QHash<QCP::MarginSide, QCPMarginGroup*> mMarginGroups;
694 
695   // introduced virtual methods:
696   virtual int calculateAutoMargin(QCP::MarginSide side);
697   // events:
698   virtual void mousePressEvent(QMouseEvent *event) {Q_UNUSED(event)}
699   virtual void mouseMoveEvent(QMouseEvent *event) {Q_UNUSED(event)}
700   virtual void mouseReleaseEvent(QMouseEvent *event) {Q_UNUSED(event)}
701   virtual void mouseDoubleClickEvent(QMouseEvent *event) {Q_UNUSED(event)}
702   virtual void wheelEvent(QWheelEvent *event) {Q_UNUSED(event)}
703 
704   // reimplemented virtual methods:
705   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const { Q_UNUSED(painter) }
706   virtual void draw(QCPPainter *painter) { Q_UNUSED(painter) }
707   virtual void parentPlotInitialized(QCustomPlot *parentPlot);
708 
709 private:
710   Q_DISABLE_COPY(QCPLayoutElement)
711 
712   friend class QCustomPlot;
713   friend class QCPLayout;
714   friend class QCPMarginGroup;
715 };
716 
717 
718 class QCP_LIB_DECL QCPLayout : public QCPLayoutElement
719 {
720   Q_OBJECT
721 public:
722   explicit QCPLayout();
723 
724   // reimplemented virtual methods:
725   virtual void update(UpdatePhase phase);
726   virtual QList<QCPLayoutElement*> elements(bool recursive) const;
727 
728   // introduced virtual methods:
729   virtual int elementCount() const = 0;
730   virtual QCPLayoutElement* elementAt(int index) const = 0;
731   virtual QCPLayoutElement* takeAt(int index) = 0;
732   virtual bool take(QCPLayoutElement* element) = 0;
733   virtual void simplify();
734 
735   // non-virtual methods:
736   bool removeAt(int index);
737   bool remove(QCPLayoutElement* element);
738   void clear();
739 
740 protected:
741   // introduced virtual methods:
742   virtual void updateLayout();
743 
744   // non-virtual methods:
745   void sizeConstraintsChanged() const;
746   void adoptElement(QCPLayoutElement *el);
747   void releaseElement(QCPLayoutElement *el);
748   QVector<int> getSectionSizes(QVector<int> maxSizes, QVector<int> minSizes, QVector<double> stretchFactors, int totalSize) const;
749 
750 private:
751   Q_DISABLE_COPY(QCPLayout)
752   friend class QCPLayoutElement;
753 };
754 
755 
756 class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout
757 {
758   Q_OBJECT
759   /// \cond INCLUDE_QPROPERTIES
760   Q_PROPERTY(int rowCount READ rowCount)
761   Q_PROPERTY(int columnCount READ columnCount)
762   Q_PROPERTY(QList<double> columnStretchFactors READ columnStretchFactors WRITE setColumnStretchFactors)
763   Q_PROPERTY(QList<double> rowStretchFactors READ rowStretchFactors WRITE setRowStretchFactors)
764   Q_PROPERTY(int columnSpacing READ columnSpacing WRITE setColumnSpacing)
765   Q_PROPERTY(int rowSpacing READ rowSpacing WRITE setRowSpacing)
766   /// \endcond
767 public:
768   explicit QCPLayoutGrid();
769   virtual ~QCPLayoutGrid();
770 
771   // getters:
772   int rowCount() const;
773   int columnCount() const;
774   QList<double> columnStretchFactors() const { return mColumnStretchFactors; }
775   QList<double> rowStretchFactors() const { return mRowStretchFactors; }
776   int columnSpacing() const { return mColumnSpacing; }
777   int rowSpacing() const { return mRowSpacing; }
778 
779   // setters:
780   void setColumnStretchFactor(int column, double factor);
781   void setColumnStretchFactors(const QList<double> &factors);
782   void setRowStretchFactor(int row, double factor);
783   void setRowStretchFactors(const QList<double> &factors);
784   void setColumnSpacing(int pixels);
785   void setRowSpacing(int pixels);
786 
787   // reimplemented virtual methods:
788   virtual void updateLayout();
789   virtual int elementCount() const;
790   virtual QCPLayoutElement* elementAt(int index) const;
791   virtual QCPLayoutElement* takeAt(int index);
792   virtual bool take(QCPLayoutElement* element);
793   virtual QList<QCPLayoutElement*> elements(bool recursive) const;
794   virtual void simplify();
795   virtual QSize minimumSizeHint() const;
796   virtual QSize maximumSizeHint() const;
797 
798   // non-virtual methods:
799   QCPLayoutElement *element(int row, int column) const;
800   bool addElement(int row, int column, QCPLayoutElement *element);
801   bool hasElement(int row, int column);
802   void expandTo(int newRowCount, int newColumnCount);
803   void insertRow(int newIndex);
804   void insertColumn(int newIndex);
805 
806 protected:
807   // property members:
808   QList<QList<QCPLayoutElement*> > mElements;
809   QList<double> mColumnStretchFactors;
810   QList<double> mRowStretchFactors;
811   int mColumnSpacing, mRowSpacing;
812 
813   // non-virtual methods:
814   void getMinimumRowColSizes(QVector<int> *minColWidths, QVector<int> *minRowHeights) const;
815   void getMaximumRowColSizes(QVector<int> *maxColWidths, QVector<int> *maxRowHeights) const;
816 
817 private:
818   Q_DISABLE_COPY(QCPLayoutGrid)
819 };
820 
821 
822 class QCP_LIB_DECL QCPLayoutInset : public QCPLayout
823 {
824   Q_OBJECT
825 public:
826   /*!
827     Defines how the placement and sizing is handled for a certain element in a QCPLayoutInset.
828   */
829   enum InsetPlacement { ipFree            ///< The element may be positioned/sized arbitrarily, see \ref setInsetRect
830                         ,ipBorderAligned  ///< The element is aligned to one of the layout sides, see \ref setInsetAlignment
831                       };
832 
833   explicit QCPLayoutInset();
834   virtual ~QCPLayoutInset();
835 
836   // getters:
837   InsetPlacement insetPlacement(int index) const;
838   Qt::Alignment insetAlignment(int index) const;
839   QRectF insetRect(int index) const;
840 
841   // setters:
842   void setInsetPlacement(int index, InsetPlacement placement);
843   void setInsetAlignment(int index, Qt::Alignment alignment);
844   void setInsetRect(int index, const QRectF &rect);
845 
846   // reimplemented virtual methods:
847   virtual void updateLayout();
848   virtual int elementCount() const;
849   virtual QCPLayoutElement* elementAt(int index) const;
850   virtual QCPLayoutElement* takeAt(int index);
851   virtual bool take(QCPLayoutElement* element);
852   virtual void simplify() {}
853   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
854 
855   // non-virtual methods:
856   void addElement(QCPLayoutElement *element, Qt::Alignment alignment);
857   void addElement(QCPLayoutElement *element, const QRectF &rect);
858 
859 protected:
860   // property members:
861   QList<QCPLayoutElement*> mElements;
862   QList<InsetPlacement> mInsetPlacement;
863   QList<Qt::Alignment> mInsetAlignment;
864   QList<QRectF> mInsetRect;
865 
866 private:
867   Q_DISABLE_COPY(QCPLayoutInset)
868 };
869 
870 
871 class QCP_LIB_DECL QCPLineEnding
872 {
873   Q_GADGET
874 public:
875   /*!
876     Defines the type of ending decoration for line-like items, e.g. an arrow.
877 
878     \image html QCPLineEnding.png
879 
880     The width and length of these decorations can be controlled with the functions \ref setWidth
881     and \ref setLength. Some decorations like \ref esDisc, \ref esSquare, \ref esDiamond and \ref esBar only
882     support a width, the length property is ignored.
883 
884     \see QCPItemLine::setHead, QCPItemLine::setTail, QCPItemCurve::setHead, QCPItemCurve::setTail, QCPAxis::setLowerEnding, QCPAxis::setUpperEnding
885   */
886   enum EndingStyle { esNone          ///< No ending decoration
887                      ,esFlatArrow    ///< A filled arrow head with a straight/flat back (a triangle)
888                      ,esSpikeArrow   ///< A filled arrow head with an indented back
889                      ,esLineArrow    ///< A non-filled arrow head with open back
890                      ,esDisc         ///< A filled circle
891                      ,esSquare       ///< A filled square
892                      ,esDiamond      ///< A filled diamond (45° rotated square)
893                      ,esBar          ///< A bar perpendicular to the line
894                      ,esHalfBar      ///< A bar perpendicular to the line, pointing out to only one side (to which side can be changed with \ref setInverted)
895                      ,esSkewedBar    ///< A bar that is skewed (skew controllable via \ref setLength)
896                    };
897   Q_ENUM(EndingStyle)
898 
899   QCPLineEnding();
900   QCPLineEnding(EndingStyle style, double width=8, double length=10, bool inverted=false);
901 
902   // getters:
903   EndingStyle style() const { return mStyle; }
904   double width() const { return mWidth; }
905   double length() const { return mLength; }
906   bool inverted() const { return mInverted; }
907 
908   // setters:
909   void setStyle(EndingStyle style);
910   void setWidth(double width);
911   void setLength(double length);
912   void setInverted(bool inverted);
913 
914   // non-property methods:
915   double boundingDistance() const;
916   double realLength() const;
917   void draw(QCPPainter *painter, const QVector2D &pos, const QVector2D &dir) const;
918   void draw(QCPPainter *painter, const QVector2D &pos, double angle) const;
919 
920 protected:
921   // property members:
922   EndingStyle mStyle;
923   double mWidth, mLength;
924   bool mInverted;
925 };
926 Q_DECLARE_TYPEINFO(QCPLineEnding, Q_MOVABLE_TYPE);
927 
928 
929 class QCP_LIB_DECL QCPGrid :public QCPLayerable
930 {
931   Q_OBJECT
932   /// \cond INCLUDE_QPROPERTIES
933   Q_PROPERTY(bool subGridVisible READ subGridVisible WRITE setSubGridVisible)
934   Q_PROPERTY(bool antialiasedSubGrid READ antialiasedSubGrid WRITE setAntialiasedSubGrid)
935   Q_PROPERTY(bool antialiasedZeroLine READ antialiasedZeroLine WRITE setAntialiasedZeroLine)
936   Q_PROPERTY(QPen pen READ pen WRITE setPen)
937   Q_PROPERTY(QPen subGridPen READ subGridPen WRITE setSubGridPen)
938   Q_PROPERTY(QPen zeroLinePen READ zeroLinePen WRITE setZeroLinePen)
939   /// \endcond
940 public:
941   QCPGrid(QCPAxis *parentAxis);
942 
943   // getters:
944   bool subGridVisible() const { return mSubGridVisible; }
945   bool antialiasedSubGrid() const { return mAntialiasedSubGrid; }
946   bool antialiasedZeroLine() const { return mAntialiasedZeroLine; }
947   QPen pen() const { return mPen; }
948   QPen subGridPen() const { return mSubGridPen; }
949   QPen zeroLinePen() const { return mZeroLinePen; }
950 
951   // setters:
952   void setSubGridVisible(bool visible);
953   void setAntialiasedSubGrid(bool enabled);
954   void setAntialiasedZeroLine(bool enabled);
955   void setPen(const QPen &pen);
956   void setSubGridPen(const QPen &pen);
957   void setZeroLinePen(const QPen &pen);
958 
959 protected:
960   // property members:
961   bool mSubGridVisible;
962   bool mAntialiasedSubGrid, mAntialiasedZeroLine;
963   QPen mPen, mSubGridPen, mZeroLinePen;
964   // non-property members:
965   QCPAxis *mParentAxis;
966 
967   // reimplemented virtual methods:
968   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const;
969   virtual void draw(QCPPainter *painter);
970 
971   // non-virtual methods:
972   void drawGridLines(QCPPainter *painter) const;
973   void drawSubGridLines(QCPPainter *painter) const;
974 
975   friend class QCPAxis;
976 };
977 
978 
979 class QCP_LIB_DECL QCPAxis : public QCPLayerable
980 {
981   Q_OBJECT
982   /// \cond INCLUDE_QPROPERTIES
983   Q_PROPERTY(AxisType axisType READ axisType)
984   Q_PROPERTY(QCPAxisRect* axisRect READ axisRect)
985   Q_PROPERTY(ScaleType scaleType READ scaleType WRITE setScaleType NOTIFY scaleTypeChanged)
986   Q_PROPERTY(double scaleLogBase READ scaleLogBase WRITE setScaleLogBase)
987   Q_PROPERTY(QCPRange range READ range WRITE setRange NOTIFY rangeChanged)
988   Q_PROPERTY(bool rangeReversed READ rangeReversed WRITE setRangeReversed)
989   Q_PROPERTY(bool autoTicks READ autoTicks WRITE setAutoTicks)
990   Q_PROPERTY(int autoTickCount READ autoTickCount WRITE setAutoTickCount)
991   Q_PROPERTY(bool autoTickLabels READ autoTickLabels WRITE setAutoTickLabels)
992   Q_PROPERTY(bool autoTickStep READ autoTickStep WRITE setAutoTickStep)
993   Q_PROPERTY(bool autoSubTicks READ autoSubTicks WRITE setAutoSubTicks)
994   Q_PROPERTY(bool ticks READ ticks WRITE setTicks)
995   Q_PROPERTY(bool tickLabels READ tickLabels WRITE setTickLabels)
996   Q_PROPERTY(int tickLabelPadding READ tickLabelPadding WRITE setTickLabelPadding)
997   Q_PROPERTY(LabelType tickLabelType READ tickLabelType WRITE setTickLabelType)
998   Q_PROPERTY(QFont tickLabelFont READ tickLabelFont WRITE setTickLabelFont)
999   Q_PROPERTY(QColor tickLabelColor READ tickLabelColor WRITE setTickLabelColor)
1000   Q_PROPERTY(double tickLabelRotation READ tickLabelRotation WRITE setTickLabelRotation)
1001   Q_PROPERTY(LabelSide tickLabelSide READ tickLabelSide WRITE setTickLabelSide)
1002   Q_PROPERTY(QString dateTimeFormat READ dateTimeFormat WRITE setDateTimeFormat)
1003   Q_PROPERTY(Qt::TimeSpec dateTimeSpec READ dateTimeSpec WRITE setDateTimeSpec)
1004   Q_PROPERTY(QString numberFormat READ numberFormat WRITE setNumberFormat)
1005   Q_PROPERTY(int numberPrecision READ numberPrecision WRITE setNumberPrecision)
1006   Q_PROPERTY(double tickStep READ tickStep WRITE setTickStep)
1007   Q_PROPERTY(QVector<double> tickVector READ tickVector WRITE setTickVector)
1008   Q_PROPERTY(QVector<QString> tickVectorLabels READ tickVectorLabels WRITE setTickVectorLabels)
1009   Q_PROPERTY(int tickLengthIn READ tickLengthIn WRITE setTickLengthIn)
1010   Q_PROPERTY(int tickLengthOut READ tickLengthOut WRITE setTickLengthOut)
1011   Q_PROPERTY(int subTickCount READ subTickCount WRITE setSubTickCount)
1012   Q_PROPERTY(int subTickLengthIn READ subTickLengthIn WRITE setSubTickLengthIn)
1013   Q_PROPERTY(int subTickLengthOut READ subTickLengthOut WRITE setSubTickLengthOut)
1014   Q_PROPERTY(QPen basePen READ basePen WRITE setBasePen)
1015   Q_PROPERTY(QPen tickPen READ tickPen WRITE setTickPen)
1016   Q_PROPERTY(QPen subTickPen READ subTickPen WRITE setSubTickPen)
1017   Q_PROPERTY(QFont labelFont READ labelFont WRITE setLabelFont)
1018   Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor)
1019   Q_PROPERTY(QString label READ label WRITE setLabel)
1020   Q_PROPERTY(int labelPadding READ labelPadding WRITE setLabelPadding)
1021   Q_PROPERTY(int padding READ padding WRITE setPadding)
1022   Q_PROPERTY(int offset READ offset WRITE setOffset)
1023   Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectionChanged)
1024   Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectableChanged)
1025   Q_PROPERTY(QFont selectedTickLabelFont READ selectedTickLabelFont WRITE setSelectedTickLabelFont)
1026   Q_PROPERTY(QFont selectedLabelFont READ selectedLabelFont WRITE setSelectedLabelFont)
1027   Q_PROPERTY(QColor selectedTickLabelColor READ selectedTickLabelColor WRITE setSelectedTickLabelColor)
1028   Q_PROPERTY(QColor selectedLabelColor READ selectedLabelColor WRITE setSelectedLabelColor)
1029   Q_PROPERTY(QPen selectedBasePen READ selectedBasePen WRITE setSelectedBasePen)
1030   Q_PROPERTY(QPen selectedTickPen READ selectedTickPen WRITE setSelectedTickPen)
1031   Q_PROPERTY(QPen selectedSubTickPen READ selectedSubTickPen WRITE setSelectedSubTickPen)
1032   Q_PROPERTY(QCPLineEnding lowerEnding READ lowerEnding WRITE setLowerEnding)
1033   Q_PROPERTY(QCPLineEnding upperEnding READ upperEnding WRITE setUpperEnding)
1034   Q_PROPERTY(QCPGrid* grid READ grid)
1035   /// \endcond
1036 public:
1037   /*!
1038     Defines at which side of the axis rect the axis will appear. This also affects how the tick
1039     marks are drawn, on which side the labels are placed etc.
1040   */
1041   enum AxisType { atLeft    = 0x01  ///< <tt>0x01</tt> Axis is vertical and on the left side of the axis rect
1042                   ,atRight  = 0x02  ///< <tt>0x02</tt> Axis is vertical and on the right side of the axis rect
1043                   ,atTop    = 0x04  ///< <tt>0x04</tt> Axis is horizontal and on the top side of the axis rect
1044                   ,atBottom = 0x08  ///< <tt>0x08</tt> Axis is horizontal and on the bottom side of the axis rect
1045                 };
1046   Q_FLAGS(AxisType AxisTypes)
1047   Q_DECLARE_FLAGS(AxisTypes, AxisType)
1048   /*!
1049     When automatic tick label generation is enabled (\ref setAutoTickLabels), defines how the
1050     coordinate of the tick is interpreted, i.e. translated into a string.
1051 
1052     \see setTickLabelType
1053   */
1054   enum LabelType { ltNumber    ///< Tick coordinate is regarded as normal number and will be displayed as such. (see \ref setNumberFormat)
1055                    ,ltDateTime ///< Tick coordinate is regarded as a date/time (seconds since 1970-01-01T00:00:00 UTC) and will be displayed and formatted as such. (for details, see \ref setDateTimeFormat)
1056                  };
1057   Q_ENUM(LabelType)
1058   /*!
1059     Defines on which side of the axis the tick labels (numbers) shall appear.
1060 
1061     \see setTickLabelSide
1062   */
1063   enum LabelSide { lsInside    ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect
1064                    ,lsOutside  ///< Tick labels will be displayed outside the axis rect
1065                  };
1066   Q_ENUM(LabelSide)
1067   /*!
1068     Defines the scale of an axis.
1069     \see setScaleType
1070   */
1071   enum ScaleType { stLinear       ///< Linear scaling
1072                    ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed plots and (major) tick marks at every base power (see \ref setScaleLogBase).
1073                  };
1074   Q_ENUM(ScaleType)
1075   /*!
1076     Defines the selectable parts of an axis.
1077     \see setSelectableParts, setSelectedParts
1078   */
1079   enum SelectablePart { spNone        = 0      ///< None of the selectable parts
1080                         ,spAxis       = 0x001  ///< The axis backbone and tick marks
1081                         ,spTickLabels = 0x002  ///< Tick labels (numbers) of this axis (as a whole, not individually)
1082                         ,spAxisLabel  = 0x004  ///< The axis label
1083                       };
1084   Q_FLAGS(SelectablePart SelectableParts)
1085   Q_DECLARE_FLAGS(SelectableParts, SelectablePart)
1086 
1087   explicit QCPAxis(QCPAxisRect *parent, AxisType type);
1088   virtual ~QCPAxis();
1089 
1090   // getters:
1091   AxisType axisType() const { return mAxisType; }
1092   QCPAxisRect *axisRect() const { return mAxisRect; }
1093   ScaleType scaleType() const { return mScaleType; }
1094   double scaleLogBase() const { return mScaleLogBase; }
1095   const QCPRange range() const { return mRange; }
1096   bool rangeReversed() const { return mRangeReversed; }
1097   bool autoTicks() const { return mAutoTicks; }
1098   int autoTickCount() const { return mAutoTickCount; }
1099   bool autoTickLabels() const { return mAutoTickLabels; }
1100   bool autoTickStep() const { return mAutoTickStep; }
1101   bool autoSubTicks() const { return mAutoSubTicks; }
1102   bool ticks() const { return mTicks; }
1103   bool tickLabels() const { return mTickLabels; }
1104   int tickLabelPadding() const;
1105   LabelType tickLabelType() const { return mTickLabelType; }
1106   QFont tickLabelFont() const { return mTickLabelFont; }
1107   QColor tickLabelColor() const { return mTickLabelColor; }
1108   double tickLabelRotation() const;
1109   LabelSide tickLabelSide() const;
1110   QString dateTimeFormat() const { return mDateTimeFormat; }
1111   Qt::TimeSpec dateTimeSpec() const { return mDateTimeSpec; }
1112   QString numberFormat() const;
1113   int numberPrecision() const { return mNumberPrecision; }
1114   double tickStep() const { return mTickStep; }
1115   QVector<double> tickVector() const { return mTickVector; }
1116   QVector<QString> tickVectorLabels() const { return mTickVectorLabels; }
1117   int tickLengthIn() const;
1118   int tickLengthOut() const;
1119   int subTickCount() const { return mSubTickCount; }
1120   int subTickLengthIn() const;
1121   int subTickLengthOut() const;
1122   QPen basePen() const { return mBasePen; }
1123   QPen tickPen() const { return mTickPen; }
1124   QPen subTickPen() const { return mSubTickPen; }
1125   QFont labelFont() const { return mLabelFont; }
1126   QColor labelColor() const { return mLabelColor; }
1127   QString label() const { return mLabel; }
1128   int labelPadding() const;
1129   int padding() const { return mPadding; }
1130   int offset() const;
1131   SelectableParts selectedParts() const { return mSelectedParts; }
1132   SelectableParts selectableParts() const { return mSelectableParts; }
1133   QFont selectedTickLabelFont() const { return mSelectedTickLabelFont; }
1134   QFont selectedLabelFont() const { return mSelectedLabelFont; }
1135   QColor selectedTickLabelColor() const { return mSelectedTickLabelColor; }
1136   QColor selectedLabelColor() const { return mSelectedLabelColor; }
1137   QPen selectedBasePen() const { return mSelectedBasePen; }
1138   QPen selectedTickPen() const { return mSelectedTickPen; }
1139   QPen selectedSubTickPen() const { return mSelectedSubTickPen; }
1140   QCPLineEnding lowerEnding() const;
1141   QCPLineEnding upperEnding() const;
1142   QCPGrid *grid() const { return mGrid; }
1143 
1144   // setters:
1145   Q_SLOT void setScaleType(QCPAxis::ScaleType type);
1146   void setScaleLogBase(double base);
1147   Q_SLOT void setRange(const QCPRange &range);
1148   void setRange(double lower, double upper);
1149   void setRange(double position, double size, Qt::AlignmentFlag alignment);
1150   void setRangeLower(double lower);
1151   void setRangeUpper(double upper);
1152   void setRangeReversed(bool reversed);
1153   void setAutoTicks(bool on);
1154   void setAutoTickCount(int approximateCount);
1155   void setAutoTickLabels(bool on);
1156   void setAutoTickStep(bool on);
1157   void setAutoSubTicks(bool on);
1158   void setTicks(bool show);
1159   void setTickLabels(bool show);
1160   void setTickLabelPadding(int padding);
1161   void setTickLabelType(LabelType type);
1162   void setTickLabelFont(const QFont &font);
1163   void setTickLabelColor(const QColor &color);
1164   void setTickLabelRotation(double degrees);
1165   void setTickLabelSide(LabelSide side);
1166   void setDateTimeFormat(const QString &format);
1167   void setDateTimeSpec(const Qt::TimeSpec &timeSpec);
1168   void setNumberFormat(const QString &formatCode);
1169   void setNumberPrecision(int precision);
1170   void setTickStep(double step);
1171   void setTickVector(const QVector<double> &vec);
1172   void setTickVectorLabels(const QVector<QString> &vec);
1173   void setTickLength(int inside, int outside=0);
1174   void setTickLengthIn(int inside);
1175   void setTickLengthOut(int outside);
1176   void setSubTickCount(int count);
1177   void setSubTickLength(int inside, int outside=0);
1178   void setSubTickLengthIn(int inside);
1179   void setSubTickLengthOut(int outside);
1180   void setBasePen(const QPen &pen);
1181   void setTickPen(const QPen &pen);
1182   void setSubTickPen(const QPen &pen);
1183   void setLabelFont(const QFont &font);
1184   void setLabelColor(const QColor &color);
1185   void setLabel(const QString &str);
1186   void setLabelPadding(int padding);
1187   void setPadding(int padding);
1188   void setOffset(int offset);
1189   void setSelectedTickLabelFont(const QFont &font);
1190   void setSelectedLabelFont(const QFont &font);
1191   void setSelectedTickLabelColor(const QColor &color);
1192   void setSelectedLabelColor(const QColor &color);
1193   void setSelectedBasePen(const QPen &pen);
1194   void setSelectedTickPen(const QPen &pen);
1195   void setSelectedSubTickPen(const QPen &pen);
1196   Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts);
1197   Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts);
1198   void setLowerEnding(const QCPLineEnding &ending);
1199   void setUpperEnding(const QCPLineEnding &ending);
1200 
1201   // reimplemented virtual methods:
1202   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
1203 
1204   // non-property methods:
1205   Qt::Orientation orientation() const { return mOrientation; }
1206   void moveRange(double diff);
1207   void scaleRange(double factor, double center);
1208   void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0);
1209   void rescale(bool onlyVisiblePlottables=false);
1210   double pixelToCoord(double value) const;
1211   double coordToPixel(double value) const;
1212   SelectablePart getPartAt(const QPointF &pos) const;
1213   QList<QCPAbstractPlottable*> plottables() const;
1214   QList<QCPGraph*> graphs() const;
1215   QList<QCPAbstractItem*> items() const;
1216 
1217   static AxisType marginSideToAxisType(QCP::MarginSide side);
1218   static Qt::Orientation orientation(AxisType type) { return type==atBottom||type==atTop ? Qt::Horizontal : Qt::Vertical; }
1219   static AxisType opposite(AxisType type);
1220 
1221 signals:
1222   void ticksRequest();
1223   void rangeChanged(const QCPRange &newRange);
1224   void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange);
1225   void scaleTypeChanged(QCPAxis::ScaleType scaleType);
1226   void selectionChanged(const QCPAxis::SelectableParts &parts);
1227   void selectableChanged(const QCPAxis::SelectableParts &parts);
1228 
1229 protected:
1230   // property members:
1231   // axis base:
1232   AxisType mAxisType;
1233   QCPAxisRect *mAxisRect;
1234   //int mOffset; // in QCPAxisPainter
1235   int mPadding;
1236   Qt::Orientation mOrientation;
1237   SelectableParts mSelectableParts, mSelectedParts;
1238   QPen mBasePen, mSelectedBasePen;
1239   //QCPLineEnding mLowerEnding, mUpperEnding; // in QCPAxisPainter
1240   // axis label:
1241   //int mLabelPadding; // in QCPAxisPainter
1242   QString mLabel;
1243   QFont mLabelFont, mSelectedLabelFont;
1244   QColor mLabelColor, mSelectedLabelColor;
1245   // tick labels:
1246   //int mTickLabelPadding; // in QCPAxisPainter
1247   bool mTickLabels, mAutoTickLabels;
1248   //double mTickLabelRotation; // in QCPAxisPainter
1249   LabelType mTickLabelType;
1250   QFont mTickLabelFont, mSelectedTickLabelFont;
1251   QColor mTickLabelColor, mSelectedTickLabelColor;
1252   QString mDateTimeFormat;
1253   Qt::TimeSpec mDateTimeSpec;
1254   int mNumberPrecision;
1255   QLatin1Char mNumberFormatChar;
1256   bool mNumberBeautifulPowers;
1257   //bool mNumberMultiplyCross; // QCPAxisPainter
1258   // ticks and subticks:
1259   bool mTicks;
1260   double mTickStep;
1261   int mSubTickCount, mAutoTickCount;
1262   bool mAutoTicks, mAutoTickStep, mAutoSubTicks;
1263   //int mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut; // QCPAxisPainter
1264   QPen mTickPen, mSelectedTickPen;
1265   QPen mSubTickPen, mSelectedSubTickPen;
1266   // scale and range:
1267   QCPRange mRange;
1268   bool mRangeReversed;
1269   ScaleType mScaleType;
1270   double mScaleLogBase, mScaleLogBaseLogInv;
1271 
1272   // non-property members:
1273   QCPGrid *mGrid;
1274   QCPAxisPainterPrivate *mAxisPainter;
1275   int mLowestVisibleTick, mHighestVisibleTick;
1276   QVector<double> mTickVector;
1277   QVector<QString> mTickVectorLabels;
1278   QVector<double> mSubTickVector;
1279   bool mCachedMarginValid;
1280   int mCachedMargin;
1281 
1282   // introduced virtual methods:
1283   virtual void setupTickVectors();
1284   virtual void generateAutoTicks();
1285   virtual int calculateAutoSubTickCount(double tickStep) const;
1286   virtual int calculateMargin();
1287 
1288   // reimplemented virtual methods:
1289   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const;
1290   virtual void draw(QCPPainter *painter);
1291   virtual QCP::Interaction selectionCategory() const;
1292   // events:
1293   virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged);
1294   virtual void deselectEvent(bool *selectionStateChanged);
1295 
1296   // non-virtual methods:
1297   void visibleTickBounds(int &lowIndex, int &highIndex) const;
1298   double baseLog(double value) const;
1299   double basePow(double value) const;
1300   QPen getBasePen() const;
1301   QPen getTickPen() const;
1302   QPen getSubTickPen() const;
1303   QFont getTickLabelFont() const;
1304   QFont getLabelFont() const;
1305   QColor getTickLabelColor() const;
1306   QColor getLabelColor() const;
1307 
1308 private:
1309   Q_DISABLE_COPY(QCPAxis)
1310 
1311   friend class QCustomPlot;
1312   friend class QCPGrid;
1313   friend class QCPAxisRect;
1314 };
1315 Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::SelectableParts)
1316 Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::AxisTypes)
1317 Q_DECLARE_METATYPE(QCPAxis::SelectablePart)
1318 
1319 
1320 class QCPAxisPainterPrivate
1321 {
1322 public:
1323   explicit QCPAxisPainterPrivate(QCustomPlot *parentPlot);
1324   virtual ~QCPAxisPainterPrivate();
1325 
1326   virtual void draw(QCPPainter *painter);
1327   virtual int size() const;
1328   void clearCache();
1329 
1330   QRect axisSelectionBox() const { return mAxisSelectionBox; }
1331   QRect tickLabelsSelectionBox() const { return mTickLabelsSelectionBox; }
1332   QRect labelSelectionBox() const { return mLabelSelectionBox; }
1333 
1334   // public property members:
1335   QCPAxis::AxisType type;
1336   QPen basePen;
1337   QCPLineEnding lowerEnding, upperEnding; // directly accessed by QCPAxis setters/getters
1338   int labelPadding; // directly accessed by QCPAxis setters/getters
1339   QFont labelFont;
1340   QColor labelColor;
1341   QString label;
1342   int tickLabelPadding; // directly accessed by QCPAxis setters/getters
1343   double tickLabelRotation; // directly accessed by QCPAxis setters/getters
1344   QCPAxis::LabelSide tickLabelSide; // directly accessed by QCPAxis setters/getters
1345   bool substituteExponent;
1346   bool numberMultiplyCross; // directly accessed by QCPAxis setters/getters
1347   int tickLengthIn, tickLengthOut, subTickLengthIn, subTickLengthOut; // directly accessed by QCPAxis setters/getters
1348   QPen tickPen, subTickPen;
1349   QFont tickLabelFont;
1350   QColor tickLabelColor;
1351   QRect axisRect, viewportRect;
1352   double offset; // directly accessed by QCPAxis setters/getters
1353   bool abbreviateDecimalPowers;
1354   bool reversedEndings;
1355 
1356   QVector<double> subTickPositions;
1357   QVector<double> tickPositions;
1358   QVector<QString> tickLabels;
1359 
1360 protected:
1361   struct CachedLabel
1362   {
1363     QPointF offset;
1364     QPixmap pixmap;
1365   };
1366   struct TickLabelData
1367   {
1368     QString basePart, expPart;
1369     QRect baseBounds, expBounds, totalBounds, rotatedTotalBounds;
1370     QFont baseFont, expFont;
1371   };
1372   QCustomPlot *mParentPlot;
1373   QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters
1374   QCache<QString, CachedLabel> mLabelCache;
1375   QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox;
1376 
1377   virtual QByteArray generateLabelParameterHash() const;
1378 
1379   virtual void placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize);
1380   virtual void drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const;
1381   virtual TickLabelData getTickLabelData(const QFont &font, const QString &text) const;
1382   virtual QPointF getTickLabelDrawOffset(const TickLabelData &labelData) const;
1383   virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const;
1384 };
1385 
1386 
1387 class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable
1388 {
1389   Q_OBJECT
1390   /// \cond INCLUDE_QPROPERTIES
1391   Q_PROPERTY(QString name READ name WRITE setName)
1392   Q_PROPERTY(bool antialiasedFill READ antialiasedFill WRITE setAntialiasedFill)
1393   Q_PROPERTY(bool antialiasedScatters READ antialiasedScatters WRITE setAntialiasedScatters)
1394   Q_PROPERTY(bool antialiasedErrorBars READ antialiasedErrorBars WRITE setAntialiasedErrorBars)
1395   Q_PROPERTY(QPen pen READ pen WRITE setPen)
1396   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
1397   Q_PROPERTY(QBrush brush READ brush WRITE setBrush)
1398   Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush)
1399   Q_PROPERTY(QCPAxis* keyAxis READ keyAxis WRITE setKeyAxis)
1400   Q_PROPERTY(QCPAxis* valueAxis READ valueAxis WRITE setValueAxis)
1401   Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged)
1402   Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged)
1403   /// \endcond
1404 public:
1405   QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis);
1406 
1407   // getters:
1408   QString name() const { return mName; }
1409   bool antialiasedFill() const { return mAntialiasedFill; }
1410   bool antialiasedScatters() const { return mAntialiasedScatters; }
1411   bool antialiasedErrorBars() const { return mAntialiasedErrorBars; }
1412   QPen pen() const { return mPen; }
1413   QPen selectedPen() const { return mSelectedPen; }
1414   QBrush brush() const { return mBrush; }
1415   QBrush selectedBrush() const { return mSelectedBrush; }
1416   QCPAxis *keyAxis() const { return mKeyAxis.data(); }
1417   QCPAxis *valueAxis() const { return mValueAxis.data(); }
1418   bool selectable() const { return mSelectable; }
1419   bool selected() const { return mSelected; }
1420 
1421   // setters:
1422   void setName(const QString &name);
1423   void setAntialiasedFill(bool enabled);
1424   void setAntialiasedScatters(bool enabled);
1425   void setAntialiasedErrorBars(bool enabled);
1426   void setPen(const QPen &pen);
1427   void setSelectedPen(const QPen &pen);
1428   void setBrush(const QBrush &brush);
1429   void setSelectedBrush(const QBrush &brush);
1430   void setKeyAxis(QCPAxis *axis);
1431   void setValueAxis(QCPAxis *axis);
1432   Q_SLOT void setSelectable(bool selectable);
1433   Q_SLOT void setSelected(bool selected);
1434 
1435   // introduced virtual methods:
1436   virtual void clearData() = 0;
1437   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const = 0;
1438   virtual bool addToLegend();
1439   virtual bool removeFromLegend() const;
1440 
1441   // non-property methods:
1442   void rescaleAxes(bool onlyEnlarge=false) const;
1443   void rescaleKeyAxis(bool onlyEnlarge=false) const;
1444   void rescaleValueAxis(bool onlyEnlarge=false) const;
1445 
1446 signals:
1447   void selectionChanged(bool selected);
1448   void selectableChanged(bool selectable);
1449 
1450 protected:
1451   /*!
1452     Represents negative and positive sign domain for passing to \ref getKeyRange and \ref getValueRange.
1453   */
1454   enum SignDomain { sdNegative  ///< The negative sign domain, i.e. numbers smaller than zero
1455                     ,sdBoth     ///< Both sign domains, including zero, i.e. all (rational) numbers
1456                     ,sdPositive ///< The positive sign domain, i.e. numbers greater than zero
1457                   };
1458 
1459   // property members:
1460   QString mName;
1461   bool mAntialiasedFill, mAntialiasedScatters, mAntialiasedErrorBars;
1462   QPen mPen, mSelectedPen;
1463   QBrush mBrush, mSelectedBrush;
1464   QPointer<QCPAxis> mKeyAxis, mValueAxis;
1465   bool mSelectable, mSelected;
1466 
1467   // reimplemented virtual methods:
1468   virtual QRect clipRect() const;
1469   virtual void draw(QCPPainter *painter) = 0;
1470   virtual QCP::Interaction selectionCategory() const;
1471   void applyDefaultAntialiasingHint(QCPPainter *painter) const;
1472   // events:
1473   virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged);
1474   virtual void deselectEvent(bool *selectionStateChanged);
1475 
1476   // introduced virtual methods:
1477   virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const = 0;
1478   virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const = 0;
1479   virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const = 0;
1480 
1481   // non-virtual methods:
1482   void coordsToPixels(double key, double value, double &x, double &y) const;
1483   const QPointF coordsToPixels(double key, double value) const;
1484   void pixelsToCoords(double x, double y, double &key, double &value) const;
1485   void pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const;
1486   QPen mainPen() const;
1487   QBrush mainBrush() const;
1488   void applyFillAntialiasingHint(QCPPainter *painter) const;
1489   void applyScattersAntialiasingHint(QCPPainter *painter) const;
1490   void applyErrorBarsAntialiasingHint(QCPPainter *painter) const;
1491   double distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const;
1492 
1493 private:
1494   Q_DISABLE_COPY(QCPAbstractPlottable)
1495 
1496   friend class QCustomPlot;
1497   friend class QCPAxis;
1498   friend class QCPPlottableLegendItem;
1499 };
1500 
1501 
1502 class QCP_LIB_DECL QCPItemAnchor
1503 {
1504 public:
1505   QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString name, int anchorId=-1);
1506   virtual ~QCPItemAnchor();
1507 
1508   // getters:
1509   QString name() const { return mName; }
1510   virtual QPointF pixelPoint() const;
1511 
1512 protected:
1513   // property members:
1514   QString mName;
1515 
1516   // non-property members:
1517   QCustomPlot *mParentPlot;
1518   QCPAbstractItem *mParentItem;
1519   int mAnchorId;
1520   QSet<QCPItemPosition*> mChildrenX, mChildrenY;
1521 
1522   // introduced virtual methods:
1523   virtual QCPItemPosition *toQCPItemPosition() { return Q_NULLPTR; }
1524 
1525   // non-virtual methods:
1526   void addChildX(QCPItemPosition* pos); // called from pos when this anchor is set as parent
1527   void removeChildX(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted
1528   void addChildY(QCPItemPosition* pos); // called from pos when this anchor is set as parent
1529   void removeChildY(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted
1530 
1531 private:
1532   Q_DISABLE_COPY(QCPItemAnchor)
1533 
1534   friend class QCPItemPosition;
1535 };
1536 
1537 
1538 
1539 class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor
1540 {
1541 public:
1542   /*!
1543     Defines the ways an item position can be specified. Thus it defines what the numbers passed to
1544     \ref setCoords actually mean.
1545 
1546     \see setType
1547   */
1548   enum PositionType { ptAbsolute        ///< Static positioning in pixels, starting from the top left corner of the viewport/widget.
1549                       ,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
1550                                         ///< 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
1551                                         ///< vertically at the top of the viewport/widget, etc.
1552                       ,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
1553                                         ///< 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
1554                                         ///< 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.
1555                       ,ptPlotCoords     ///< Dynamic positioning at a plot coordinate defined by two axes (see \ref setAxes).
1556                     };
1557 
1558   QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString name);
1559   virtual ~QCPItemPosition();
1560 
1561   // getters:
1562   PositionType type() const { return typeX(); }
1563   PositionType typeX() const { return mPositionTypeX; }
1564   PositionType typeY() const { return mPositionTypeY; }
1565   QCPItemAnchor *parentAnchor() const { return parentAnchorX(); }
1566   QCPItemAnchor *parentAnchorX() const { return mParentAnchorX; }
1567   QCPItemAnchor *parentAnchorY() const { return mParentAnchorY; }
1568   double key() const { return mKey; }
1569   double value() const { return mValue; }
1570   QPointF coords() const { return QPointF(mKey, mValue); }
1571   QCPAxis *keyAxis() const { return mKeyAxis.data(); }
1572   QCPAxis *valueAxis() const { return mValueAxis.data(); }
1573   QCPAxisRect *axisRect() const;
1574   virtual QPointF pixelPoint() const;
1575 
1576   // setters:
1577   void setType(PositionType type);
1578   void setTypeX(PositionType type);
1579   void setTypeY(PositionType type);
1580   bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false);
1581   bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false);
1582   bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false);
1583   void setCoords(double key, double value);
1584   void setCoords(const QPointF &coords);
1585   void setAxes(QCPAxis* keyAxis, QCPAxis* valueAxis);
1586   void setAxisRect(QCPAxisRect *axisRect);
1587   void setPixelPoint(const QPointF &pixelPoint);
1588 
1589 protected:
1590   // property members:
1591   PositionType mPositionTypeX, mPositionTypeY;
1592   QPointer<QCPAxis> mKeyAxis, mValueAxis;
1593   QPointer<QCPAxisRect> mAxisRect;
1594   double mKey, mValue;
1595   QCPItemAnchor *mParentAnchorX, *mParentAnchorY;
1596 
1597   // reimplemented virtual methods:
1598   virtual QCPItemPosition *toQCPItemPosition() { return this; }
1599 
1600 private:
1601   Q_DISABLE_COPY(QCPItemPosition)
1602 };
1603 
1604 
1605 class QCP_LIB_DECL QCPAbstractItem : public QCPLayerable
1606 {
1607   Q_OBJECT
1608   /// \cond INCLUDE_QPROPERTIES
1609   Q_PROPERTY(bool clipToAxisRect READ clipToAxisRect WRITE setClipToAxisRect)
1610   Q_PROPERTY(QCPAxisRect* clipAxisRect READ clipAxisRect WRITE setClipAxisRect)
1611   Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged)
1612   Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged)
1613   /// \endcond
1614 public:
1615   QCPAbstractItem(QCustomPlot *parentPlot);
1616   virtual ~QCPAbstractItem();
1617 
1618   // getters:
1619   bool clipToAxisRect() const { return mClipToAxisRect; }
1620   QCPAxisRect *clipAxisRect() const;
1621   bool selectable() const { return mSelectable; }
1622   bool selected() const { return mSelected; }
1623 
1624   // setters:
1625   void setClipToAxisRect(bool clip);
1626   void setClipAxisRect(QCPAxisRect *rect);
1627   Q_SLOT void setSelectable(bool selectable);
1628   Q_SLOT void setSelected(bool selected);
1629 
1630   // reimplemented virtual methods:
1631   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const = 0;
1632 
1633   // non-virtual methods:
1634   QList<QCPItemPosition*> positions() const { return mPositions; }
1635   QList<QCPItemAnchor*> anchors() const { return mAnchors; }
1636   QCPItemPosition *position(const QString &name) const;
1637   QCPItemAnchor *anchor(const QString &name) const;
1638   bool hasAnchor(const QString &name) const;
1639 
1640 signals:
1641   void selectionChanged(bool selected);
1642   void selectableChanged(bool selectable);
1643 
1644 protected:
1645   // property members:
1646   bool mClipToAxisRect;
1647   QPointer<QCPAxisRect> mClipAxisRect;
1648   QList<QCPItemPosition*> mPositions;
1649   QList<QCPItemAnchor*> mAnchors;
1650   bool mSelectable, mSelected;
1651 
1652   // reimplemented virtual methods:
1653   virtual QCP::Interaction selectionCategory() const;
1654   virtual QRect clipRect() const;
1655   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const;
1656   virtual void draw(QCPPainter *painter) = 0;
1657   // events:
1658   virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged);
1659   virtual void deselectEvent(bool *selectionStateChanged);
1660 
1661   // introduced virtual methods:
1662   virtual QPointF anchorPixelPoint(int anchorId) const;
1663 
1664   // non-virtual methods:
1665   double distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const;
1666   double rectSelectTest(const QRectF &rect, const QPointF &pos, bool filledRect) const;
1667   QCPItemPosition *createPosition(const QString &name);
1668   QCPItemAnchor *createAnchor(const QString &name, int anchorId);
1669 
1670 private:
1671   Q_DISABLE_COPY(QCPAbstractItem)
1672 
1673   friend class QCustomPlot;
1674   friend class QCPItemAnchor;
1675 };
1676 
1677 
1678 class QCP_LIB_DECL QCustomPlot : public QWidget
1679 {
1680   Q_OBJECT
1681   /// \cond INCLUDE_QPROPERTIES
1682   Q_PROPERTY(QRect viewport READ viewport WRITE setViewport)
1683   Q_PROPERTY(QPixmap background READ background WRITE setBackground)
1684   Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled)
1685   Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode)
1686   Q_PROPERTY(QCPLayoutGrid* plotLayout READ plotLayout)
1687   Q_PROPERTY(bool autoAddPlottableToLegend READ autoAddPlottableToLegend WRITE setAutoAddPlottableToLegend)
1688   Q_PROPERTY(int selectionTolerance READ selectionTolerance WRITE setSelectionTolerance)
1689   Q_PROPERTY(bool noAntialiasingOnDrag READ noAntialiasingOnDrag WRITE setNoAntialiasingOnDrag)
1690   Q_PROPERTY(Qt::KeyboardModifier multiSelectModifier READ multiSelectModifier WRITE setMultiSelectModifier)
1691   /// \endcond
1692 public:
1693   /*!
1694     Defines how a layer should be inserted relative to an other layer.
1695 
1696     \see addLayer, moveLayer
1697   */
1698   enum LayerInsertMode { limBelow  ///< Layer is inserted below other layer
1699                          ,limAbove ///< Layer is inserted above other layer
1700                        };
1701   Q_ENUM(LayerInsertMode)
1702 
1703   /*!
1704     Defines with what timing the QCustomPlot surface is refreshed after a replot.
1705 
1706     \see replot
1707   */
1708   enum RefreshPriority { rpImmediate ///< The QCustomPlot surface is immediately refreshed, by calling QWidget::repaint() after the replot
1709                          ,rpQueued   ///< Queues the refresh such that it is performed at a slightly delayed point in time after the replot, by calling QWidget::update() after the replot
1710                          ,rpHint     ///< Whether to use immediate repaint or queued update depends on whether the plotting hint \ref QCP::phForceRepaint is set, see \ref setPlottingHints.
1711                        };
1712 
1713   explicit QCustomPlot(QWidget *parent = Q_NULLPTR);
1714   virtual ~QCustomPlot();
1715 
1716   // getters:
1717   QRect viewport() const { return mViewport; }
1718   QPixmap background() const { return mBackgroundPixmap; }
1719   bool backgroundScaled() const { return mBackgroundScaled; }
1720   Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; }
1721   QCPLayoutGrid *plotLayout() const { return mPlotLayout; }
1722   QCP::AntialiasedElements antialiasedElements() const { return mAntialiasedElements; }
1723   QCP::AntialiasedElements notAntialiasedElements() const { return mNotAntialiasedElements; }
1724   bool autoAddPlottableToLegend() const { return mAutoAddPlottableToLegend; }
1725   const QCP::Interactions interactions() const { return mInteractions; }
1726   int selectionTolerance() const { return mSelectionTolerance; }
1727   bool noAntialiasingOnDrag() const { return mNoAntialiasingOnDrag; }
1728   QCP::PlottingHints plottingHints() const { return mPlottingHints; }
1729   Qt::KeyboardModifier multiSelectModifier() const { return mMultiSelectModifier; }
1730 
1731   // setters:
1732   void setViewport(const QRect &rect);
1733   void setBackground(const QPixmap &pm);
1734   void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding);
1735   void setBackground(const QBrush &brush);
1736   void setBackgroundScaled(bool scaled);
1737   void setBackgroundScaledMode(Qt::AspectRatioMode mode);
1738   void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements);
1739   void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true);
1740   void setNotAntialiasedElements(const QCP::AntialiasedElements &notAntialiasedElements);
1741   void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true);
1742   void setAutoAddPlottableToLegend(bool on);
1743   void setInteractions(const QCP::Interactions &interactions);
1744   void setInteraction(const QCP::Interaction &interaction, bool enabled=true);
1745   void setSelectionTolerance(int pixels);
1746   void setNoAntialiasingOnDrag(bool enabled);
1747   void setPlottingHints(const QCP::PlottingHints &hints);
1748   void setPlottingHint(QCP::PlottingHint hint, bool enabled=true);
1749   void setMultiSelectModifier(Qt::KeyboardModifier modifier);
1750 
1751   // non-property methods:
1752   // plottable interface:
1753   QCPAbstractPlottable *plottable(int index);
1754   QCPAbstractPlottable *plottable();
1755   bool addPlottable(QCPAbstractPlottable *plottable);
1756   bool removePlottable(QCPAbstractPlottable *plottable);
1757   bool removePlottable(int index);
1758   int clearPlottables();
1759   int plottableCount() const;
1760   QList<QCPAbstractPlottable*> selectedPlottables() const;
1761   QCPAbstractPlottable *plottableAt(const QPointF &pos, bool onlySelectable=false) const;
1762   bool hasPlottable(QCPAbstractPlottable *plottable) const;
1763 
1764   // specialized interface for QCPGraph:
1765   QCPGraph *graph(int index) const;
1766   QCPGraph *graph() const;
1767   QCPGraph *addGraph(QCPAxis *keyAxis=Q_NULLPTR, QCPAxis *valueAxis=Q_NULLPTR);
1768   bool removeGraph(QCPGraph *graph);
1769   bool removeGraph(int index);
1770   int clearGraphs();
1771   int graphCount() const;
1772   QList<QCPGraph*> selectedGraphs() const;
1773 
1774   // item interface:
1775   QCPAbstractItem *item(int index) const;
1776   QCPAbstractItem *item() const;
1777   bool addItem(QCPAbstractItem* item);
1778   bool removeItem(QCPAbstractItem *item);
1779   bool removeItem(int index);
1780   int clearItems();
1781   int itemCount() const;
1782   QList<QCPAbstractItem*> selectedItems() const;
1783   QCPAbstractItem *itemAt(const QPointF &pos, bool onlySelectable=false) const;
1784   bool hasItem(QCPAbstractItem *item) const;
1785 
1786   // layer interface:
1787   QCPLayer *layer(const QString &name) const;
1788   QCPLayer *layer(int index) const;
1789   QCPLayer *currentLayer() const;
1790   bool setCurrentLayer(const QString &name);
1791   bool setCurrentLayer(QCPLayer *layer);
1792   int layerCount() const;
1793   bool addLayer(const QString &name, QCPLayer *otherLayer=Q_NULLPTR, LayerInsertMode insertMode=limAbove);
1794   bool removeLayer(QCPLayer *layer);
1795   bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove);
1796 
1797   // axis rect/layout interface:
1798   int axisRectCount() const;
1799   QCPAxisRect* axisRect(int index=0) const;
1800   QList<QCPAxisRect*> axisRects() const;
1801   QCPLayoutElement* layoutElementAt(const QPointF &pos) const;
1802   Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false);
1803 
1804   QList<QCPAxis*> selectedAxes() const;
1805   QList<QCPLegend*> selectedLegends() const;
1806   Q_SLOT void deselectAll();
1807 
1808   bool savePdf(const QString &fileName, bool noCosmeticPen=false, int width=0, int height=0, const QString &pdfCreator=QString(), const QString &pdfTitle=QString());
1809   bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1);
1810   bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1);
1811   bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0);
1812   bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1);
1813   QPixmap toPixmap(int width=0, int height=0, double scale=1.0);
1814   void toPainter(QCPPainter *painter, int width=0, int height=0);
1815   Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpHint);
1816 
1817   QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2;
1818   QCPLegend *legend;
1819 
1820 signals:
1821   void mouseDoubleClick(QMouseEvent *event);
1822   void mousePress(QMouseEvent *event);
1823   void mouseMove(QMouseEvent *event);
1824   void mouseRelease(QMouseEvent *event);
1825   void mouseWheel(QWheelEvent *event);
1826 
1827   void plottableClick(QCPAbstractPlottable *plottable, QMouseEvent *event);
1828   void plottableDoubleClick(QCPAbstractPlottable *plottable, QMouseEvent *event);
1829   void itemClick(QCPAbstractItem *item, QMouseEvent *event);
1830   void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event);
1831   void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event);
1832   void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event);
1833   void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event);
1834   void legendDoubleClick(QCPLegend *legend,  QCPAbstractLegendItem *item, QMouseEvent *event);
1835   void titleClick(QMouseEvent *event, QCPPlotTitle *title);
1836   void titleDoubleClick(QMouseEvent *event, QCPPlotTitle *title);
1837 
1838   void selectionChangedByUser();
1839   void beforeReplot();
1840   void afterReplot();
1841 
1842 protected:
1843   // property members:
1844   QRect mViewport;
1845   QCPLayoutGrid *mPlotLayout;
1846   bool mAutoAddPlottableToLegend;
1847   QList<QCPAbstractPlottable*> mPlottables;
1848   QList<QCPGraph*> mGraphs; // extra list of plottables also in mPlottables that are of type QCPGraph
1849   QList<QCPAbstractItem*> mItems;
1850   QList<QCPLayer*> mLayers;
1851   QCP::AntialiasedElements mAntialiasedElements, mNotAntialiasedElements;
1852   QCP::Interactions mInteractions;
1853   int mSelectionTolerance;
1854   bool mNoAntialiasingOnDrag;
1855   QBrush mBackgroundBrush;
1856   QPixmap mBackgroundPixmap;
1857   QPixmap mScaledBackgroundPixmap;
1858   bool mBackgroundScaled;
1859   Qt::AspectRatioMode mBackgroundScaledMode;
1860   QCPLayer *mCurrentLayer;
1861   QCP::PlottingHints mPlottingHints;
1862   Qt::KeyboardModifier mMultiSelectModifier;
1863 
1864   // non-property members:
1865   QPixmap mPaintBuffer;
1866   QPoint mMousePressPos;
1867   QPointer<QCPLayoutElement> mMouseEventElement;
1868   bool mReplotting;
1869 
1870   // reimplemented virtual methods:
1871   virtual QSize minimumSizeHint() const;
1872   virtual QSize sizeHint() const;
1873   virtual void paintEvent(QPaintEvent *event);
1874   virtual void resizeEvent(QResizeEvent *event);
1875   virtual void mouseDoubleClickEvent(QMouseEvent *event);
1876   virtual void mousePressEvent(QMouseEvent *event);
1877   virtual void mouseMoveEvent(QMouseEvent *event);
1878   virtual void mouseReleaseEvent(QMouseEvent *event);
1879   virtual void wheelEvent(QWheelEvent *event);
1880 
1881   // introduced virtual methods:
1882   virtual void draw(QCPPainter *painter);
1883   virtual void axisRemoved(QCPAxis *axis);
1884   virtual void legendRemoved(QCPLegend *legend);
1885 
1886   // non-virtual methods:
1887   void updateLayerIndices() const;
1888   QCPLayerable *layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=Q_NULLPTR) const;
1889   void drawBackground(QCPPainter *painter);
1890 
1891   friend class QCPLegend;
1892   friend class QCPAxis;
1893   friend class QCPLayer;
1894   friend class QCPAxisRect;
1895 };
1896 
1897 
1898 class QCP_LIB_DECL QCPColorGradient
1899 {
1900   Q_GADGET
1901 public:
1902   /*!
1903     Defines the color spaces in which color interpolation between gradient stops can be performed.
1904 
1905     \see setColorInterpolation
1906   */
1907   enum ColorInterpolation { ciRGB  ///< Color channels red, green and blue are linearly interpolated
1908                             ,ciHSV ///< Color channels hue, saturation and value are linearly interpolated (The hue is interpolated over the shortest angle distance)
1909                           };
1910   Q_ENUM(ColorInterpolation)
1911 
1912   /*!
1913     Defines the available presets that can be loaded with \ref loadPreset. See the documentation
1914     there for an image of the presets.
1915   */
1916   enum GradientPreset { gpGrayscale  ///< Continuous lightness from black to white (suited for non-biased data representation)
1917                         ,gpHot       ///< Continuous lightness from black over firey colors to white (suited for non-biased data representation)
1918                         ,gpCold      ///< Continuous lightness from black over icey colors to white (suited for non-biased data representation)
1919                         ,gpNight     ///< Continuous lightness from black over weak blueish colors to white (suited for non-biased data representation)
1920                         ,gpCandy     ///< Blue over pink to white
1921                         ,gpGeography ///< Colors suitable to represent different elevations on geographical maps
1922                         ,gpIon       ///< Half hue spectrum from black over purple to blue and finally green (creates banding illusion but allows more precise magnitude estimates)
1923                         ,gpThermal   ///< Colors suitable for thermal imaging, ranging from dark blue over purple to orange, yellow and white
1924                         ,gpPolar     ///< Colors suitable to emphasize polarity around the center, with blue for negative, black in the middle and red for positive values
1925                         ,gpSpectrum  ///< An approximation of the visible light spectrum (creates banding illusion but allows more precise magnitude estimates)
1926                         ,gpJet       ///< Hue variation similar to a spectrum, often used in numerical visualization (creates banding illusion but allows more precise magnitude estimates)
1927                         ,gpHues      ///< Full hue cycle, with highest and lowest color red (suitable for periodic data, such as angles and phases, see \ref setPeriodic)
1928                       };
1929   Q_ENUM(GradientPreset)
1930 
1931   QCPColorGradient(GradientPreset preset=gpCold);
1932   bool operator==(const QCPColorGradient &other) const;
1933   bool operator!=(const QCPColorGradient &other) const { return !(*this == other); }
1934 
1935   // getters:
1936   int levelCount() const { return mLevelCount; }
1937   QMap<double, QColor> colorStops() const { return mColorStops; }
1938   ColorInterpolation colorInterpolation() const { return mColorInterpolation; }
1939   bool periodic() const { return mPeriodic; }
1940 
1941   // setters:
1942   void setLevelCount(int n);
1943   void setColorStops(const QMap<double, QColor> &colorStops);
1944   void setColorStopAt(double position, const QColor &color);
1945   void setColorInterpolation(ColorInterpolation interpolation);
1946   void setPeriodic(bool enabled);
1947 
1948   // non-property methods:
1949   void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false);
1950   QRgb color(double position, const QCPRange &range, bool logarithmic=false);
1951   void loadPreset(GradientPreset preset);
1952   void clearColorStops();
1953   QCPColorGradient inverted() const;
1954 
1955 protected:
1956   void updateColorBuffer();
1957 
1958   // property members:
1959   int mLevelCount;
1960   QMap<double, QColor> mColorStops;
1961   ColorInterpolation mColorInterpolation;
1962   bool mPeriodic;
1963 
1964   // non-property members:
1965   QVector<QRgb> mColorBuffer;
1966   bool mColorBufferInvalidated;
1967 };
1968 
1969 
1970 class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement
1971 {
1972   Q_OBJECT
1973   /// \cond INCLUDE_QPROPERTIES
1974   Q_PROPERTY(QPixmap background READ background WRITE setBackground)
1975   Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled)
1976   Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode)
1977   Q_PROPERTY(Qt::Orientations rangeDrag READ rangeDrag WRITE setRangeDrag)
1978   Q_PROPERTY(Qt::Orientations rangeZoom READ rangeZoom WRITE setRangeZoom)
1979   /// \endcond
1980 public:
1981   explicit QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes=true);
1982   virtual ~QCPAxisRect();
1983 
1984   // getters:
1985   QPixmap background() const { return mBackgroundPixmap; }
1986   bool backgroundScaled() const { return mBackgroundScaled; }
1987   Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; }
1988   Qt::Orientations rangeDrag() const { return mRangeDrag; }
1989   Qt::Orientations rangeZoom() const { return mRangeZoom; }
1990   QCPAxis *rangeDragAxis(Qt::Orientation orientation);
1991   QCPAxis *rangeZoomAxis(Qt::Orientation orientation);
1992   double rangeZoomFactor(Qt::Orientation orientation);
1993 
1994   // setters:
1995   void setBackground(const QPixmap &pm);
1996   void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding);
1997   void setBackground(const QBrush &brush);
1998   void setBackgroundScaled(bool scaled);
1999   void setBackgroundScaledMode(Qt::AspectRatioMode mode);
2000   void setRangeDrag(Qt::Orientations orientations);
2001   void setRangeZoom(Qt::Orientations orientations);
2002   void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical);
2003   void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical);
2004   void setRangeZoomFactor(double horizontalFactor, double verticalFactor);
2005   void setRangeZoomFactor(double factor);
2006 
2007   // non-property methods:
2008   int axisCount(QCPAxis::AxisType type) const;
2009   QCPAxis *axis(QCPAxis::AxisType type, int index=0) const;
2010   QList<QCPAxis*> axes(QCPAxis::AxisTypes types) const;
2011   QList<QCPAxis*> axes() const;
2012   QCPAxis *addAxis(QCPAxis::AxisType type, QCPAxis *axis=Q_NULLPTR);
2013   QList<QCPAxis*> addAxes(QCPAxis::AxisTypes types);
2014   bool removeAxis(QCPAxis *axis);
2015   QCPLayoutInset *insetLayout() const { return mInsetLayout; }
2016 
2017   void setupFullAxesBox(bool connectRanges=false);
2018   QList<QCPAbstractPlottable*> plottables() const;
2019   QList<QCPGraph*> graphs() const;
2020   QList<QCPAbstractItem*> items() const;
2021 
2022   // read-only interface imitating a QRect:
2023   int left() const { return mRect.left(); }
2024   int right() const { return mRect.right(); }
2025   int top() const { return mRect.top(); }
2026   int bottom() const { return mRect.bottom(); }
2027   int width() const { return mRect.width(); }
2028   int height() const { return mRect.height(); }
2029   QSize size() const { return mRect.size(); }
2030   QPoint topLeft() const { return mRect.topLeft(); }
2031   QPoint topRight() const { return mRect.topRight(); }
2032   QPoint bottomLeft() const { return mRect.bottomLeft(); }
2033   QPoint bottomRight() const { return mRect.bottomRight(); }
2034   QPoint center() const { return mRect.center(); }
2035 
2036   // reimplemented virtual methods:
2037   virtual void update(UpdatePhase phase);
2038   virtual QList<QCPLayoutElement*> elements(bool recursive) const;
2039 
2040 protected:
2041   // property members:
2042   QBrush mBackgroundBrush;
2043   QPixmap mBackgroundPixmap;
2044   QPixmap mScaledBackgroundPixmap;
2045   bool mBackgroundScaled;
2046   Qt::AspectRatioMode mBackgroundScaledMode;
2047   QCPLayoutInset *mInsetLayout;
2048   Qt::Orientations mRangeDrag, mRangeZoom;
2049   QPointer<QCPAxis> mRangeDragHorzAxis, mRangeDragVertAxis, mRangeZoomHorzAxis, mRangeZoomVertAxis;
2050   double mRangeZoomFactorHorz, mRangeZoomFactorVert;
2051   // non-property members:
2052   QCPRange mDragStartHorzRange, mDragStartVertRange;
2053   QCP::AntialiasedElements mAADragBackup, mNotAADragBackup;
2054   QPoint mDragStart;
2055   bool mDragging;
2056   QHash<QCPAxis::AxisType, QList<QCPAxis*> > mAxes;
2057 
2058   // reimplemented virtual methods:
2059   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const;
2060   virtual void draw(QCPPainter *painter);
2061   virtual int calculateAutoMargin(QCP::MarginSide side);
2062   // events:
2063   virtual void mousePressEvent(QMouseEvent *event);
2064   virtual void mouseMoveEvent(QMouseEvent *event);
2065   virtual void mouseReleaseEvent(QMouseEvent *event);
2066   virtual void wheelEvent(QWheelEvent *event);
2067 
2068   // non-property methods:
2069   void drawBackground(QCPPainter *painter);
2070   void updateAxesOffset(QCPAxis::AxisType type);
2071 
2072 private:
2073   Q_DISABLE_COPY(QCPAxisRect)
2074 
2075   friend class QCustomPlot;
2076 };
2077 
2078 
2079 class QCP_LIB_DECL QCPAbstractLegendItem : public QCPLayoutElement
2080 {
2081   Q_OBJECT
2082   /// \cond INCLUDE_QPROPERTIES
2083   Q_PROPERTY(QCPLegend* parentLegend READ parentLegend)
2084   Q_PROPERTY(QFont font READ font WRITE setFont)
2085   Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor)
2086   Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont)
2087   Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor)
2088   Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectionChanged)
2089   Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectableChanged)
2090   /// \endcond
2091 public:
2092   explicit QCPAbstractLegendItem(QCPLegend *parent);
2093 
2094   // getters:
2095   QCPLegend *parentLegend() const { return mParentLegend; }
2096   QFont font() const { return mFont; }
2097   QColor textColor() const { return mTextColor; }
2098   QFont selectedFont() const { return mSelectedFont; }
2099   QColor selectedTextColor() const { return mSelectedTextColor; }
2100   bool selectable() const { return mSelectable; }
2101   bool selected() const { return mSelected; }
2102 
2103   // setters:
2104   void setFont(const QFont &font);
2105   void setTextColor(const QColor &color);
2106   void setSelectedFont(const QFont &font);
2107   void setSelectedTextColor(const QColor &color);
2108   Q_SLOT void setSelectable(bool selectable);
2109   Q_SLOT void setSelected(bool selected);
2110 
2111   // reimplemented virtual methods:
2112   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
2113 
2114 signals:
2115   void selectionChanged(bool selected);
2116   void selectableChanged(bool selectable);
2117 
2118 protected:
2119   // property members:
2120   QCPLegend *mParentLegend;
2121   QFont mFont;
2122   QColor mTextColor;
2123   QFont mSelectedFont;
2124   QColor mSelectedTextColor;
2125   bool mSelectable, mSelected;
2126 
2127   // reimplemented virtual methods:
2128   virtual QCP::Interaction selectionCategory() const;
2129   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const;
2130   virtual QRect clipRect() const;
2131   virtual void draw(QCPPainter *painter) = 0;
2132   // events:
2133   virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged);
2134   virtual void deselectEvent(bool *selectionStateChanged);
2135 
2136 private:
2137   Q_DISABLE_COPY(QCPAbstractLegendItem)
2138 
2139   friend class QCPLegend;
2140 };
2141 
2142 
2143 class QCP_LIB_DECL QCPPlottableLegendItem : public QCPAbstractLegendItem
2144 {
2145   Q_OBJECT
2146 public:
2147   QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable);
2148 
2149   // getters:
2150   QCPAbstractPlottable *plottable() { return mPlottable; }
2151 
2152 protected:
2153   // property members:
2154   QCPAbstractPlottable *mPlottable;
2155 
2156   // reimplemented virtual methods:
2157   virtual void draw(QCPPainter *painter);
2158   virtual QSize minimumSizeHint() const;
2159 
2160   // non-virtual methods:
2161   QPen getIconBorderPen() const;
2162   QColor getTextColor() const;
2163   QFont getFont() const;
2164 };
2165 
2166 
2167 class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid
2168 {
2169   Q_OBJECT
2170   /// \cond INCLUDE_QPROPERTIES
2171   Q_PROPERTY(QPen borderPen READ borderPen WRITE setBorderPen)
2172   Q_PROPERTY(QBrush brush READ brush WRITE setBrush)
2173   Q_PROPERTY(QFont font READ font WRITE setFont)
2174   Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor)
2175   Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
2176   Q_PROPERTY(int iconTextPadding READ iconTextPadding WRITE setIconTextPadding)
2177   Q_PROPERTY(QPen iconBorderPen READ iconBorderPen WRITE setIconBorderPen)
2178   Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectionChanged)
2179   Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectableChanged)
2180   Q_PROPERTY(QPen selectedBorderPen READ selectedBorderPen WRITE setSelectedBorderPen)
2181   Q_PROPERTY(QPen selectedIconBorderPen READ selectedIconBorderPen WRITE setSelectedIconBorderPen)
2182   Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush)
2183   Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont)
2184   Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor)
2185   /// \endcond
2186 public:
2187   /*!
2188     Defines the selectable parts of a legend
2189 
2190     \see setSelectedParts, setSelectableParts
2191   */
2192   enum SelectablePart { spNone       = 0x000  ///< <tt>0x000</tt> None
2193                         ,spLegendBox  = 0x001 ///< <tt>0x001</tt> The legend box (frame)
2194                         ,spItems      = 0x002 ///< <tt>0x002</tt> Legend items individually (see \ref selectedItems)
2195                       };
2196   Q_FLAGS(SelectablePart SelectableParts)
2197   Q_DECLARE_FLAGS(SelectableParts, SelectablePart)
2198 
2199   explicit QCPLegend();
2200   virtual ~QCPLegend();
2201 
2202   // getters:
2203   QPen borderPen() const { return mBorderPen; }
2204   QBrush brush() const { return mBrush; }
2205   QFont font() const { return mFont; }
2206   QColor textColor() const { return mTextColor; }
2207   QSize iconSize() const { return mIconSize; }
2208   int iconTextPadding() const { return mIconTextPadding; }
2209   QPen iconBorderPen() const { return mIconBorderPen; }
2210   SelectableParts selectableParts() const { return mSelectableParts; }
2211   SelectableParts selectedParts() const;
2212   QPen selectedBorderPen() const { return mSelectedBorderPen; }
2213   QPen selectedIconBorderPen() const { return mSelectedIconBorderPen; }
2214   QBrush selectedBrush() const { return mSelectedBrush; }
2215   QFont selectedFont() const { return mSelectedFont; }
2216   QColor selectedTextColor() const { return mSelectedTextColor; }
2217 
2218   // setters:
2219   void setBorderPen(const QPen &pen);
2220   void setBrush(const QBrush &brush);
2221   void setFont(const QFont &font);
2222   void setTextColor(const QColor &color);
2223   void setIconSize(const QSize &size);
2224   void setIconSize(int width, int height);
2225   void setIconTextPadding(int padding);
2226   void setIconBorderPen(const QPen &pen);
2227   Q_SLOT void setSelectableParts(const SelectableParts &selectableParts);
2228   Q_SLOT void setSelectedParts(const SelectableParts &selectedParts);
2229   void setSelectedBorderPen(const QPen &pen);
2230   void setSelectedIconBorderPen(const QPen &pen);
2231   void setSelectedBrush(const QBrush &brush);
2232   void setSelectedFont(const QFont &font);
2233   void setSelectedTextColor(const QColor &color);
2234 
2235   // reimplemented virtual methods:
2236   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
2237 
2238   // non-virtual methods:
2239   QCPAbstractLegendItem *item(int index) const;
2240   QCPPlottableLegendItem *itemWithPlottable(const QCPAbstractPlottable *plottable) const;
2241   int itemCount() const;
2242   bool hasItem(QCPAbstractLegendItem *item) const;
2243   bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const;
2244   bool addItem(QCPAbstractLegendItem *item);
2245   bool removeItem(int index);
2246   bool removeItem(QCPAbstractLegendItem *item);
2247   void clearItems();
2248   QList<QCPAbstractLegendItem*> selectedItems() const;
2249 
2250 signals:
2251   void selectionChanged(QCPLegend::SelectableParts parts);
2252   void selectableChanged(QCPLegend::SelectableParts parts);
2253 
2254 protected:
2255   // property members:
2256   QPen mBorderPen, mIconBorderPen;
2257   QBrush mBrush;
2258   QFont mFont;
2259   QColor mTextColor;
2260   QSize mIconSize;
2261   int mIconTextPadding;
2262   SelectableParts mSelectedParts, mSelectableParts;
2263   QPen mSelectedBorderPen, mSelectedIconBorderPen;
2264   QBrush mSelectedBrush;
2265   QFont mSelectedFont;
2266   QColor mSelectedTextColor;
2267 
2268   // reimplemented virtual methods:
2269   virtual void parentPlotInitialized(QCustomPlot *parentPlot);
2270   virtual QCP::Interaction selectionCategory() const;
2271   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const;
2272   virtual void draw(QCPPainter *painter);
2273   // events:
2274   virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged);
2275   virtual void deselectEvent(bool *selectionStateChanged);
2276 
2277   // non-virtual methods:
2278   QPen getBorderPen() const;
2279   QBrush getBrush() const;
2280 
2281 private:
2282   Q_DISABLE_COPY(QCPLegend)
2283 
2284   friend class QCustomPlot;
2285   friend class QCPAbstractLegendItem;
2286 };
2287 Q_DECLARE_OPERATORS_FOR_FLAGS(QCPLegend::SelectableParts)
2288 Q_DECLARE_METATYPE(QCPLegend::SelectablePart)
2289 
2290 
2291 class QCP_LIB_DECL QCPPlotTitle : public QCPLayoutElement
2292 {
2293   Q_OBJECT
2294   /// \cond INCLUDE_QPROPERTIES
2295   Q_PROPERTY(QString text READ text WRITE setText)
2296   Q_PROPERTY(QFont font READ font WRITE setFont)
2297   Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor)
2298   Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont)
2299   Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor)
2300   Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged)
2301   Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged)
2302   /// \endcond
2303 public:
2304   explicit QCPPlotTitle(QCustomPlot *parentPlot);
2305   explicit QCPPlotTitle(QCustomPlot *parentPlot, const QString &text);
2306 
2307   // getters:
2308   QString text() const { return mText; }
2309   QFont font() const { return mFont; }
2310   QColor textColor() const { return mTextColor; }
2311   QFont selectedFont() const { return mSelectedFont; }
2312   QColor selectedTextColor() const { return mSelectedTextColor; }
2313   bool selectable() const { return mSelectable; }
2314   bool selected() const { return mSelected; }
2315 
2316   // setters:
2317   void setText(const QString &text);
2318   void setFont(const QFont &font);
2319   void setTextColor(const QColor &color);
2320   void setSelectedFont(const QFont &font);
2321   void setSelectedTextColor(const QColor &color);
2322   Q_SLOT void setSelectable(bool selectable);
2323   Q_SLOT void setSelected(bool selected);
2324 
2325   // reimplemented virtual methods:
2326   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
2327 
2328 signals:
2329   void selectionChanged(bool selected);
2330   void selectableChanged(bool selectable);
2331 
2332 protected:
2333   // property members:
2334   QString mText;
2335   QFont mFont;
2336   QColor mTextColor;
2337   QFont mSelectedFont;
2338   QColor mSelectedTextColor;
2339   QRect mTextBoundingRect;
2340   bool mSelectable, mSelected;
2341 
2342   // reimplemented virtual methods:
2343   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const;
2344   virtual void draw(QCPPainter *painter);
2345   virtual QSize minimumSizeHint() const;
2346   virtual QSize maximumSizeHint() const;
2347   // events:
2348   virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged);
2349   virtual void deselectEvent(bool *selectionStateChanged);
2350 
2351   // non-virtual methods:
2352   QFont mainFont() const;
2353   QColor mainTextColor() const;
2354 
2355 private:
2356   Q_DISABLE_COPY(QCPPlotTitle)
2357 };
2358 
2359 
2360 class QCPColorScaleAxisRectPrivate : public QCPAxisRect
2361 {
2362   Q_OBJECT
2363 public:
2364   explicit QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale);
2365 protected:
2366   QCPColorScale *mParentColorScale;
2367   QImage mGradientImage;
2368   bool mGradientImageInvalidated;
2369   // re-using some methods of QCPAxisRect to make them available to friend class QCPColorScale
2370   using QCPAxisRect::calculateAutoMargin;
2371   using QCPAxisRect::mousePressEvent;
2372   using QCPAxisRect::mouseMoveEvent;
2373   using QCPAxisRect::mouseReleaseEvent;
2374   using QCPAxisRect::wheelEvent;
2375   using QCPAxisRect::update;
2376   virtual void draw(QCPPainter *painter);
2377   void updateGradientImage();
2378   Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts);
2379   Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts);
2380   friend class QCPColorScale;
2381 };
2382 
2383 
2384 class QCP_LIB_DECL QCPColorScale : public QCPLayoutElement
2385 {
2386   Q_OBJECT
2387   /// \cond INCLUDE_QPROPERTIES
2388   Q_PROPERTY(QCPAxis::AxisType type READ type WRITE setType)
2389   Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged)
2390   Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged)
2391   Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged)
2392   Q_PROPERTY(QString label READ label WRITE setLabel)
2393   Q_PROPERTY(int barWidth READ barWidth WRITE setBarWidth)
2394   Q_PROPERTY(bool rangeDrag READ rangeDrag WRITE setRangeDrag)
2395   Q_PROPERTY(bool rangeZoom READ rangeZoom WRITE setRangeZoom)
2396   /// \endcond
2397 public:
2398   explicit QCPColorScale(QCustomPlot *parentPlot);
2399   virtual ~QCPColorScale();
2400 
2401   // getters:
2402   QCPAxis *axis() const { return mColorAxis.data(); }
2403   QCPAxis::AxisType type() const { return mType; }
2404   QCPRange dataRange() const { return mDataRange; }
2405   QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; }
2406   QCPColorGradient gradient() const { return mGradient; }
2407   QString label() const;
2408   int barWidth () const { return mBarWidth; }
2409   bool rangeDrag() const;
2410   bool rangeZoom() const;
2411 
2412   // setters:
2413   void setType(QCPAxis::AxisType type);
2414   Q_SLOT void setDataRange(const QCPRange &dataRange);
2415   Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType);
2416   Q_SLOT void setGradient(const QCPColorGradient &gradient);
2417   void setLabel(const QString &str);
2418   void setBarWidth(int width);
2419   void setRangeDrag(bool enabled);
2420   void setRangeZoom(bool enabled);
2421 
2422   // non-property methods:
2423   QList<QCPColorMap*> colorMaps() const;
2424   void rescaleDataRange(bool onlyVisibleMaps);
2425 
2426   // reimplemented virtual methods:
2427   virtual void update(UpdatePhase phase);
2428 
2429 signals:
2430   void dataRangeChanged(QCPRange newRange);
2431   void dataScaleTypeChanged(QCPAxis::ScaleType scaleType);
2432   void gradientChanged(QCPColorGradient newGradient);
2433 
2434 protected:
2435   // property members:
2436   QCPAxis::AxisType mType;
2437   QCPRange mDataRange;
2438   QCPAxis::ScaleType mDataScaleType;
2439   QCPColorGradient mGradient;
2440   int mBarWidth;
2441 
2442   // non-property members:
2443   QPointer<QCPColorScaleAxisRectPrivate> mAxisRect;
2444   QPointer<QCPAxis> mColorAxis;
2445 
2446   // reimplemented virtual methods:
2447   virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const;
2448   // events:
2449   virtual void mousePressEvent(QMouseEvent *event);
2450   virtual void mouseMoveEvent(QMouseEvent *event);
2451   virtual void mouseReleaseEvent(QMouseEvent *event);
2452   virtual void wheelEvent(QWheelEvent *event);
2453 
2454 private:
2455   Q_DISABLE_COPY(QCPColorScale)
2456 
2457   friend class QCPColorScaleAxisRectPrivate;
2458 };
2459 
2460 
2461 /*! \file */
2462 
2463 
2464 
2465 class QCP_LIB_DECL QCPData
2466 {
2467 public:
2468   QCPData();
2469   QCPData(double key, double value);
2470   double key, value;
2471   double keyErrorPlus, keyErrorMinus;
2472   double valueErrorPlus, valueErrorMinus;
2473 };
2474 Q_DECLARE_TYPEINFO(QCPData, Q_MOVABLE_TYPE);
2475 
2476 /*! \typedef QCPDataMap
2477   Container for storing \ref QCPData items in a sorted fashion. The key of the map
2478   is the key member of the QCPData instance.
2479 
2480   This is the container in which QCPGraph holds its data.
2481   \see QCPData, QCPGraph::setData
2482 */
2483 typedef QMap<double, QCPData> QCPDataMap;
2484 typedef QMapIterator<double, QCPData> QCPDataMapIterator;
2485 typedef QMutableMapIterator<double, QCPData> QCPDataMutableMapIterator;
2486 
2487 
2488 class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable
2489 {
2490   Q_OBJECT
2491   /// \cond INCLUDE_QPROPERTIES
2492   Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle)
2493   Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle)
2494   Q_PROPERTY(ErrorType errorType READ errorType WRITE setErrorType)
2495   Q_PROPERTY(QPen errorPen READ errorPen WRITE setErrorPen)
2496   Q_PROPERTY(double errorBarSize READ errorBarSize WRITE setErrorBarSize)
2497   Q_PROPERTY(bool errorBarSkipSymbol READ errorBarSkipSymbol WRITE setErrorBarSkipSymbol)
2498   Q_PROPERTY(QCPGraph* channelFillGraph READ channelFillGraph WRITE setChannelFillGraph)
2499   Q_PROPERTY(bool adaptiveSampling READ adaptiveSampling WRITE setAdaptiveSampling)
2500   /// \endcond
2501 public:
2502   /*!
2503     Defines how the graph's line is represented visually in the plot. The line is drawn with the
2504     current pen of the graph (\ref setPen).
2505     \see setLineStyle
2506   */
2507   enum LineStyle { lsNone        ///< data points are not connected with any lines (e.g. data only represented
2508                                  ///< with symbols according to the scatter style, see \ref setScatterStyle)
2509                    ,lsLine       ///< data points are connected by a straight line
2510                    ,lsStepLeft   ///< line is drawn as steps where the step height is the value of the left data point
2511                    ,lsStepRight  ///< line is drawn as steps where the step height is the value of the right data point
2512                    ,lsStepCenter ///< line is drawn as steps where the step is in between two data points
2513                    ,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
2514                  };
2515   Q_ENUM(LineStyle)
2516   /*!
2517     Defines what kind of error bars are drawn for each data point
2518   */
2519   enum ErrorType { etNone   ///< No error bars are shown
2520                    ,etKey   ///< Error bars for the key dimension of the data point are shown
2521                    ,etValue ///< Error bars for the value dimension of the data point are shown
2522                    ,etBoth  ///< Error bars for both key and value dimensions of the data point are shown
2523                  };
2524   Q_ENUM(ErrorType)
2525 
2526   explicit QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis);
2527   virtual ~QCPGraph();
2528 
2529   // getters:
2530   QCPDataMap *data() const { return mData; }
2531   LineStyle lineStyle() const { return mLineStyle; }
2532   QCPScatterStyle scatterStyle() const { return mScatterStyle; }
2533   ErrorType errorType() const { return mErrorType; }
2534   QPen errorPen() const { return mErrorPen; }
2535   double errorBarSize() const { return mErrorBarSize; }
2536   bool errorBarSkipSymbol() const { return mErrorBarSkipSymbol; }
2537   QCPGraph *channelFillGraph() const { return mChannelFillGraph.data(); }
2538   bool adaptiveSampling() const { return mAdaptiveSampling; }
2539 
2540   // setters:
2541   void setData(QCPDataMap *data, bool copy=false);
2542   void setData(const QVector<double> &key, const QVector<double> &value);
2543   void setDataKeyError(const QVector<double> &key, const QVector<double> &value, const QVector<double> &keyError);
2544   void setDataKeyError(const QVector<double> &key, const QVector<double> &value, const QVector<double> &keyErrorMinus, const QVector<double> &keyErrorPlus);
2545   void setDataValueError(const QVector<double> &key, const QVector<double> &value, const QVector<double> &valueError);
2546   void setDataValueError(const QVector<double> &key, const QVector<double> &value, const QVector<double> &valueErrorMinus, const QVector<double> &valueErrorPlus);
2547   void setDataBothError(const QVector<double> &key, const QVector<double> &value, const QVector<double> &keyError, const QVector<double> &valueError);
2548   void setDataBothError(const QVector<double> &key, const QVector<double> &value, const QVector<double> &keyErrorMinus, const QVector<double> &keyErrorPlus, const QVector<double> &valueErrorMinus, const QVector<double> &valueErrorPlus);
2549   void setLineStyle(LineStyle ls);
2550   void setScatterStyle(const QCPScatterStyle &style);
2551   void setErrorType(ErrorType errorType);
2552   void setErrorPen(const QPen &pen);
2553   void setErrorBarSize(double size);
2554   void setErrorBarSkipSymbol(bool enabled);
2555   void setChannelFillGraph(QCPGraph *targetGraph);
2556   void setAdaptiveSampling(bool enabled);
2557 
2558   // non-property methods:
2559   void addData(const QCPDataMap &dataMap);
2560   void addData(const QCPData &data);
2561   void addData(double key, double value);
2562   void addData(const QVector<double> &keys, const QVector<double> &values);
2563   void removeDataBefore(double key);
2564   void removeDataAfter(double key);
2565   void removeData(double fromKey, double toKey);
2566   void removeData(double key);
2567 
2568   // reimplemented virtual methods:
2569   virtual void clearData();
2570   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
2571   using QCPAbstractPlottable::rescaleAxes;
2572   using QCPAbstractPlottable::rescaleKeyAxis;
2573   using QCPAbstractPlottable::rescaleValueAxis;
2574   void rescaleAxes(bool onlyEnlarge, bool includeErrorBars) const; // overloads base class interface
2575   void rescaleKeyAxis(bool onlyEnlarge, bool includeErrorBars) const; // overloads base class interface
2576   void rescaleValueAxis(bool onlyEnlarge, bool includeErrorBars) const; // overloads base class interface
2577 
2578 protected:
2579   // property members:
2580   QCPDataMap *mData;
2581   QPen mErrorPen;
2582   LineStyle mLineStyle;
2583   QCPScatterStyle mScatterStyle;
2584   ErrorType mErrorType;
2585   double mErrorBarSize;
2586   bool mErrorBarSkipSymbol;
2587   QPointer<QCPGraph> mChannelFillGraph;
2588   bool mAdaptiveSampling;
2589 
2590   // reimplemented virtual methods:
2591   virtual void draw(QCPPainter *painter);
2592   virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const;
2593   virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const;
2594   virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const;
2595   virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain, bool includeErrors) const; // overloads base class interface
2596   virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain, bool includeErrors) const; // overloads base class interface
2597 
2598   // introduced virtual methods:
2599   virtual void drawFill(QCPPainter *painter, QVector<QPointF> *lineData) const;
2600   virtual void drawScatterPlot(QCPPainter *painter, QVector<QCPData> *scatterData) const;
2601   virtual void drawLinePlot(QCPPainter *painter, QVector<QPointF> *lineData) const;
2602   virtual void drawImpulsePlot(QCPPainter *painter, QVector<QPointF> *lineData) const;
2603 
2604   // non-virtual methods:
2605   void getPreparedData(QVector<QCPData> *lineData, QVector<QCPData> *scatterData) const;
2606   void getPlotData(QVector<QPointF> *lineData, QVector<QCPData> *scatterData) const;
2607   void getScatterPlotData(QVector<QCPData> *scatterData) const;
2608   void getLinePlotData(QVector<QPointF> *linePixelData, QVector<QCPData> *scatterData) const;
2609   void getStepLeftPlotData(QVector<QPointF> *linePixelData, QVector<QCPData> *scatterData) const;
2610   void getStepRightPlotData(QVector<QPointF> *linePixelData, QVector<QCPData> *scatterData) const;
2611   void getStepCenterPlotData(QVector<QPointF> *linePixelData, QVector<QCPData> *scatterData) const;
2612   void getImpulsePlotData(QVector<QPointF> *linePixelData, QVector<QCPData> *scatterData) const;
2613   void drawError(QCPPainter *painter, double x, double y, const QCPData &data) const;
2614   void getVisibleDataBounds(QCPDataMap::const_iterator &lower, QCPDataMap::const_iterator &upper) const;
2615   int countDataInBounds(const QCPDataMap::const_iterator &lower, const QCPDataMap::const_iterator &upper, int maxCount) const;
2616   void addFillBasePoints(QVector<QPointF> *lineData) const;
2617   void removeFillBasePoints(QVector<QPointF> *lineData) const;
2618   QPointF lowerFillBasePoint(double lowerKey) const;
2619   QPointF upperFillBasePoint(double upperKey) const;
2620   const QPolygonF getChannelFillPolygon(const QVector<QPointF> *lineData) const;
2621   int findIndexBelowX(const QVector<QPointF> *data, double x) const;
2622   int findIndexAboveX(const QVector<QPointF> *data, double x) const;
2623   int findIndexBelowY(const QVector<QPointF> *data, double y) const;
2624   int findIndexAboveY(const QVector<QPointF> *data, double y) const;
2625   double pointDistance(const QPointF &pixelPoint) const;
2626 
2627   friend class QCustomPlot;
2628   friend class QCPLegend;
2629 };
2630 
2631 
2632 /*! \file */
2633 
2634 
2635 
2636 class QCP_LIB_DECL QCPCurveData
2637 {
2638 public:
2639   QCPCurveData();
2640   QCPCurveData(double t, double key, double value);
2641   double t, key, value;
2642 };
2643 Q_DECLARE_TYPEINFO(QCPCurveData, Q_MOVABLE_TYPE);
2644 
2645 /*! \typedef QCPCurveDataMap
2646   Container for storing \ref QCPCurveData items in a sorted fashion. The key of the map
2647   is the t member of the QCPCurveData instance.
2648 
2649   This is the container in which QCPCurve holds its data.
2650   \see QCPCurveData, QCPCurve::setData
2651 */
2652 
2653 typedef QMap<double, QCPCurveData> QCPCurveDataMap;
2654 typedef QMapIterator<double, QCPCurveData> QCPCurveDataMapIterator;
2655 typedef QMutableMapIterator<double, QCPCurveData> QCPCurveDataMutableMapIterator;
2656 
2657 
2658 class QCP_LIB_DECL QCPCurve : public QCPAbstractPlottable
2659 {
2660   Q_OBJECT
2661   /// \cond INCLUDE_QPROPERTIES
2662   Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle)
2663   Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle)
2664   /// \endcond
2665 public:
2666   /*!
2667     Defines how the curve's line is represented visually in the plot. The line is drawn with the
2668     current pen of the curve (\ref setPen).
2669     \see setLineStyle
2670   */
2671   enum LineStyle { lsNone  ///< No line is drawn between data points (e.g. only scatters)
2672                    ,lsLine ///< Data points are connected with a straight line
2673                  };
2674   explicit QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis);
2675   virtual ~QCPCurve();
2676 
2677   // getters:
2678   QCPCurveDataMap *data() const { return mData; }
2679   QCPScatterStyle scatterStyle() const { return mScatterStyle; }
2680   LineStyle lineStyle() const { return mLineStyle; }
2681 
2682   // setters:
2683   void setData(QCPCurveDataMap *data, bool copy=false);
2684   void setData(const QVector<double> &t, const QVector<double> &key, const QVector<double> &value);
2685   void setData(const QVector<double> &key, const QVector<double> &value);
2686   void setScatterStyle(const QCPScatterStyle &style);
2687   void setLineStyle(LineStyle style);
2688 
2689   // non-property methods:
2690   void addData(const QCPCurveDataMap &dataMap);
2691   void addData(const QCPCurveData &data);
2692   void addData(double t, double key, double value);
2693   void addData(double key, double value);
2694   void addData(const QVector<double> &ts, const QVector<double> &keys, const QVector<double> &values);
2695   void removeDataBefore(double t);
2696   void removeDataAfter(double t);
2697   void removeData(double fromt, double tot);
2698   void removeData(double t);
2699 
2700   // reimplemented virtual methods:
2701   virtual void clearData();
2702   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
2703 
2704 protected:
2705   // property members:
2706   QCPCurveDataMap *mData;
2707   QCPScatterStyle mScatterStyle;
2708   LineStyle mLineStyle;
2709 
2710   // reimplemented virtual methods:
2711   virtual void draw(QCPPainter *painter);
2712   virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const;
2713   virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const;
2714   virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const;
2715 
2716   // introduced virtual methods:
2717   virtual void drawScatterPlot(QCPPainter *painter, const QVector<QPointF> *pointData) const;
2718 
2719   // non-virtual methods:
2720   void getCurveData(QVector<QPointF> *lineData) const;
2721   int getRegion(double x, double y, double rectLeft, double rectTop, double rectRight, double rectBottom) const;
2722   QPointF getOptimizedPoint(int prevRegion, double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom) const;
2723   QVector<QPointF> getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom) const;
2724   bool mayTraverse(int prevRegion, int currentRegion) const;
2725   bool getTraverse(double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom, QPointF &crossA, QPointF &crossB) const;
2726   void getTraverseCornerPoints(int prevRegion, int currentRegion, double rectLeft, double rectTop, double rectRight, double rectBottom, QVector<QPointF> &beforeTraverse, QVector<QPointF> &afterTraverse) const;
2727   double pointDistance(const QPointF &pixelPoint) const;
2728 
2729   friend class QCustomPlot;
2730   friend class QCPLegend;
2731 };
2732 
2733 
2734 /*! \file */
2735 
2736 
2737 
2738 class QCP_LIB_DECL QCPBarsGroup : public QObject
2739 {
2740   Q_OBJECT
2741   /// \cond INCLUDE_QPROPERTIES
2742   Q_PROPERTY(SpacingType spacingType READ spacingType WRITE setSpacingType)
2743   Q_PROPERTY(double spacing READ spacing WRITE setSpacing)
2744   /// \endcond
2745 public:
2746   /*!
2747     Defines the ways the spacing between bars in the group can be specified. Thus it defines what
2748     the number passed to \ref setSpacing actually means.
2749 
2750     \see setSpacingType, setSpacing
2751   */
2752   enum SpacingType { stAbsolute       ///< Bar spacing is in absolute pixels
2753                      ,stAxisRectRatio ///< Bar spacing is given by a fraction of the axis rect size
2754                      ,stPlotCoords    ///< Bar spacing is in key coordinates and thus scales with the key axis range
2755                  };
2756   QCPBarsGroup(QCustomPlot *parentPlot);
2757   ~QCPBarsGroup();
2758 
2759   // getters:
2760   SpacingType spacingType() const { return mSpacingType; }
2761   double spacing() const { return mSpacing; }
2762 
2763   // setters:
2764   void setSpacingType(SpacingType spacingType);
2765   void setSpacing(double spacing);
2766 
2767   // non-virtual methods:
2768   QList<QCPBars*> bars() const { return mBars; }
2769   QCPBars* bars(int index) const;
2770   int size() const { return mBars.size(); }
2771   bool isEmpty() const { return mBars.isEmpty(); }
2772   void clear();
2773   bool contains(QCPBars *bars) const { return mBars.contains(bars); }
2774   void append(QCPBars *bars);
2775   void insert(int i, QCPBars *bars);
2776   void remove(QCPBars *bars);
2777 
2778 protected:
2779   // non-property members:
2780   QCustomPlot *mParentPlot;
2781   SpacingType mSpacingType;
2782   double mSpacing;
2783   QList<QCPBars*> mBars;
2784 
2785   // non-virtual methods:
2786   void registerBars(QCPBars *bars);
2787   void unregisterBars(QCPBars *bars);
2788 
2789   // virtual methods:
2790   double keyPixelOffset(const QCPBars *bars, double keyCoord);
2791   double getPixelSpacing(const QCPBars *bars, double keyCoord);
2792 
2793 private:
2794   Q_DISABLE_COPY(QCPBarsGroup)
2795 
2796   friend class QCPBars;
2797 };
2798 
2799 
2800 class QCP_LIB_DECL QCPBarData
2801 {
2802 public:
2803   QCPBarData();
2804   QCPBarData(double key, double value);
2805   double key, value;
2806 };
2807 Q_DECLARE_TYPEINFO(QCPBarData, Q_MOVABLE_TYPE);
2808 
2809 /*! \typedef QCPBarDataMap
2810   Container for storing \ref QCPBarData items in a sorted fashion. The key of the map
2811   is the key member of the QCPBarData instance.
2812 
2813   This is the container in which QCPBars holds its data.
2814   \see QCPBarData, QCPBars::setData
2815 */
2816 typedef QMap<double, QCPBarData> QCPBarDataMap;
2817 typedef QMapIterator<double, QCPBarData> QCPBarDataMapIterator;
2818 typedef QMutableMapIterator<double, QCPBarData> QCPBarDataMutableMapIterator;
2819 
2820 
2821 class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable
2822 {
2823   Q_OBJECT
2824   /// \cond INCLUDE_QPROPERTIES
2825   Q_PROPERTY(double width READ width WRITE setWidth)
2826   Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType)
2827   Q_PROPERTY(QCPBarsGroup* barsGroup READ barsGroup WRITE setBarsGroup)
2828   Q_PROPERTY(double baseValue READ baseValue WRITE setBaseValue)
2829   Q_PROPERTY(QCPBars* barBelow READ barBelow)
2830   Q_PROPERTY(QCPBars* barAbove READ barAbove)
2831   /// \endcond
2832 public:
2833   /*!
2834     Defines the ways the width of the bar can be specified. Thus it defines what the number passed
2835     to \ref setWidth actually means.
2836 
2837     \see setWidthType, setWidth
2838   */
2839   enum WidthType { wtAbsolute       ///< Bar width is in absolute pixels
2840                    ,wtAxisRectRatio ///< Bar width is given by a fraction of the axis rect size
2841                    ,wtPlotCoords    ///< Bar width is in key coordinates and thus scales with the key axis range
2842                  };
2843    Q_ENUM(WidthType)
2844 
2845   explicit QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis);
2846   virtual ~QCPBars();
2847 
2848   // getters:
2849   double width() const { return mWidth; }
2850   WidthType widthType() const { return mWidthType; }
2851   QCPBarsGroup *barsGroup() const { return mBarsGroup; }
2852   double baseValue() const { return mBaseValue; }
2853   QCPBars *barBelow() const { return mBarBelow.data(); }
2854   QCPBars *barAbove() const { return mBarAbove.data(); }
2855   QCPBarDataMap *data() const { return mData; }
2856 
2857   // setters:
2858   void setWidth(double width);
2859   void setWidthType(WidthType widthType);
2860   void setBarsGroup(QCPBarsGroup *barsGroup);
2861   void setBaseValue(double baseValue);
2862   void setData(QCPBarDataMap *data, bool copy=false);
2863   void setData(const QVector<double> &key, const QVector<double> &value);
2864 
2865   // non-property methods:
2866   void moveBelow(QCPBars *bars);
2867   void moveAbove(QCPBars *bars);
2868   void addData(const QCPBarDataMap &dataMap);
2869   void addData(const QCPBarData &data);
2870   void addData(double key, double value);
2871   void addData(const QVector<double> &keys, const QVector<double> &values);
2872   void removeDataBefore(double key);
2873   void removeDataAfter(double key);
2874   void removeData(double fromKey, double toKey);
2875   void removeData(double key);
2876 
2877   // reimplemented virtual methods:
2878   virtual void clearData();
2879   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
2880 
2881 protected:
2882   // property members:
2883   QCPBarDataMap *mData;
2884   double mWidth;
2885   WidthType mWidthType;
2886   QCPBarsGroup *mBarsGroup;
2887   double mBaseValue;
2888   QPointer<QCPBars> mBarBelow, mBarAbove;
2889 
2890   // reimplemented virtual methods:
2891   virtual void draw(QCPPainter *painter);
2892   virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const;
2893   virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const;
2894   virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const;
2895 
2896   // non-virtual methods:
2897   void getVisibleDataBounds(QCPBarDataMap::const_iterator &lower, QCPBarDataMap::const_iterator &upperEnd) const;
2898   QPolygonF getBarPolygon(double key, double value) const;
2899   void getPixelWidth(double key, double &lower, double &upper) const;
2900   double getStackedBaseValue(double key, bool positive) const;
2901   static void connectBars(QCPBars* lower, QCPBars* upper);
2902 
2903   friend class QCustomPlot;
2904   friend class QCPLegend;
2905   friend class QCPBarsGroup;
2906 };
2907 
2908 
2909 /*! \file */
2910 
2911 
2912 
2913 class QCP_LIB_DECL QCPStatisticalBox : public QCPAbstractPlottable
2914 {
2915   Q_OBJECT
2916   /// \cond INCLUDE_QPROPERTIES
2917   Q_PROPERTY(double key READ key WRITE setKey)
2918   Q_PROPERTY(double minimum READ minimum WRITE setMinimum)
2919   Q_PROPERTY(double lowerQuartile READ lowerQuartile WRITE setLowerQuartile)
2920   Q_PROPERTY(double median READ median WRITE setMedian)
2921   Q_PROPERTY(double upperQuartile READ upperQuartile WRITE setUpperQuartile)
2922   Q_PROPERTY(double maximum READ maximum WRITE setMaximum)
2923   Q_PROPERTY(QVector<double> outliers READ outliers WRITE setOutliers)
2924   Q_PROPERTY(double width READ width WRITE setWidth)
2925   Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth)
2926   Q_PROPERTY(QPen whiskerPen READ whiskerPen WRITE setWhiskerPen)
2927   Q_PROPERTY(QPen whiskerBarPen READ whiskerBarPen WRITE setWhiskerBarPen)
2928   Q_PROPERTY(QPen medianPen READ medianPen WRITE setMedianPen)
2929   Q_PROPERTY(QCPScatterStyle outlierStyle READ outlierStyle WRITE setOutlierStyle)
2930   /// \endcond
2931 public:
2932   explicit QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis);
2933 
2934   // getters:
2935   double key() const { return mKey; }
2936   double minimum() const { return mMinimum; }
2937   double lowerQuartile() const { return mLowerQuartile; }
2938   double median() const { return mMedian; }
2939   double upperQuartile() const { return mUpperQuartile; }
2940   double maximum() const { return mMaximum; }
2941   QVector<double> outliers() const { return mOutliers; }
2942   double width() const { return mWidth; }
2943   double whiskerWidth() const { return mWhiskerWidth; }
2944   QPen whiskerPen() const { return mWhiskerPen; }
2945   QPen whiskerBarPen() const { return mWhiskerBarPen; }
2946   QPen medianPen() const { return mMedianPen; }
2947   QCPScatterStyle outlierStyle() const { return mOutlierStyle; }
2948 
2949   // setters:
2950   void setKey(double key);
2951   void setMinimum(double value);
2952   void setLowerQuartile(double value);
2953   void setMedian(double value);
2954   void setUpperQuartile(double value);
2955   void setMaximum(double value);
2956   void setOutliers(const QVector<double> &values);
2957   void setData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum);
2958   void setWidth(double width);
2959   void setWhiskerWidth(double width);
2960   void setWhiskerPen(const QPen &pen);
2961   void setWhiskerBarPen(const QPen &pen);
2962   void setMedianPen(const QPen &pen);
2963   void setOutlierStyle(const QCPScatterStyle &style);
2964 
2965   // non-property methods:
2966   virtual void clearData();
2967   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
2968 
2969 protected:
2970   // property members:
2971   QVector<double> mOutliers;
2972   double mKey, mMinimum, mLowerQuartile, mMedian, mUpperQuartile, mMaximum;
2973   double mWidth;
2974   double mWhiskerWidth;
2975   QPen mWhiskerPen, mWhiskerBarPen, mMedianPen;
2976   QCPScatterStyle mOutlierStyle;
2977 
2978   // reimplemented virtual methods:
2979   virtual void draw(QCPPainter *painter);
2980   virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const;
2981   virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const;
2982   virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const;
2983 
2984   // introduced virtual methods:
2985   virtual void drawQuartileBox(QCPPainter *painter, QRectF *quartileBox=Q_NULLPTR) const;
2986   virtual void drawMedian(QCPPainter *painter) const;
2987   virtual void drawWhiskers(QCPPainter *painter) const;
2988   virtual void drawOutliers(QCPPainter *painter) const;
2989 
2990   friend class QCustomPlot;
2991   friend class QCPLegend;
2992 };
2993 
2994 
2995 class QCP_LIB_DECL QCPColorMapData
2996 {
2997 public:
2998   QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange);
2999   ~QCPColorMapData();
3000   QCPColorMapData(const QCPColorMapData &other);
3001   QCPColorMapData &operator=(const QCPColorMapData &other);
3002 
3003   // getters:
3004   int keySize() const { return mKeySize; }
3005   int valueSize() const { return mValueSize; }
3006   QCPRange keyRange() const { return mKeyRange; }
3007   QCPRange valueRange() const { return mValueRange; }
3008   QCPRange dataBounds() const { return mDataBounds; }
3009   double data(double key, double value);
3010   double cell(int keyIndex, int valueIndex);
3011 
3012   // setters:
3013   void setSize(int keySize, int valueSize);
3014   void setKeySize(int keySize);
3015   void setValueSize(int valueSize);
3016   void setRange(const QCPRange &keyRange, const QCPRange &valueRange);
3017   void setKeyRange(const QCPRange &keyRange);
3018   void setValueRange(const QCPRange &valueRange);
3019   void setData(double key, double value, double z);
3020   void setCell(int keyIndex, int valueIndex, double z);
3021 
3022   // non-property methods:
3023   void recalculateDataBounds();
3024   void clear();
3025   void fill(double z);
3026   bool isEmpty() const { return mIsEmpty; }
3027   void coordToCell(double key, double value, int *keyIndex, int *valueIndex) const;
3028   void cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const;
3029 
3030 protected:
3031   // property members:
3032   int mKeySize, mValueSize;
3033   QCPRange mKeyRange, mValueRange;
3034   bool mIsEmpty;
3035   // non-property members:
3036   double *mData;
3037   QCPRange mDataBounds;
3038   bool mDataModified;
3039 
3040   friend class QCPColorMap;
3041 };
3042 
3043 
3044 class QCP_LIB_DECL QCPColorMap : public QCPAbstractPlottable
3045 {
3046   Q_OBJECT
3047   /// \cond INCLUDE_QPROPERTIES
3048   Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged)
3049   Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged)
3050   Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged)
3051   Q_PROPERTY(bool interpolate READ interpolate WRITE setInterpolate)
3052   Q_PROPERTY(bool tightBoundary READ tightBoundary WRITE setTightBoundary)
3053   Q_PROPERTY(QCPColorScale* colorScale READ colorScale WRITE setColorScale)
3054   /// \endcond
3055 public:
3056   explicit QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis);
3057   virtual ~QCPColorMap();
3058 
3059   // getters:
3060   QCPColorMapData *data() const { return mMapData; }
3061   QCPRange dataRange() const { return mDataRange; }
3062   QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; }
3063   bool interpolate() const { return mInterpolate; }
3064   bool tightBoundary() const { return mTightBoundary; }
3065   QCPColorGradient gradient() const { return mGradient; }
3066   QCPColorScale *colorScale() const { return mColorScale.data(); }
3067 
3068   // setters:
3069   void setData(QCPColorMapData *data, bool copy=false);
3070   Q_SLOT void setDataRange(const QCPRange &dataRange);
3071   Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType);
3072   Q_SLOT void setGradient(const QCPColorGradient &gradient);
3073   void setInterpolate(bool enabled);
3074   void setTightBoundary(bool enabled);
3075   void setColorScale(QCPColorScale *colorScale);
3076 
3077   // non-property methods:
3078   void rescaleDataRange(bool recalculateDataBounds=false);
3079   Q_SLOT void updateLegendIcon(Qt::TransformationMode transformMode=Qt::SmoothTransformation, const QSize &thumbSize=QSize(32, 18));
3080 
3081   // reimplemented virtual methods:
3082   virtual void clearData();
3083   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
3084 
3085 signals:
3086   void dataRangeChanged(QCPRange newRange);
3087   void dataScaleTypeChanged(QCPAxis::ScaleType scaleType);
3088   void gradientChanged(QCPColorGradient newGradient);
3089 
3090 protected:
3091   // property members:
3092   QCPRange mDataRange;
3093   QCPAxis::ScaleType mDataScaleType;
3094   QCPColorMapData *mMapData;
3095   QCPColorGradient mGradient;
3096   bool mInterpolate;
3097   bool mTightBoundary;
3098   QPointer<QCPColorScale> mColorScale;
3099   // non-property members:
3100   QImage mMapImage, mUndersampledMapImage;
3101   QPixmap mLegendIcon;
3102   bool mMapImageInvalidated;
3103 
3104   // introduced virtual methods:
3105   virtual void updateMapImage();
3106 
3107   // reimplemented virtual methods:
3108   virtual void draw(QCPPainter *painter);
3109   virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const;
3110   virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const;
3111   virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const;
3112 
3113   friend class QCustomPlot;
3114   friend class QCPLegend;
3115 };
3116 
3117 
3118 /*! \file */
3119 
3120 
3121 
3122 class QCP_LIB_DECL QCPFinancialData
3123 {
3124 public:
3125   QCPFinancialData();
3126   QCPFinancialData(double key, double open, double high, double low, double close);
3127   double key, open, high, low, close;
3128 };
3129 Q_DECLARE_TYPEINFO(QCPFinancialData, Q_MOVABLE_TYPE);
3130 
3131 /*! \typedef QCPFinancialDataMap
3132   Container for storing \ref QCPFinancialData items in a sorted fashion. The key of the map
3133   is the key member of the QCPFinancialData instance.
3134 
3135   This is the container in which QCPFinancial holds its data.
3136   \see QCPFinancial, QCPFinancial::setData
3137 */
3138 typedef QMap<double, QCPFinancialData> QCPFinancialDataMap;
3139 typedef QMapIterator<double, QCPFinancialData> QCPFinancialDataMapIterator;
3140 typedef QMutableMapIterator<double, QCPFinancialData> QCPFinancialDataMutableMapIterator;
3141 
3142 
3143 class QCP_LIB_DECL QCPFinancial : public QCPAbstractPlottable
3144 {
3145   Q_OBJECT
3146   /// \cond INCLUDE_QPROPERTIES
3147   Q_PROPERTY(ChartStyle chartStyle READ chartStyle WRITE setChartStyle)
3148   Q_PROPERTY(double width READ width WRITE setWidth)
3149   Q_PROPERTY(bool twoColored READ twoColored WRITE setTwoColored)
3150   Q_PROPERTY(QBrush brushPositive READ brushPositive WRITE setBrushPositive)
3151   Q_PROPERTY(QBrush brushNegative READ brushNegative WRITE setBrushNegative)
3152   Q_PROPERTY(QPen penPositive READ penPositive WRITE setPenPositive)
3153   Q_PROPERTY(QPen penNegative READ penNegative WRITE setPenNegative)
3154   /// \endcond
3155 public:
3156   /*!
3157     Defines the possible representations of OHLC data in the plot.
3158 
3159     \see setChartStyle
3160   */
3161   enum ChartStyle { csOhlc         ///< Open-High-Low-Close bar representation
3162                    ,csCandlestick  ///< Candlestick representation
3163                   };
3164   Q_ENUM(ChartStyle)
3165 
3166   explicit QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis);
3167   virtual ~QCPFinancial();
3168 
3169   // getters:
3170   QCPFinancialDataMap *data() const { return mData; }
3171   ChartStyle chartStyle() const { return mChartStyle; }
3172   double width() const { return mWidth; }
3173   bool twoColored() const { return mTwoColored; }
3174   QBrush brushPositive() const { return mBrushPositive; }
3175   QBrush brushNegative() const { return mBrushNegative; }
3176   QPen penPositive() const { return mPenPositive; }
3177   QPen penNegative() const { return mPenNegative; }
3178 
3179 
3180   // setters:
3181   void setData(QCPFinancialDataMap *data, bool copy=false);
3182   void setData(const QVector<double> &key, const QVector<double> &open, const QVector<double> &high, const QVector<double> &low, const QVector<double> &close);
3183   void setChartStyle(ChartStyle style);
3184   void setWidth(double width);
3185   void setTwoColored(bool twoColored);
3186   void setBrushPositive(const QBrush &brush);
3187   void setBrushNegative(const QBrush &brush);
3188   void setPenPositive(const QPen &pen);
3189   void setPenNegative(const QPen &pen);
3190 
3191   // non-property methods:
3192   void addData(const QCPFinancialDataMap &dataMap);
3193   void addData(const QCPFinancialData &data);
3194   void addData(double key, double open, double high, double low, double close);
3195   void addData(const QVector<double> &key, const QVector<double> &open, const QVector<double> &high, const QVector<double> &low, const QVector<double> &close);
3196   void removeDataBefore(double key);
3197   void removeDataAfter(double key);
3198   void removeData(double fromKey, double toKey);
3199   void removeData(double key);
3200 
3201   // reimplemented virtual methods:
3202   virtual void clearData();
3203   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
3204 
3205   // static methods:
3206   static QCPFinancialDataMap timeSeriesToOhlc(const QVector<double> &time, const QVector<double> &value, double timeBinSize, double timeBinOffset = 0);
3207 
3208 protected:
3209   // property members:
3210   QCPFinancialDataMap *mData;
3211   ChartStyle mChartStyle;
3212   double mWidth;
3213   bool mTwoColored;
3214   QBrush mBrushPositive, mBrushNegative;
3215   QPen mPenPositive, mPenNegative;
3216 
3217   // reimplemented virtual methods:
3218   virtual void draw(QCPPainter *painter);
3219   virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const;
3220   virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const;
3221   virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const;
3222 
3223   // non-virtual methods:
3224   void drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end);
3225   void drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end);
3226   double ohlcSelectTest(const QPointF &pos, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end) const;
3227   double candlestickSelectTest(const QPointF &pos, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end) const;
3228   void getVisibleDataBounds(QCPFinancialDataMap::const_iterator &lower, QCPFinancialDataMap::const_iterator &upper) const;
3229 
3230   friend class QCustomPlot;
3231   friend class QCPLegend;
3232 };
3233 
3234 
3235 class QCP_LIB_DECL QCPItemStraightLine : public QCPAbstractItem
3236 {
3237   Q_OBJECT
3238   /// \cond INCLUDE_QPROPERTIES
3239   Q_PROPERTY(QPen pen READ pen WRITE setPen)
3240   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
3241   /// \endcond
3242 public:
3243   QCPItemStraightLine(QCustomPlot *parentPlot);
3244   virtual ~QCPItemStraightLine();
3245 
3246   // getters:
3247   QPen pen() const { return mPen; }
3248   QPen selectedPen() const { return mSelectedPen; }
3249 
3250   // setters;
3251   void setPen(const QPen &pen);
3252   void setSelectedPen(const QPen &pen);
3253 
3254   // reimplemented virtual methods:
3255   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
3256 
3257   QCPItemPosition * const point1;
3258   QCPItemPosition * const point2;
3259 
3260 protected:
3261   // property members:
3262   QPen mPen, mSelectedPen;
3263 
3264   // reimplemented virtual methods:
3265   virtual void draw(QCPPainter *painter);
3266 
3267   // non-virtual methods:
3268   double distToStraightLine(const QVector2D &point1, const QVector2D &vec, const QVector2D &point) const;
3269   QLineF getRectClippedStraightLine(const QVector2D &point1, const QVector2D &vec, const QRect &rect) const;
3270   QPen mainPen() const;
3271 };
3272 
3273 
3274 class QCP_LIB_DECL QCPItemLine : public QCPAbstractItem
3275 {
3276   Q_OBJECT
3277   /// \cond INCLUDE_QPROPERTIES
3278   Q_PROPERTY(QPen pen READ pen WRITE setPen)
3279   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
3280   Q_PROPERTY(QCPLineEnding head READ head WRITE setHead)
3281   Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail)
3282   /// \endcond
3283 public:
3284   QCPItemLine(QCustomPlot *parentPlot);
3285   virtual ~QCPItemLine();
3286 
3287   // getters:
3288   QPen pen() const { return mPen; }
3289   QPen selectedPen() const { return mSelectedPen; }
3290   QCPLineEnding head() const { return mHead; }
3291   QCPLineEnding tail() const { return mTail; }
3292 
3293   // setters;
3294   void setPen(const QPen &pen);
3295   void setSelectedPen(const QPen &pen);
3296   void setHead(const QCPLineEnding &head);
3297   void setTail(const QCPLineEnding &tail);
3298 
3299   // reimplemented virtual methods:
3300   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
3301 
3302   QCPItemPosition * const start;
3303   QCPItemPosition * const end;
3304 
3305 protected:
3306   // property members:
3307   QPen mPen, mSelectedPen;
3308   QCPLineEnding mHead, mTail;
3309 
3310   // reimplemented virtual methods:
3311   virtual void draw(QCPPainter *painter);
3312 
3313   // non-virtual methods:
3314   QLineF getRectClippedLine(const QVector2D &start, const QVector2D &end, const QRect &rect) const;
3315   QPen mainPen() const;
3316 };
3317 
3318 
3319 class QCP_LIB_DECL QCPItemCurve : public QCPAbstractItem
3320 {
3321   Q_OBJECT
3322   /// \cond INCLUDE_QPROPERTIES
3323   Q_PROPERTY(QPen pen READ pen WRITE setPen)
3324   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
3325   Q_PROPERTY(QCPLineEnding head READ head WRITE setHead)
3326   Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail)
3327   /// \endcond
3328 public:
3329   QCPItemCurve(QCustomPlot *parentPlot);
3330   virtual ~QCPItemCurve();
3331 
3332   // getters:
3333   QPen pen() const { return mPen; }
3334   QPen selectedPen() const { return mSelectedPen; }
3335   QCPLineEnding head() const { return mHead; }
3336   QCPLineEnding tail() const { return mTail; }
3337 
3338   // setters;
3339   void setPen(const QPen &pen);
3340   void setSelectedPen(const QPen &pen);
3341   void setHead(const QCPLineEnding &head);
3342   void setTail(const QCPLineEnding &tail);
3343 
3344   // reimplemented virtual methods:
3345   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
3346 
3347   QCPItemPosition * const start;
3348   QCPItemPosition * const startDir;
3349   QCPItemPosition * const endDir;
3350   QCPItemPosition * const end;
3351 
3352 protected:
3353   // property members:
3354   QPen mPen, mSelectedPen;
3355   QCPLineEnding mHead, mTail;
3356 
3357   // reimplemented virtual methods:
3358   virtual void draw(QCPPainter *painter);
3359 
3360   // non-virtual methods:
3361   QPen mainPen() const;
3362 };
3363 
3364 
3365 class QCP_LIB_DECL QCPItemRect : public QCPAbstractItem
3366 {
3367   Q_OBJECT
3368   /// \cond INCLUDE_QPROPERTIES
3369   Q_PROPERTY(QPen pen READ pen WRITE setPen)
3370   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
3371   Q_PROPERTY(QBrush brush READ brush WRITE setBrush)
3372   Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush)
3373   /// \endcond
3374 public:
3375   QCPItemRect(QCustomPlot *parentPlot);
3376   virtual ~QCPItemRect();
3377 
3378   // getters:
3379   QPen pen() const { return mPen; }
3380   QPen selectedPen() const { return mSelectedPen; }
3381   QBrush brush() const { return mBrush; }
3382   QBrush selectedBrush() const { return mSelectedBrush; }
3383 
3384   // setters;
3385   void setPen(const QPen &pen);
3386   void setSelectedPen(const QPen &pen);
3387   void setBrush(const QBrush &brush);
3388   void setSelectedBrush(const QBrush &brush);
3389 
3390   // reimplemented virtual methods:
3391   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
3392 
3393   QCPItemPosition * const topLeft;
3394   QCPItemPosition * const bottomRight;
3395   QCPItemAnchor * const top;
3396   QCPItemAnchor * const topRight;
3397   QCPItemAnchor * const right;
3398   QCPItemAnchor * const bottom;
3399   QCPItemAnchor * const bottomLeft;
3400   QCPItemAnchor * const left;
3401 
3402 protected:
3403   enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft};
3404 
3405   // property members:
3406   QPen mPen, mSelectedPen;
3407   QBrush mBrush, mSelectedBrush;
3408 
3409   // reimplemented virtual methods:
3410   virtual void draw(QCPPainter *painter);
3411   virtual QPointF anchorPixelPoint(int anchorId) const;
3412 
3413   // non-virtual methods:
3414   QPen mainPen() const;
3415   QBrush mainBrush() const;
3416 };
3417 
3418 
3419 class QCP_LIB_DECL QCPItemText : public QCPAbstractItem
3420 {
3421   Q_OBJECT
3422   /// \cond INCLUDE_QPROPERTIES
3423   Q_PROPERTY(QColor color READ color WRITE setColor)
3424   Q_PROPERTY(QColor selectedColor READ selectedColor WRITE setSelectedColor)
3425   Q_PROPERTY(QPen pen READ pen WRITE setPen)
3426   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
3427   Q_PROPERTY(QBrush brush READ brush WRITE setBrush)
3428   Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush)
3429   Q_PROPERTY(QFont font READ font WRITE setFont)
3430   Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont)
3431   Q_PROPERTY(QString text READ text WRITE setText)
3432   Q_PROPERTY(Qt::Alignment positionAlignment READ positionAlignment WRITE setPositionAlignment)
3433   Q_PROPERTY(Qt::Alignment textAlignment READ textAlignment WRITE setTextAlignment)
3434   Q_PROPERTY(double rotation READ rotation WRITE setRotation)
3435   Q_PROPERTY(QMargins padding READ padding WRITE setPadding)
3436   /// \endcond
3437 public:
3438   QCPItemText(QCustomPlot *parentPlot);
3439   virtual ~QCPItemText();
3440 
3441   // getters:
3442   QColor color() const { return mColor; }
3443   QColor selectedColor() const { return mSelectedColor; }
3444   QPen pen() const { return mPen; }
3445   QPen selectedPen() const { return mSelectedPen; }
3446   QBrush brush() const { return mBrush; }
3447   QBrush selectedBrush() const { return mSelectedBrush; }
3448   QFont font() const { return mFont; }
3449   QFont selectedFont() const { return mSelectedFont; }
3450   QString text() const { return mText; }
3451   Qt::Alignment positionAlignment() const { return mPositionAlignment; }
3452   Qt::Alignment textAlignment() const { return mTextAlignment; }
3453   double rotation() const { return mRotation; }
3454   QMargins padding() const { return mPadding; }
3455 
3456   // setters;
3457   void setColor(const QColor &color);
3458   void setSelectedColor(const QColor &color);
3459   void setPen(const QPen &pen);
3460   void setSelectedPen(const QPen &pen);
3461   void setBrush(const QBrush &brush);
3462   void setSelectedBrush(const QBrush &brush);
3463   void setFont(const QFont &font);
3464   void setSelectedFont(const QFont &font);
3465   void setText(const QString &text);
3466   void setPositionAlignment(Qt::Alignment alignment);
3467   void setTextAlignment(Qt::Alignment alignment);
3468   void setRotation(double degrees);
3469   void setPadding(const QMargins &padding);
3470 
3471   // reimplemented virtual methods:
3472   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
3473 
3474   QCPItemPosition * const position;
3475   QCPItemAnchor * const topLeft;
3476   QCPItemAnchor * const top;
3477   QCPItemAnchor * const topRight;
3478   QCPItemAnchor * const right;
3479   QCPItemAnchor * const bottomRight;
3480   QCPItemAnchor * const bottom;
3481   QCPItemAnchor * const bottomLeft;
3482   QCPItemAnchor * const left;
3483 
3484 protected:
3485   enum AnchorIndex {aiTopLeft, aiTop, aiTopRight, aiRight, aiBottomRight, aiBottom, aiBottomLeft, aiLeft};
3486 
3487   // property members:
3488   QColor mColor, mSelectedColor;
3489   QPen mPen, mSelectedPen;
3490   QBrush mBrush, mSelectedBrush;
3491   QFont mFont, mSelectedFont;
3492   QString mText;
3493   Qt::Alignment mPositionAlignment;
3494   Qt::Alignment mTextAlignment;
3495   double mRotation;
3496   QMargins mPadding;
3497 
3498   // reimplemented virtual methods:
3499   virtual void draw(QCPPainter *painter);
3500   virtual QPointF anchorPixelPoint(int anchorId) const;
3501 
3502   // non-virtual methods:
3503   QPointF getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const;
3504   QFont mainFont() const;
3505   QColor mainColor() const;
3506   QPen mainPen() const;
3507   QBrush mainBrush() const;
3508 };
3509 
3510 
3511 class QCP_LIB_DECL QCPItemEllipse : public QCPAbstractItem
3512 {
3513   Q_OBJECT
3514   /// \cond INCLUDE_QPROPERTIES
3515   Q_PROPERTY(QPen pen READ pen WRITE setPen)
3516   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
3517   Q_PROPERTY(QBrush brush READ brush WRITE setBrush)
3518   Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush)
3519   /// \endcond
3520 public:
3521   QCPItemEllipse(QCustomPlot *parentPlot);
3522   virtual ~QCPItemEllipse();
3523 
3524   // getters:
3525   QPen pen() const { return mPen; }
3526   QPen selectedPen() const { return mSelectedPen; }
3527   QBrush brush() const { return mBrush; }
3528   QBrush selectedBrush() const { return mSelectedBrush; }
3529 
3530   // setters;
3531   void setPen(const QPen &pen);
3532   void setSelectedPen(const QPen &pen);
3533   void setBrush(const QBrush &brush);
3534   void setSelectedBrush(const QBrush &brush);
3535 
3536   // reimplemented virtual methods:
3537   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
3538 
3539   QCPItemPosition * const topLeft;
3540   QCPItemPosition * const bottomRight;
3541   QCPItemAnchor * const topLeftRim;
3542   QCPItemAnchor * const top;
3543   QCPItemAnchor * const topRightRim;
3544   QCPItemAnchor * const right;
3545   QCPItemAnchor * const bottomRightRim;
3546   QCPItemAnchor * const bottom;
3547   QCPItemAnchor * const bottomLeftRim;
3548   QCPItemAnchor * const left;
3549   QCPItemAnchor * const center;
3550 
3551 protected:
3552   enum AnchorIndex {aiTopLeftRim, aiTop, aiTopRightRim, aiRight, aiBottomRightRim, aiBottom, aiBottomLeftRim, aiLeft, aiCenter};
3553 
3554   // property members:
3555   QPen mPen, mSelectedPen;
3556   QBrush mBrush, mSelectedBrush;
3557 
3558   // reimplemented virtual methods:
3559   virtual void draw(QCPPainter *painter);
3560   virtual QPointF anchorPixelPoint(int anchorId) const;
3561 
3562   // non-virtual methods:
3563   QPen mainPen() const;
3564   QBrush mainBrush() const;
3565 };
3566 
3567 
3568 class QCP_LIB_DECL QCPItemPixmap : public QCPAbstractItem
3569 {
3570   Q_OBJECT
3571   /// \cond INCLUDE_QPROPERTIES
3572   Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap)
3573   Q_PROPERTY(bool scaled READ scaled WRITE setScaled)
3574   Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode)
3575   Q_PROPERTY(Qt::TransformationMode transformationMode READ transformationMode)
3576   Q_PROPERTY(QPen pen READ pen WRITE setPen)
3577   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
3578   /// \endcond
3579 public:
3580   QCPItemPixmap(QCustomPlot *parentPlot);
3581   virtual ~QCPItemPixmap();
3582 
3583   // getters:
3584   QPixmap pixmap() const { return mPixmap; }
3585   bool scaled() const { return mScaled; }
3586   Qt::AspectRatioMode aspectRatioMode() const { return mAspectRatioMode; }
3587   Qt::TransformationMode transformationMode() const { return mTransformationMode; }
3588   QPen pen() const { return mPen; }
3589   QPen selectedPen() const { return mSelectedPen; }
3590 
3591   // setters;
3592   void setPixmap(const QPixmap &pixmap);
3593   void setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio, Qt::TransformationMode transformationMode=Qt::SmoothTransformation);
3594   void setPen(const QPen &pen);
3595   void setSelectedPen(const QPen &pen);
3596 
3597   // reimplemented virtual methods:
3598   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
3599 
3600   QCPItemPosition * const topLeft;
3601   QCPItemPosition * const bottomRight;
3602   QCPItemAnchor * const top;
3603   QCPItemAnchor * const topRight;
3604   QCPItemAnchor * const right;
3605   QCPItemAnchor * const bottom;
3606   QCPItemAnchor * const bottomLeft;
3607   QCPItemAnchor * const left;
3608 
3609 protected:
3610   enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft};
3611 
3612   // property members:
3613   QPixmap mPixmap;
3614   QPixmap mScaledPixmap;
3615   bool mScaled;
3616   bool mScaledPixmapInvalidated;
3617   Qt::AspectRatioMode mAspectRatioMode;
3618   Qt::TransformationMode mTransformationMode;
3619   QPen mPen, mSelectedPen;
3620 
3621   // reimplemented virtual methods:
3622   virtual void draw(QCPPainter *painter);
3623   virtual QPointF anchorPixelPoint(int anchorId) const;
3624 
3625   // non-virtual methods:
3626   void updateScaledPixmap(QRect finalRect=QRect(), bool flipHorz=false, bool flipVert=false);
3627   QRect getFinalRect(bool *flippedHorz=Q_NULLPTR, bool *flippedVert=Q_NULLPTR) const;
3628   QPen mainPen() const;
3629 };
3630 
3631 
3632 class QCP_LIB_DECL QCPItemTracer : public QCPAbstractItem
3633 {
3634   Q_OBJECT
3635   /// \cond INCLUDE_QPROPERTIES
3636   Q_PROPERTY(QPen pen READ pen WRITE setPen)
3637   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
3638   Q_PROPERTY(QBrush brush READ brush WRITE setBrush)
3639   Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush)
3640   Q_PROPERTY(double size READ size WRITE setSize)
3641   Q_PROPERTY(TracerStyle style READ style WRITE setStyle)
3642   Q_PROPERTY(QCPGraph* graph READ graph WRITE setGraph)
3643   Q_PROPERTY(double graphKey READ graphKey WRITE setGraphKey)
3644   Q_PROPERTY(bool interpolating READ interpolating WRITE setInterpolating)
3645   /// \endcond
3646 public:
3647   /*!
3648     The different visual appearances a tracer item can have. Some styles size may be controlled with \ref setSize.
3649 
3650     \see setStyle
3651   */
3652   enum TracerStyle { tsNone        ///< The tracer is not visible
3653                      ,tsPlus       ///< A plus shaped crosshair with limited size
3654                      ,tsCrosshair  ///< A plus shaped crosshair which spans the complete axis rect
3655                      ,tsCircle     ///< A circle
3656                      ,tsSquare     ///< A square
3657                    };
3658   Q_ENUM(TracerStyle)
3659 
3660   QCPItemTracer(QCustomPlot *parentPlot);
3661   virtual ~QCPItemTracer();
3662 
3663   // getters:
3664   QPen pen() const { return mPen; }
3665   QPen selectedPen() const { return mSelectedPen; }
3666   QBrush brush() const { return mBrush; }
3667   QBrush selectedBrush() const { return mSelectedBrush; }
3668   double size() const { return mSize; }
3669   TracerStyle style() const { return mStyle; }
3670   QCPGraph *graph() const { return mGraph; }
3671   double graphKey() const { return mGraphKey; }
3672   bool interpolating() const { return mInterpolating; }
3673 
3674   // setters;
3675   void setPen(const QPen &pen);
3676   void setSelectedPen(const QPen &pen);
3677   void setBrush(const QBrush &brush);
3678   void setSelectedBrush(const QBrush &brush);
3679   void setSize(double size);
3680   void setStyle(TracerStyle style);
3681   void setGraph(QCPGraph *graph);
3682   void setGraphKey(double key);
3683   void setInterpolating(bool enabled);
3684 
3685   // reimplemented virtual methods:
3686   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
3687 
3688   // non-virtual methods:
3689   void updatePosition();
3690 
3691   QCPItemPosition * const position;
3692 
3693 protected:
3694   // property members:
3695   QPen mPen, mSelectedPen;
3696   QBrush mBrush, mSelectedBrush;
3697   double mSize;
3698   TracerStyle mStyle;
3699   QCPGraph *mGraph;
3700   double mGraphKey;
3701   bool mInterpolating;
3702 
3703   // reimplemented virtual methods:
3704   virtual void draw(QCPPainter *painter);
3705 
3706   // non-virtual methods:
3707   QPen mainPen() const;
3708   QBrush mainBrush() const;
3709 };
3710 
3711 
3712 class QCP_LIB_DECL QCPItemBracket : public QCPAbstractItem
3713 {
3714   Q_OBJECT
3715   /// \cond INCLUDE_QPROPERTIES
3716   Q_PROPERTY(QPen pen READ pen WRITE setPen)
3717   Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen)
3718   Q_PROPERTY(double length READ length WRITE setLength)
3719   Q_PROPERTY(BracketStyle style READ style WRITE setStyle)
3720   /// \endcond
3721 public:
3722   enum BracketStyle { bsSquare  ///< A brace with angled edges
3723                       ,bsRound  ///< A brace with round edges
3724                       ,bsCurly  ///< A curly brace
3725                       ,bsCalligraphic ///< A curly brace with varying stroke width giving a calligraphic impression
3726   };
3727 
3728   QCPItemBracket(QCustomPlot *parentPlot);
3729   virtual ~QCPItemBracket();
3730 
3731   // getters:
3732   QPen pen() const { return mPen; }
3733   QPen selectedPen() const { return mSelectedPen; }
3734   double length() const { return mLength; }
3735   BracketStyle style() const { return mStyle; }
3736 
3737   // setters;
3738   void setPen(const QPen &pen);
3739   void setSelectedPen(const QPen &pen);
3740   void setLength(double length);
3741   void setStyle(BracketStyle style);
3742 
3743   // reimplemented virtual methods:
3744   virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=Q_NULLPTR) const;
3745 
3746   QCPItemPosition * const left;
3747   QCPItemPosition * const right;
3748   QCPItemAnchor * const center;
3749 
3750 protected:
3751   // property members:
3752   enum AnchorIndex {aiCenter};
3753   QPen mPen, mSelectedPen;
3754   double mLength;
3755   BracketStyle mStyle;
3756 
3757   // reimplemented virtual methods:
3758   virtual void draw(QCPPainter *painter);
3759   virtual QPointF anchorPixelPoint(int anchorId) const;
3760 
3761   // non-virtual methods:
3762   QPen mainPen() const;
3763 };
3764 
3765 #endif // QCUSTOMPLOT_H
3766 
3767