Kstars

qcustomplot.h
1 /*
2  QCustomPlot, an easy to use, modern plotting widget for Qt
3  SPDX-FileCopyrightText: 2011-2021 Emanuel Eichhammer <http://www.qcustomplot.com/>
4 
5  SPDX-License-Identifier: GPL-3.0-or-later
6 */
7 
8 #ifndef QCUSTOMPLOT_H
9 #define QCUSTOMPLOT_H
10 
11 #include <QtCore/qglobal.h>
12 
13 // some Qt version/configuration dependent macros to include or exclude certain code paths:
14 #ifdef QCUSTOMPLOT_USE_OPENGL
15 # if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
16 # define QCP_OPENGL_PBUFFER
17 # else
18 # define QCP_OPENGL_FBO
19 # endif
20 # if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0)
21 # define QCP_OPENGL_OFFSCREENSURFACE
22 # endif
23 #endif
24 
25 #define QCP_DEVICEPIXELRATIO_SUPPORTED
26 #define QCP_DEVICEPIXELRATIO_FLOAT
27 
28 #include <QtCore/QObject>
29 #include <QtCore/QPointer>
30 #include <QtCore/QSharedPointer>
31 #include <QtCore/QTimer>
32 #include <QtGui/QPainter>
33 #include <QtGui/QPainterPath>
34 #include <QtGui/QPaintEvent>
35 #include <QtGui/QMouseEvent>
36 #include <QtGui/QWheelEvent>
37 #include <QtGui/QPixmap>
38 #include <QtCore/QVector>
39 #include <QtCore/QString>
40 #include <QtCore/QDateTime>
41 #include <QtCore/QMultiMap>
42 #include <QtCore/QFlags>
43 #include <QtCore/QDebug>
44 #include <QtCore/QStack>
45 #include <QtCore/QCache>
46 #include <QtCore/QMargins>
47 #include <qmath.h>
48 #include <limits>
49 #include <algorithm>
50 #ifdef QCP_OPENGL_FBO
51 # include <QtGui/QOpenGLContext>
52 # if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
53 # include <QtGui/QOpenGLFramebufferObject>
54 # else
55 # include <QOpenGLFramebufferObject>
56 # include <QOpenGLPaintDevice>
57 # endif
58 # ifdef QCP_OPENGL_OFFSCREENSURFACE
59 # include <QtGui/QOffscreenSurface>
60 # else
61 # include <QtGui/QWindow>
62 # endif
63 #endif
64 #ifdef QCP_OPENGL_PBUFFER
65 # include <QtOpenGL/QGLPixelBuffer>
66 #endif
67 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
68 # include <qnumeric.h>
69 # include <QtGui/QWidget>
70 # include <QtGui/QPrinter>
71 # include <QtGui/QPrintEngine>
72 #else
73 # include <QtNumeric>
74 # include <QtWidgets/QWidget>
75 # include <QtPrintSupport/QtPrintSupport>
76 #endif
77 #if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0)
78 # include <QtCore/QElapsedTimer>
79 #endif
80 # if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
81 # include <QtCore/QTimeZone>
82 #endif
83 
84 class QCPPainter;
85 class QCustomPlot;
86 class QCPLayerable;
87 class QCPLayoutElement;
88 class QCPLayout;
89 class QCPAxis;
90 class QCPAxisRect;
93 class QCPGraph;
94 class QCPAbstractItem;
96 class QCPLegend;
97 class QCPItemPosition;
98 class QCPLayer;
100 class QCPSelectionRect;
101 class QCPColorMap;
102 class QCPColorScale;
103 class QCPBars;
104 class QCPPolarAxisRadial;
105 class QCPPolarAxisAngular;
106 class QCPPolarGrid;
107 class QCPPolarGraph;
108 
109 /* including file 'src/global.h' */
110 /* modified 2021-03-29T02:30:44, size 16981 */
111 
112 #define QCUSTOMPLOT_VERSION_STR "2.1.0"
113 #define QCUSTOMPLOT_VERSION 0x020100
114 
115 // decl definitions for shared library compilation/usage:
116 #if defined(QT_STATIC_BUILD)
117 # define QCP_LIB_DECL
118 #elif defined(QCUSTOMPLOT_COMPILE_LIBRARY)
119 # define QCP_LIB_DECL Q_DECL_EXPORT
120 #elif defined(QCUSTOMPLOT_USE_LIBRARY)
121 # define QCP_LIB_DECL Q_DECL_IMPORT
122 #else
123 # define QCP_LIB_DECL
124 #endif
125 
126 // define empty macro for Q_DECL_OVERRIDE if it doesn't exist (Qt < 5)
127 #ifndef Q_DECL_OVERRIDE
128 # define Q_DECL_OVERRIDE
129 #endif
130 
131 /*!
132  The QCP Namespace contains general enums, QFlags and functions used throughout the QCustomPlot
133  library.
134 
135  It provides QMetaObject-based reflection of its enums and flags via \a QCP::staticMetaObject.
136 */
137 #ifndef Q_MOC_RUN
138 namespace QCP {
139 #else
140 class QCP { // when in moc-run, make it look like a class, so we get Q_GADGET, Q_ENUMS/Q_FLAGS features in namespace
141  Q_GADGET
142  Q_ENUMS(ExportPen)
143  Q_ENUMS(ResolutionUnit)
144  Q_ENUMS(SignDomain)
145  Q_ENUMS(MarginSide)
146  Q_FLAGS(MarginSides)
147  Q_ENUMS(AntialiasedElement)
148  Q_FLAGS(AntialiasedElements)
149  Q_ENUMS(PlottingHint)
150  Q_FLAGS(PlottingHints)
151  Q_ENUMS(Interaction)
152  Q_FLAGS(Interactions)
153  Q_ENUMS(SelectionRectMode)
154  Q_ENUMS(SelectionType)
155 public:
156 #endif
157 
158 /*!
159  Defines the different units in which the image resolution can be specified in the export
160  functions.
161 
162  \see QCustomPlot::savePng, QCustomPlot::saveJpg, QCustomPlot::saveBmp, QCustomPlot::saveRastered
163 */
164 enum ResolutionUnit { ruDotsPerMeter ///< Resolution is given in dots per meter (dpm)
165  ,ruDotsPerCentimeter ///< Resolution is given in dots per centimeter (dpcm)
166  ,ruDotsPerInch ///< Resolution is given in dots per inch (DPI/PPI)
167  };
168 
169 /*!
170  Defines how cosmetic pens (pens with numerical width 0) are handled during export.
171 
172  \see QCustomPlot::savePdf
173 */
174 enum ExportPen { epNoCosmetic ///< Cosmetic pens are converted to pens with pixel width 1 when exporting
175  ,epAllowCosmetic ///< Cosmetic pens are exported normally (e.g. in PDF exports, cosmetic pens always appear as 1 pixel on screen, independent of viewer zoom level)
176  };
177 
178 /*!
179  Represents negative and positive sign domain, e.g. for passing to \ref
180  QCPAbstractPlottable::getKeyRange and \ref QCPAbstractPlottable::getValueRange.
181 
182  This is primarily needed when working with logarithmic axis scales, since only one of the sign
183  domains can be visible at a time.
184 */
185 enum SignDomain { sdNegative ///< The negative sign domain, i.e. numbers smaller than zero
186  ,sdBoth ///< Both sign domains, including zero, i.e. all numbers
187  ,sdPositive ///< The positive sign domain, i.e. numbers greater than zero
188  };
189 
190 /*!
191  Defines the sides of a rectangular entity to which margins can be applied.
192 
193  \see QCPLayoutElement::setAutoMargins, QCPAxisRect::setAutoMargins
194 */
195 enum MarginSide { msLeft = 0x01 ///< <tt>0x01</tt> left margin
196  ,msRight = 0x02 ///< <tt>0x02</tt> right margin
197  ,msTop = 0x04 ///< <tt>0x04</tt> top margin
198  ,msBottom = 0x08 ///< <tt>0x08</tt> bottom margin
199  ,msAll = 0xFF ///< <tt>0xFF</tt> all margins
200  ,msNone = 0x00 ///< <tt>0x00</tt> no margin
201  };
202 Q_DECLARE_FLAGS(MarginSides, MarginSide)
203 
204 /*!
205  Defines what objects of a plot can be forcibly drawn antialiased/not antialiased. If an object is
206  neither forcibly drawn antialiased nor forcibly drawn not antialiased, it is up to the respective
207  element how it is drawn. Typically it provides a \a setAntialiased function for this.
208 
209  \c AntialiasedElements is a flag of or-combined elements of this enum type.
210 
211  \see QCustomPlot::setAntialiasedElements, QCustomPlot::setNotAntialiasedElements
212 */
213 enum AntialiasedElement { aeAxes = 0x0001 ///< <tt>0x0001</tt> Axis base line and tick marks
214  ,aeGrid = 0x0002 ///< <tt>0x0002</tt> Grid lines
215  ,aeSubGrid = 0x0004 ///< <tt>0x0004</tt> Sub grid lines
216  ,aeLegend = 0x0008 ///< <tt>0x0008</tt> Legend box
217  ,aeLegendItems = 0x0010 ///< <tt>0x0010</tt> Legend items
218  ,aePlottables = 0x0020 ///< <tt>0x0020</tt> Main lines of plottables
219  ,aeItems = 0x0040 ///< <tt>0x0040</tt> Main lines of items
220  ,aeScatters = 0x0080 ///< <tt>0x0080</tt> Scatter symbols of plottables (excluding scatter symbols of type ssPixmap)
221  ,aeFills = 0x0100 ///< <tt>0x0100</tt> Borders of fills (e.g. under or between graphs)
222  ,aeZeroLine = 0x0200 ///< <tt>0x0200</tt> Zero-lines, see \ref QCPGrid::setZeroLinePen
223  ,aeOther = 0x8000 ///< <tt>0x8000</tt> Other elements that don't fit into any of the existing categories
224  ,aeAll = 0xFFFF ///< <tt>0xFFFF</tt> All elements
225  ,aeNone = 0x0000 ///< <tt>0x0000</tt> No elements
226  };
227 Q_DECLARE_FLAGS(AntialiasedElements, AntialiasedElement)
228 
229 /*!
230  Defines plotting hints that control various aspects of the quality and speed of plotting.
231 
232  \see QCustomPlot::setPlottingHints
233 */
234 enum PlottingHint { phNone = 0x000 ///< <tt>0x000</tt> No hints are set
235  ,phFastPolylines = 0x001 ///< <tt>0x001</tt> Graph/Curve lines are drawn with a faster method. This reduces the quality especially of the line segment
236  ///< joins, thus is most effective for pen sizes larger than 1. It is only used for solid line pens.
237  ,phImmediateRefresh = 0x002 ///< <tt>0x002</tt> causes an immediate repaint() instead of a soft update() when QCustomPlot::replot() is called with parameter \ref QCustomPlot::rpRefreshHint.
238  ///< This is set by default to prevent the plot from freezing on fast consecutive replots (e.g. user drags ranges with mouse).
239  ,phCacheLabels = 0x004 ///< <tt>0x004</tt> axis (tick) labels will be cached as pixmaps, increasing replot performance.
240  };
241 Q_DECLARE_FLAGS(PlottingHints, PlottingHint)
242 
243 /*!
244  Defines the mouse interactions possible with QCustomPlot.
245 
246  \c Interactions is a flag of or-combined elements of this enum type.
247 
248  \see QCustomPlot::setInteractions
249 */
250 enum Interaction { iNone = 0x000 ///< <tt>0x000</tt> None of the interactions are possible
251  ,iRangeDrag = 0x001 ///< <tt>0x001</tt> Axis ranges are draggable (see \ref QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeDragAxes)
252  ,iRangeZoom = 0x002 ///< <tt>0x002</tt> Axis ranges are zoomable with the mouse wheel (see \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeZoomAxes)
253  ,iMultiSelect = 0x004 ///< <tt>0x004</tt> The user can select multiple objects by holding the modifier set by \ref QCustomPlot::setMultiSelectModifier while clicking
254  ,iSelectPlottables = 0x008 ///< <tt>0x008</tt> Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable)
255  ,iSelectAxes = 0x010 ///< <tt>0x010</tt> Axes are selectable (or parts of them, see QCPAxis::setSelectableParts)
256  ,iSelectLegend = 0x020 ///< <tt>0x020</tt> Legends are selectable (or their child items, see QCPLegend::setSelectableParts)
257  ,iSelectItems = 0x040 ///< <tt>0x040</tt> Items are selectable (Rectangles, Arrows, Textitems, etc. see \ref QCPAbstractItem)
258  ,iSelectOther = 0x080 ///< <tt>0x080</tt> All other objects are selectable (e.g. your own derived layerables, other layout elements,...)
259  ,iSelectPlottablesBeyondAxisRect = 0x100 ///< <tt>0x100</tt> When performing plottable selection/hit tests, this flag extends the sensitive area beyond the axis rect
260  };
261 Q_DECLARE_FLAGS(Interactions, Interaction)
262 
263 /*!
264  Defines the behaviour of the selection rect.
265 
266  \see QCustomPlot::setSelectionRectMode, QCustomPlot::selectionRect, QCPSelectionRect
267 */
268 enum SelectionRectMode { srmNone ///< The selection rect is disabled, and all mouse events are forwarded to the underlying objects, e.g. for axis range dragging
269  ,srmZoom ///< When dragging the mouse, a selection rect becomes active. Upon releasing, the axes that are currently set as range zoom axes (\ref QCPAxisRect::setRangeZoomAxes) will have their ranges zoomed accordingly.
270  ,srmSelect ///< When dragging the mouse, a selection rect becomes active. Upon releasing, plottable data points that were within the selection rect are selected, if the plottable's selectability setting permits. (See \ref dataselection "data selection mechanism" for details.)
271  ,srmCustom ///< When dragging the mouse, a selection rect becomes active. It is the programmer's responsibility to connect according slots to the selection rect's signals (e.g. \ref QCPSelectionRect::accepted) in order to process the user interaction.
272  };
273 
274 /*!
275  Defines the different ways a plottable can be selected. These images show the effect of the
276  different selection types, when the indicated selection rect was dragged:
277 
278  <center>
279  <table>
280  <tr>
281  <td>\image html selectiontype-none.png stNone</td>
282  <td>\image html selectiontype-whole.png stWhole</td>
283  <td>\image html selectiontype-singledata.png stSingleData</td>
284  <td>\image html selectiontype-datarange.png stDataRange</td>
285  <td>\image html selectiontype-multipledataranges.png stMultipleDataRanges</td>
286  </tr>
287  </table>
288  </center>
289 
290  \see QCPAbstractPlottable::setSelectable, QCPDataSelection::enforceType
291 */
292 enum SelectionType { stNone ///< The plottable is not selectable
293  ,stWhole ///< Selection behaves like \ref stMultipleDataRanges, but if there are any data points selected, the entire plottable is drawn as selected.
294  ,stSingleData ///< One individual data point can be selected at a time
295  ,stDataRange ///< Multiple contiguous data points (a data range) can be selected
296  ,stMultipleDataRanges ///< Any combination of data points/ranges can be selected
297  };
298 
299 /*! \internal
300 
301  Returns whether the specified \a value is considered an invalid data value for plottables (i.e.
302  is \e nan or \e +/-inf). This function is used to check data validity upon replots, when the
303  compiler flag \c QCUSTOMPLOT_CHECK_DATA is set.
304 */
305 inline bool isInvalidData(double value)
306 {
307  return qIsNaN(value) || qIsInf(value);
308 }
309 
310 /*! \internal
311  \overload
312 
313  Checks two arguments instead of one.
314 */
315 inline bool isInvalidData(double value1, double value2)
316 {
317  return isInvalidData(value1) || isInvalidData(value2);
318 }
319 
320 /*! \internal
321 
322  Sets the specified \a side of \a margins to \a value
323 
324  \see getMarginValue
325 */
326 inline void setMarginValue(QMargins &margins, QCP::MarginSide side, int value)
327 {
328  switch (side)
329  {
330  case QCP::msLeft: margins.setLeft(value); break;
331  case QCP::msRight: margins.setRight(value); break;
332  case QCP::msTop: margins.setTop(value); break;
333  case QCP::msBottom: margins.setBottom(value); break;
334  case QCP::msAll: margins = QMargins(value, value, value, value); break;
335  default: break;
336  }
337 }
338 
339 /*! \internal
340 
341  Returns the value of the specified \a side of \a margins. If \a side is \ref QCP::msNone or
342  \ref QCP::msAll, returns 0.
343 
344  \see setMarginValue
345 */
346 inline int getMarginValue(const QMargins &margins, QCP::MarginSide side)
347 {
348  switch (side)
349  {
350  case QCP::msLeft: return margins.left();
351  case QCP::msRight: return margins.right();
352  case QCP::msTop: return margins.top();
353  case QCP::msBottom: return margins.bottom();
354  default: break;
355  }
356  return 0;
357 }
358 
359 
360 extern const QMetaObject staticMetaObject; // in moc-run we create a static meta object for QCP "fake" object. This line is the link to it via QCP::staticMetaObject in normal operation as namespace
361 
362 } // end of namespace QCP
363 Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::AntialiasedElements)
364 Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::PlottingHints)
365 Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::MarginSides)
366 Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::Interactions)
367 Q_DECLARE_METATYPE(QCP::ExportPen)
368 Q_DECLARE_METATYPE(QCP::ResolutionUnit)
369 Q_DECLARE_METATYPE(QCP::SignDomain)
370 Q_DECLARE_METATYPE(QCP::MarginSide)
371 Q_DECLARE_METATYPE(QCP::AntialiasedElement)
372 Q_DECLARE_METATYPE(QCP::PlottingHint)
373 Q_DECLARE_METATYPE(QCP::Interaction)
374 Q_DECLARE_METATYPE(QCP::SelectionRectMode)
375 Q_DECLARE_METATYPE(QCP::SelectionType)
376 
377 /* end of 'src/global.h' */
378 
379 
380 /* including file 'src/vector2d.h' */
381 /* modified 2021-03-29T02:30:44, size 4988 */
382 
383 class QCP_LIB_DECL QCPVector2D
384 {
385 public:
386  QCPVector2D();
387  QCPVector2D(double x, double y);
388  QCPVector2D(const QPoint &point);
389  QCPVector2D(const QPointF &point);
390 
391  // getters:
392  double x() const { return mX; }
393  double y() const { return mY; }
394  double &rx() { return mX; }
395  double &ry() { return mY; }
396 
397  // setters:
398  void setX(double x) { mX = x; }
399  void setY(double y) { mY = y; }
400 
401  // non-virtual methods:
402  double length() const { return qSqrt(mX*mX+mY*mY); }
403  double lengthSquared() const { return mX*mX+mY*mY; }
404  double angle() const { return qAtan2(mY, mX); }
405  QPoint toPoint() const { return QPoint(int(mX), int(mY)); }
406  QPointF toPointF() const { return QPointF(mX, mY); }
407 
408  bool isNull() const { return qIsNull(mX) && qIsNull(mY); }
409  void normalize();
410  QCPVector2D normalized() const;
411  QCPVector2D perpendicular() const { return QCPVector2D(-mY, mX); }
412  double dot(const QCPVector2D &vec) const { return mX*vec.mX+mY*vec.mY; }
413  double distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const;
414  double distanceSquaredToLine(const QLineF &line) const;
415  double distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const;
416 
417  QCPVector2D &operator*=(double factor);
418  QCPVector2D &operator/=(double divisor);
419  QCPVector2D &operator+=(const QCPVector2D &vector);
420  QCPVector2D &operator-=(const QCPVector2D &vector);
421 
422 private:
423  // property members:
424  double mX, mY;
425 
426  friend inline const QCPVector2D operator*(double factor, const QCPVector2D &vec);
427  friend inline const QCPVector2D operator*(const QCPVector2D &vec, double factor);
428  friend inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor);
429  friend inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2);
430  friend inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2);
431  friend inline const QCPVector2D operator-(const QCPVector2D &vec);
432 };
433 Q_DECLARE_TYPEINFO(QCPVector2D, Q_MOVABLE_TYPE);
434 
435 inline const QCPVector2D operator*(double factor, const QCPVector2D &vec) { return QCPVector2D(vec.mX*factor, vec.mY*factor); }
436 inline const QCPVector2D operator*(const QCPVector2D &vec, double factor) { return QCPVector2D(vec.mX*factor, vec.mY*factor); }
437 inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor) { return QCPVector2D(vec.mX/divisor, vec.mY/divisor); }
438 inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX+vec2.mX, vec1.mY+vec2.mY); }
439 inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX-vec2.mX, vec1.mY-vec2.mY); }
440 inline const QCPVector2D operator-(const QCPVector2D &vec) { return QCPVector2D(-vec.mX, -vec.mY); }
441 
442 /*! \relates QCPVector2D
443 
444  Prints \a vec in a human readable format to the qDebug output.
445 */
446 inline QDebug operator<< (QDebug d, const QCPVector2D &vec)
447 {
448  d.nospace() << "QCPVector2D(" << vec.x() << ", " << vec.y() << ")";
449  return d.space();
450 }
451 
452 /* end of 'src/vector2d.h' */
453 
454 
455 /* including file 'src/painter.h' */
456 /* modified 2021-03-29T02:30:44, size 4035 */
457 
458 class QCP_LIB_DECL QCPPainter : public QPainter
459 {
460  Q_GADGET
461 public:
462  /*!
463  Defines special modes the painter can operate in. They disable or enable certain subsets of features/fixes/workarounds,
464  depending on whether they are wanted on the respective output device.
465  */
466  enum PainterMode { pmDefault = 0x00 ///< <tt>0x00</tt> Default mode for painting on screen devices
467  ,pmVectorized = 0x01 ///< <tt>0x01</tt> Mode for vectorized painting (e.g. PDF export). For example, this prevents some antialiasing fixes.
468  ,pmNoCaching = 0x02 ///< <tt>0x02</tt> Mode for all sorts of exports (e.g. PNG, PDF,...). For example, this prevents using cached pixmap labels
469  ,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.)
470  };
471  Q_ENUMS(PainterMode)
472  Q_FLAGS(PainterModes)
473  Q_DECLARE_FLAGS(PainterModes, PainterMode)
474 
475  QCPPainter();
476  explicit QCPPainter(QPaintDevice *device);
477 
478  // getters:
479  bool antialiasing() const { return testRenderHint(QPainter::Antialiasing); }
480  PainterModes modes() const { return mModes; }
481 
482  // setters:
483  void setAntialiasing(bool enabled);
484  void setMode(PainterMode mode, bool enabled=true);
485  void setModes(PainterModes modes);
486 
487  // methods hiding non-virtual base class functions (QPainter bug workarounds):
488  bool begin(QPaintDevice *device);
489  void setPen(const QPen &pen);
490  void setPen(const QColor &color);
491  void setPen(Qt::PenStyle penStyle);
492  void drawLine(const QLineF &line);
493  void drawLine(const QPointF &p1, const QPointF &p2) {drawLine(QLineF(p1, p2));}
494  void save();
495  void restore();
496 
497  // non-virtual methods:
498  void makeNonCosmetic();
499 
500 protected:
501  // property members:
502  PainterModes mModes;
503  bool mIsAntialiasing;
504 
505  // non-property members:
506  QStack<bool> mAntialiasingStack;
507 };
508 Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPainter::PainterModes)
509 Q_DECLARE_METATYPE(QCPPainter::PainterMode)
510 
511 /* end of 'src/painter.h' */
512 
513 
514 /* including file 'src/paintbuffer.h' */
515 /* modified 2021-03-29T02:30:44, size 5006 */
516 
517 class QCP_LIB_DECL QCPAbstractPaintBuffer
518 {
519 public:
520  explicit QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio);
521  virtual ~QCPAbstractPaintBuffer();
522 
523  // getters:
524  QSize size() const { return mSize; }
525  bool invalidated() const { return mInvalidated; }
526  double devicePixelRatio() const { return mDevicePixelRatio; }
527 
528  // setters:
529  void setSize(const QSize &size);
530  void setInvalidated(bool invalidated=true);
531  void setDevicePixelRatio(double ratio);
532 
533  // introduced virtual methods:
534  virtual QCPPainter *startPainting() = 0;
535  virtual void donePainting() {}
536  virtual void draw(QCPPainter *painter) const = 0;
537  virtual void clear(const QColor &color) = 0;
538 
539 protected:
540  // property members:
541  QSize mSize;
542  double mDevicePixelRatio;
543 
544  // non-property members:
545  bool mInvalidated;
546 
547  // introduced virtual methods:
548  virtual void reallocateBuffer() = 0;
549 };
550 
551 
552 class QCP_LIB_DECL QCPPaintBufferPixmap : public QCPAbstractPaintBuffer
553 {
554 public:
555  explicit QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio);
556  virtual ~QCPPaintBufferPixmap() Q_DECL_OVERRIDE;
557 
558  // reimplemented virtual methods:
559  virtual QCPPainter *startPainting() Q_DECL_OVERRIDE;
560  virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE;
561  void clear(const QColor &color) Q_DECL_OVERRIDE;
562 
563 protected:
564  // non-property members:
565  QPixmap mBuffer;
566 
567  // reimplemented virtual methods:
568  virtual void reallocateBuffer() Q_DECL_OVERRIDE;
569 };
570 
571 
572 #ifdef QCP_OPENGL_PBUFFER
573 class QCP_LIB_DECL QCPPaintBufferGlPbuffer : public QCPAbstractPaintBuffer
574 {
575 public:
576  explicit QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples);
577  virtual ~QCPPaintBufferGlPbuffer() Q_DECL_OVERRIDE;
578 
579  // reimplemented virtual methods:
580  virtual QCPPainter *startPainting() Q_DECL_OVERRIDE;
581  virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE;
582  void clear(const QColor &color) Q_DECL_OVERRIDE;
583 
584 protected:
585  // non-property members:
586  QGLPixelBuffer *mGlPBuffer;
587  int mMultisamples;
588 
589  // reimplemented virtual methods:
590  virtual void reallocateBuffer() Q_DECL_OVERRIDE;
591 };
592 #endif // QCP_OPENGL_PBUFFER
593 
594 
595 #ifdef QCP_OPENGL_FBO
596 class QCP_LIB_DECL QCPPaintBufferGlFbo : public QCPAbstractPaintBuffer
597 {
598 public:
599  explicit QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer<QOpenGLContext> glContext, QWeakPointer<QOpenGLPaintDevice> glPaintDevice);
600  virtual ~QCPPaintBufferGlFbo() Q_DECL_OVERRIDE;
601 
602  // reimplemented virtual methods:
603  virtual QCPPainter *startPainting() Q_DECL_OVERRIDE;
604  virtual void donePainting() Q_DECL_OVERRIDE;
605  virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE;
606  void clear(const QColor &color) Q_DECL_OVERRIDE;
607 
608 protected:
609  // non-property members:
610  QWeakPointer<QOpenGLContext> mGlContext;
611  QWeakPointer<QOpenGLPaintDevice> mGlPaintDevice;
612  QOpenGLFramebufferObject *mGlFrameBuffer;
613 
614  // reimplemented virtual methods:
615  virtual void reallocateBuffer() Q_DECL_OVERRIDE;
616 };
617 #endif // QCP_OPENGL_FBO
618 
619 /* end of 'src/paintbuffer.h' */
620 
621 
622 /* including file 'src/layer.h' */
623 /* modified 2021-03-29T02:30:44, size 7038 */
624 
625 class QCP_LIB_DECL QCPLayer : public QObject
626 {
627  Q_OBJECT
628  /// \cond INCLUDE_QPROPERTIES
629  Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot)
630  Q_PROPERTY(QString name READ name)
631  Q_PROPERTY(int index READ index)
632  Q_PROPERTY(QList<QCPLayerable*> children READ children)
633  Q_PROPERTY(bool visible READ visible WRITE setVisible)
634  Q_PROPERTY(LayerMode mode READ mode WRITE setMode)
635  /// \endcond
636 public:
637 
638  /*!
639  Defines the different rendering modes of a layer. Depending on the mode, certain layers can be
640  replotted individually, without the need to replot (possibly complex) layerables on other
641  layers.
642 
643  \see setMode
644  */
645  enum LayerMode { lmLogical ///< Layer is used only for rendering order, and shares paint buffer with all other adjacent logical layers.
646  ,lmBuffered ///< Layer has its own paint buffer and may be replotted individually (see \ref replot).
647  };
648  Q_ENUMS(LayerMode)
649 
650  QCPLayer(QCustomPlot* parentPlot, const QString &layerName);
651  virtual ~QCPLayer();
652 
653  // getters:
654  QCustomPlot *parentPlot() const { return mParentPlot; }
655  QString name() const { return mName; }
656  int index() const { return mIndex; }
657  QList<QCPLayerable*> children() const { return mChildren; }
658  bool visible() const { return mVisible; }
659  LayerMode mode() const { return mMode; }
660 
661  // setters:
662  void setVisible(bool visible);
663  void setMode(LayerMode mode);
664 
665  // non-virtual methods:
666  void replot();
667 
668 protected:
669  // property members:
670  QCustomPlot *mParentPlot;
671  QString mName;
672  int mIndex;
673  QList<QCPLayerable*> mChildren;
674  bool mVisible;
675  LayerMode mMode;
676 
677  // non-property members:
679 
680  // non-virtual methods:
681  void draw(QCPPainter *painter);
682  void drawToPaintBuffer();
683  void addChild(QCPLayerable *layerable, bool prepend);
684  void removeChild(QCPLayerable *layerable);
685 
686 private:
687  Q_DISABLE_COPY(QCPLayer)
688 
689  friend class QCustomPlot;
690  friend class QCPLayerable;
691 };
692 Q_DECLARE_METATYPE(QCPLayer::LayerMode)
693 
694 class QCP_LIB_DECL QCPLayerable : public QObject
695 {
696  Q_OBJECT
697  /// \cond INCLUDE_QPROPERTIES
698  Q_PROPERTY(bool visible READ visible WRITE setVisible)
699  Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot)
701  Q_PROPERTY(QCPLayer* layer READ layer WRITE setLayer NOTIFY layerChanged)
702  Q_PROPERTY(bool antialiased READ antialiased WRITE setAntialiased)
703  /// \endcond
704 public:
705  QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=nullptr);
706  virtual ~QCPLayerable();
707 
708  // getters:
709  bool visible() const { return mVisible; }
710  QCustomPlot *parentPlot() const { return mParentPlot; }
711  QCPLayerable *parentLayerable() const { return mParentLayerable.data(); }
712  QCPLayer *layer() const { return mLayer; }
713  bool antialiased() const { return mAntialiased; }
714 
715  // setters:
716  void setVisible(bool on);
717  Q_SLOT bool setLayer(QCPLayer *layer);
718  bool setLayer(const QString &layerName);
719  void setAntialiased(bool enabled);
720 
721  // introduced virtual methods:
722  virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const;
723 
724  // non-property methods:
725  bool realVisibility() const;
726 
727 signals:
728  void layerChanged(QCPLayer *newLayer);
729 
730 protected:
731  // property members:
732  bool mVisible;
733  QCustomPlot *mParentPlot;
734  QPointer<QCPLayerable> mParentLayerable;
735  QCPLayer *mLayer;
736  bool mAntialiased;
737 
738  // introduced virtual methods:
739  virtual void parentPlotInitialized(QCustomPlot *parentPlot);
740  virtual QCP::Interaction selectionCategory() const;
741  virtual QRect clipRect() const;
742  virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const = 0;
743  virtual void draw(QCPPainter *painter) = 0;
744  // selection events:
745  virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged);
746  virtual void deselectEvent(bool *selectionStateChanged);
747  // low-level mouse events:
748  virtual void mousePressEvent(QMouseEvent *event, const QVariant &details);
749  virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos);
750  virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos);
751  virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details);
752  virtual void wheelEvent(QWheelEvent *event);
753 
754  // non-property methods:
755  void initializeParentPlot(QCustomPlot *parentPlot);
757  bool moveToLayer(QCPLayer *layer, bool prepend);
758  void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const;
759 
760 private:
762 
763  friend class QCustomPlot;
764  friend class QCPLayer;
765  friend class QCPAxisRect;
766 };
767 
768 /* end of 'src/layer.h' */
769 
770 
771 /* including file 'src/axis/range.h' */
772 /* modified 2021-03-29T02:30:44, size 5280 */
773 
774 class QCP_LIB_DECL QCPRange
775 {
776 public:
777  double lower, upper;
778 
779  QCPRange();
780  QCPRange(double lower, double upper);
781 
782  bool operator==(const QCPRange& other) const { return lower == other.lower && upper == other.upper; }
783  bool operator!=(const QCPRange& other) const { return !(*this == other); }
784 
785  QCPRange &operator+=(const double& value) { lower+=value; upper+=value; return *this; }
786  QCPRange &operator-=(const double& value) { lower-=value; upper-=value; return *this; }
787  QCPRange &operator*=(const double& value) { lower*=value; upper*=value; return *this; }
788  QCPRange &operator/=(const double& value) { lower/=value; upper/=value; return *this; }
789  friend inline const QCPRange operator+(const QCPRange&, double);
790  friend inline const QCPRange operator+(double, const QCPRange&);
791  friend inline const QCPRange operator-(const QCPRange& range, double value);
792  friend inline const QCPRange operator*(const QCPRange& range, double value);
793  friend inline const QCPRange operator*(double value, const QCPRange& range);
794  friend inline const QCPRange operator/(const QCPRange& range, double value);
795 
796  double size() const { return upper-lower; }
797  double center() const { return (upper+lower)*0.5; }
798  void normalize() { if (lower > upper) qSwap(lower, upper); }
799  void expand(const QCPRange &otherRange);
800  void expand(double includeCoord);
801  QCPRange expanded(const QCPRange &otherRange) const;
802  QCPRange expanded(double includeCoord) const;
803  QCPRange bounded(double lowerBound, double upperBound) const;
804  QCPRange sanitizedForLogScale() const;
805  QCPRange sanitizedForLinScale() const;
806  bool contains(double value) const { return value >= lower && value <= upper; }
807 
808  static bool validRange(double lower, double upper);
809  static bool validRange(const QCPRange &range);
810  static const double minRange;
811  static const double maxRange;
812 
813 };
814 Q_DECLARE_TYPEINFO(QCPRange, Q_MOVABLE_TYPE);
815 
816 /*! \relates QCPRange
817 
818  Prints \a range in a human readable format to the qDebug output.
819 */
820 inline QDebug operator<< (QDebug d, const QCPRange &range)
821 {
822  d.nospace() << "QCPRange(" << range.lower << ", " << range.upper << ")";
823  return d.space();
824 }
825 
826 /*!
827  Adds \a value to both boundaries of the range.
828 */
829 inline const QCPRange operator+(const QCPRange& range, double value)
830 {
831  QCPRange result(range);
832  result += value;
833  return result;
834 }
835 
836 /*!
837  Adds \a value to both boundaries of the range.
838 */
839 inline const QCPRange operator+(double value, const QCPRange& range)
840 {
841  QCPRange result(range);
842  result += value;
843  return result;
844 }
845 
846 /*!
847  Subtracts \a value from both boundaries of the range.
848 */
849 inline const QCPRange operator-(const QCPRange& range, double value)
850 {
851  QCPRange result(range);
852  result -= value;
853  return result;
854 }
855 
856 /*!
857  Multiplies both boundaries of the range by \a value.
858 */
859 inline const QCPRange operator*(const QCPRange& range, double value)
860 {
861  QCPRange result(range);
862  result *= value;
863  return result;
864 }
865 
866 /*!
867  Multiplies both boundaries of the range by \a value.
868 */
869 inline const QCPRange operator*(double value, const QCPRange& range)
870 {
871  QCPRange result(range);
872  result *= value;
873  return result;
874 }
875 
876 /*!
877  Divides both boundaries of the range by \a value.
878 */
879 inline const QCPRange operator/(const QCPRange& range, double value)
880 {
881  QCPRange result(range);
882  result /= value;
883  return result;
884 }
885 
886 /* end of 'src/axis/range.h' */
887 
888 
889 /* including file 'src/selection.h' */
890 /* modified 2021-03-29T02:30:44, size 8569 */
891 
892 class QCP_LIB_DECL QCPDataRange
893 {
894 public:
895  QCPDataRange();
896  QCPDataRange(int begin, int end);
897 
898  bool operator==(const QCPDataRange& other) const { return mBegin == other.mBegin && mEnd == other.mEnd; }
899  bool operator!=(const QCPDataRange& other) const { return !(*this == other); }
900 
901  // getters:
902  int begin() const { return mBegin; }
903  int end() const { return mEnd; }
904  int size() const { return mEnd-mBegin; }
905  int length() const { return size(); }
906 
907  // setters:
908  void setBegin(int begin) { mBegin = begin; }
909  void setEnd(int end) { mEnd = end; }
910 
911  // non-property methods:
912  bool isValid() const { return (mEnd >= mBegin) && (mBegin >= 0); }
913  bool isEmpty() const { return length() == 0; }
914  QCPDataRange bounded(const QCPDataRange &other) const;
915  QCPDataRange expanded(const QCPDataRange &other) const;
916  QCPDataRange intersection(const QCPDataRange &other) const;
917  QCPDataRange adjusted(int changeBegin, int changeEnd) const { return QCPDataRange(mBegin+changeBegin, mEnd+changeEnd); }
918  bool intersects(const QCPDataRange &other) const;
919  bool contains(const QCPDataRange &other) const;
920 
921 private:
922  // property members:
923  int mBegin, mEnd;
924 
925 };
926 Q_DECLARE_TYPEINFO(QCPDataRange, Q_MOVABLE_TYPE);
927 
928 
929 class QCP_LIB_DECL QCPDataSelection
930 {
931 public:
932  explicit QCPDataSelection();
933  explicit QCPDataSelection(const QCPDataRange &range);
934 
935  bool operator==(const QCPDataSelection& other) const;
936  bool operator!=(const QCPDataSelection& other) const { return !(*this == other); }
937  QCPDataSelection &operator+=(const QCPDataSelection& other);
938  QCPDataSelection &operator+=(const QCPDataRange& other);
939  QCPDataSelection &operator-=(const QCPDataSelection& other);
940  QCPDataSelection &operator-=(const QCPDataRange& other);
941  friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b);
942  friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b);
943  friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataRange& b);
944  friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataRange& b);
945  friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b);
946  friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b);
947  friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b);
948  friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b);
949 
950  // getters:
951  int dataRangeCount() const { return mDataRanges.size(); }
952  int dataPointCount() const;
953  QCPDataRange dataRange(int index=0) const;
954  QList<QCPDataRange> dataRanges() const { return mDataRanges; }
955  QCPDataRange span() const;
956 
957  // non-property methods:
958  void addDataRange(const QCPDataRange &dataRange, bool simplify=true);
959  void clear();
960  bool isEmpty() const { return mDataRanges.isEmpty(); }
961  void simplify();
962  void enforceType(QCP::SelectionType type);
963  bool contains(const QCPDataSelection &other) const;
964  QCPDataSelection intersection(const QCPDataRange &other) const;
965  QCPDataSelection intersection(const QCPDataSelection &other) const;
966  QCPDataSelection inverse(const QCPDataRange &outerRange) const;
967 
968 private:
969  // property members:
970  QList<QCPDataRange> mDataRanges;
971 
972  inline static bool lessThanDataRangeBegin(const QCPDataRange &a, const QCPDataRange &b) { return a.begin() < b.begin(); }
973 };
974 Q_DECLARE_METATYPE(QCPDataSelection)
975 
976 
977 /*!
978  Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
979  The resulting data selection is already simplified (see \ref QCPDataSelection::simplify).
980 */
981 inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b)
982 {
983  QCPDataSelection result(a);
984  result += b;
985  return result;
986 }
987 
988 /*!
989  Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
990  The resulting data selection is already simplified (see \ref QCPDataSelection::simplify).
991 */
992 inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b)
993 {
994  QCPDataSelection result(a);
995  result += b;
996  return result;
997 }
998 
999 /*!
1000  Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
1001  The resulting data selection is already simplified (see \ref QCPDataSelection::simplify).
1002 */
1004 {
1005  QCPDataSelection result(a);
1006  result += b;
1007  return result;
1008 }
1009 
1010 /*!
1011  Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
1012  The resulting data selection is already simplified (see \ref QCPDataSelection::simplify).
1013 */
1014 inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataRange& b)
1015 {
1016  QCPDataSelection result(a);
1017  result += b;
1018  return result;
1019 }
1020 
1021 /*!
1022  Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b.
1023 */
1024 inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b)
1025 {
1026  QCPDataSelection result(a);
1027  result -= b;
1028  return result;
1029 }
1030 
1031 /*!
1032  Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b.
1033 */
1034 inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b)
1035 {
1036  QCPDataSelection result(a);
1037  result -= b;
1038  return result;
1039 }
1040 
1041 /*!
1042  Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b.
1043 */
1044 inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b)
1045 {
1046  QCPDataSelection result(a);
1047  result -= b;
1048  return result;
1049 }
1050 
1051 /*!
1052  Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b.
1053 */
1054 inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataRange& b)
1055 {
1056  QCPDataSelection result(a);
1057  result -= b;
1058  return result;
1059 }
1060 
1061 /*! \relates QCPDataRange
1062 
1063  Prints \a dataRange in a human readable format to the qDebug output.
1064 */
1065 inline QDebug operator<< (QDebug d, const QCPDataRange &dataRange)
1066 {
1067  d.nospace() << "QCPDataRange(" << dataRange.begin() << ", " << dataRange.end() << ")";
1068  return d;
1069 }
1070 
1071 /*! \relates QCPDataSelection
1072 
1073  Prints \a selection in a human readable format to the qDebug output.
1074 */
1075 inline QDebug operator<< (QDebug d, const QCPDataSelection &selection)
1076 {
1077  d.nospace() << "QCPDataSelection(";
1078  for (int i=0; i<selection.dataRangeCount(); ++i)
1079  {
1080  if (i != 0)
1081  d << ", ";
1082  d << selection.dataRange(i);
1083  }
1084  d << ")";
1085  return d;
1086 }
1087 
1088 
1089 
1090 /* end of 'src/selection.h' */
1091 
1092 
1093 /* including file 'src/selectionrect.h' */
1094 /* modified 2021-03-29T02:30:44, size 3354 */
1095 
1096 class QCP_LIB_DECL QCPSelectionRect : public QCPLayerable
1097 {
1098  Q_OBJECT
1099 public:
1100  explicit QCPSelectionRect(QCustomPlot *parentPlot);
1101  virtual ~QCPSelectionRect() Q_DECL_OVERRIDE;
1102 
1103  // getters:
1104  QRect rect() const { return mRect; }
1105  QCPRange range(const QCPAxis *axis) const;
1106  QPen pen() const { return mPen; }
1107  QBrush brush() const { return mBrush; }
1108  bool isActive() const { return mActive; }
1109 
1110  // setters:
1111  void setPen(const QPen &pen);
1112  void setBrush(const QBrush &brush);
1113 
1114  // non-property methods:
1115  Q_SLOT void cancel();
1116 
1117 signals:
1118  void started(QMouseEvent *event);
1119  void changed(const QRect &rect, QMouseEvent *event);
1120  void canceled(const QRect &rect, QInputEvent *event);
1121  void accepted(const QRect &rect, QMouseEvent *event);
1122 
1123 protected:
1124  // property members:
1125  QRect mRect;
1126  QPen mPen;
1127  QBrush mBrush;
1128  // non-property members:
1129  bool mActive;
1130 
1131  // introduced virtual methods:
1132  virtual void startSelection(QMouseEvent *event);
1133  virtual void moveSelection(QMouseEvent *event);
1134  virtual void endSelection(QMouseEvent *event);
1135  virtual void keyPressEvent(QKeyEvent *event);
1136 
1137  // reimplemented virtual methods
1138  virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
1139  virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
1140 
1141  friend class QCustomPlot;
1142 };
1143 
1144 /* end of 'src/selectionrect.h' */
1145 
1146 
1147 /* including file 'src/layout.h' */
1148 /* modified 2021-03-29T02:30:44, size 14279 */
1149 
1150 class QCP_LIB_DECL QCPMarginGroup : public QObject
1151 {
1152  Q_OBJECT
1153 public:
1154  explicit QCPMarginGroup(QCustomPlot *parentPlot);
1155  virtual ~QCPMarginGroup();
1156 
1157  // non-virtual methods:
1158  QList<QCPLayoutElement*> elements(QCP::MarginSide side) const { return mChildren.value(side); }
1159  bool isEmpty() const;
1160  void clear();
1161 
1162 protected:
1163  // non-property members:
1164  QCustomPlot *mParentPlot;
1166 
1167  // introduced virtual methods:
1168  virtual int commonMargin(QCP::MarginSide side) const;
1169 
1170  // non-virtual methods:
1171  void addChild(QCP::MarginSide side, QCPLayoutElement *element);
1172  void removeChild(QCP::MarginSide side, QCPLayoutElement *element);
1173 
1174 private:
1175  Q_DISABLE_COPY(QCPMarginGroup)
1176 
1177  friend class QCPLayoutElement;
1178 };
1179 
1180 
1181 class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable
1182 {
1183  Q_OBJECT
1184  /// \cond INCLUDE_QPROPERTIES
1185  Q_PROPERTY(QCPLayout* layout READ layout)
1186  Q_PROPERTY(QRect rect READ rect)
1187  Q_PROPERTY(QRect outerRect READ outerRect WRITE setOuterRect)
1188  Q_PROPERTY(QMargins margins READ margins WRITE setMargins)
1189  Q_PROPERTY(QMargins minimumMargins READ minimumMargins WRITE setMinimumMargins)
1190  Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize)
1191  Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize)
1192  Q_PROPERTY(SizeConstraintRect sizeConstraintRect READ sizeConstraintRect WRITE setSizeConstraintRect)
1193  /// \endcond
1194 public:
1195  /*!
1196  Defines the phases of the update process, that happens just before a replot. At each phase,
1197  \ref update is called with the according UpdatePhase value.
1198  */
1199  enum UpdatePhase { upPreparation ///< Phase used for any type of preparation that needs to be done before margin calculation and layout
1200  ,upMargins ///< Phase in which the margins are calculated and set
1201  ,upLayout ///< Final phase in which the layout system places the rects of the elements
1202  };
1203  Q_ENUMS(UpdatePhase)
1204 
1205  /*!
1206  Defines to which rect of a layout element the size constraints that can be set via \ref
1207  setMinimumSize and \ref setMaximumSize apply. The outer rect (\ref outerRect) includes the
1208  margins (e.g. in the case of a QCPAxisRect the axis labels), whereas the inner rect (\ref rect)
1209  does not.
1210 
1211  \see setSizeConstraintRect
1212  */
1213  enum SizeConstraintRect { scrInnerRect ///< Minimum/Maximum size constraints apply to inner rect
1214  , scrOuterRect ///< Minimum/Maximum size constraints apply to outer rect, thus include layout element margins
1215  };
1216  Q_ENUMS(SizeConstraintRect)
1217 
1218  explicit QCPLayoutElement(QCustomPlot *parentPlot=nullptr);
1219  virtual ~QCPLayoutElement() Q_DECL_OVERRIDE;
1220 
1221  // getters:
1222  QCPLayout *layout() const { return mParentLayout; }
1223  QRect rect() const { return mRect; }
1224  QRect outerRect() const { return mOuterRect; }
1225  QMargins margins() const { return mMargins; }
1226  QMargins minimumMargins() const { return mMinimumMargins; }
1227  QCP::MarginSides autoMargins() const { return mAutoMargins; }
1228  QSize minimumSize() const { return mMinimumSize; }
1229  QSize maximumSize() const { return mMaximumSize; }
1230  SizeConstraintRect sizeConstraintRect() const { return mSizeConstraintRect; }
1231  QCPMarginGroup *marginGroup(QCP::MarginSide side) const { return mMarginGroups.value(side, nullptr); }
1232  QHash<QCP::MarginSide, QCPMarginGroup*> marginGroups() const { return mMarginGroups; }
1233 
1234  // setters:
1235  void setOuterRect(const QRect &rect);
1236  void setMargins(const QMargins &margins);
1237  void setMinimumMargins(const QMargins &margins);
1238  void setAutoMargins(QCP::MarginSides sides);
1239  void setMinimumSize(const QSize &size);
1240  void setMinimumSize(int width, int height);
1241  void setMaximumSize(const QSize &size);
1242  void setMaximumSize(int width, int height);
1243  void setSizeConstraintRect(SizeConstraintRect constraintRect);
1244  void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group);
1245 
1246  // introduced virtual methods:
1247  virtual void update(UpdatePhase phase);
1248  virtual QSize minimumOuterSizeHint() const;
1249  virtual QSize maximumOuterSizeHint() const;
1250  virtual QList<QCPLayoutElement*> elements(bool recursive) const;
1251 
1252  // reimplemented virtual methods:
1253  virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
1254 
1255 protected:
1256  // property members:
1257  QCPLayout *mParentLayout;
1258  QSize mMinimumSize, mMaximumSize;
1259  SizeConstraintRect mSizeConstraintRect;
1260  QRect mRect, mOuterRect;
1261  QMargins mMargins, mMinimumMargins;
1262  QCP::MarginSides mAutoMargins;
1263  QHash<QCP::MarginSide, QCPMarginGroup*> mMarginGroups;
1264 
1265  // introduced virtual methods:
1266  virtual int calculateAutoMargin(QCP::MarginSide side);
1267  virtual void layoutChanged();
1268 
1269  // reimplemented virtual methods:
1270  virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE { Q_UNUSED(painter) }
1271  virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE { Q_UNUSED(painter) }
1272  virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE;
1273 
1274 private:
1275  Q_DISABLE_COPY(QCPLayoutElement)
1276 
1277  friend class QCustomPlot;
1278  friend class QCPLayout;
1279  friend class QCPMarginGroup;
1280 };
1281 Q_DECLARE_METATYPE(QCPLayoutElement::UpdatePhase)
1282 
1283 
1284 class QCP_LIB_DECL QCPLayout : public QCPLayoutElement
1285 {
1286  Q_OBJECT
1287 public:
1288  explicit QCPLayout();
1289 
1290  // reimplemented virtual methods:
1291  virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE;
1292  virtual QList<QCPLayoutElement*> elements(bool recursive) const Q_DECL_OVERRIDE;
1293 
1294  // introduced virtual methods:
1295  virtual int elementCount() const = 0;
1296  virtual QCPLayoutElement* elementAt(int index) const = 0;
1297  virtual QCPLayoutElement* takeAt(int index) = 0;
1298  virtual bool take(QCPLayoutElement* element) = 0;
1299  virtual void simplify();
1300 
1301  // non-virtual methods:
1302  bool removeAt(int index);
1303  bool remove(QCPLayoutElement* element);
1304  void clear();
1305 
1306 protected:
1307  // introduced virtual methods:
1308  virtual void updateLayout();
1309 
1310  // non-virtual methods:
1311  void sizeConstraintsChanged() const;
1312  void adoptElement(QCPLayoutElement *el);
1313  void releaseElement(QCPLayoutElement *el);
1314  QVector<int> getSectionSizes(QVector<int> maxSizes, QVector<int> minSizes, QVector<double> stretchFactors, int totalSize) const;
1315  static QSize getFinalMinimumOuterSize(const QCPLayoutElement *el);
1316  static QSize getFinalMaximumOuterSize(const QCPLayoutElement *el);
1317 
1318 private:
1320  friend class QCPLayoutElement;
1321 };
1322 
1323 
1324 class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout
1325 {
1326  Q_OBJECT
1327  /// \cond INCLUDE_QPROPERTIES
1328  Q_PROPERTY(int rowCount READ rowCount)
1329  Q_PROPERTY(int columnCount READ columnCount)
1330  Q_PROPERTY(QList<double> columnStretchFactors READ columnStretchFactors WRITE setColumnStretchFactors)
1331  Q_PROPERTY(QList<double> rowStretchFactors READ rowStretchFactors WRITE setRowStretchFactors)
1332  Q_PROPERTY(int columnSpacing READ columnSpacing WRITE setColumnSpacing)
1333  Q_PROPERTY(int rowSpacing READ rowSpacing WRITE setRowSpacing)
1334  Q_PROPERTY(FillOrder fillOrder READ fillOrder WRITE setFillOrder)
1335  Q_PROPERTY(int wrap READ wrap WRITE setWrap)
1336  /// \endcond
1337 public:
1338 
1339  /*!
1340  Defines in which direction the grid is filled when using \ref addElement(QCPLayoutElement*).
1341  The column/row at which wrapping into the next row/column occurs can be specified with \ref
1342  setWrap.
1343 
1344  \see setFillOrder
1345  */
1346  enum FillOrder { foRowsFirst ///< Rows are filled first, and a new element is wrapped to the next column if the row count would exceed \ref setWrap.
1347  ,foColumnsFirst ///< Columns are filled first, and a new element is wrapped to the next row if the column count would exceed \ref setWrap.
1348  };
1349  Q_ENUMS(FillOrder)
1350 
1351  explicit QCPLayoutGrid();
1352  virtual ~QCPLayoutGrid() Q_DECL_OVERRIDE;
1353 
1354  // getters:
1355  int rowCount() const { return mElements.size(); }
1356  int columnCount() const { return mElements.size() > 0 ? mElements.first().size() : 0; }
1357  QList<double> columnStretchFactors() const { return mColumnStretchFactors; }
1358  QList<double> rowStretchFactors() const { return mRowStretchFactors; }
1359  int columnSpacing() const { return mColumnSpacing; }
1360  int rowSpacing() const { return mRowSpacing; }
1361  int wrap() const { return mWrap; }
1362  FillOrder fillOrder() const { return mFillOrder; }
1363 
1364  // setters:
1365  void setColumnStretchFactor(int column, double factor);
1366  void setColumnStretchFactors(const QList<double> &factors);
1367  void setRowStretchFactor(int row, double factor);
1368  void setRowStretchFactors(const QList<double> &factors);
1369  void setColumnSpacing(int pixels);
1370  void setRowSpacing(int pixels);
1371  void setWrap(int count);
1372  void setFillOrder(FillOrder order, bool rearrange=true);
1373 
1374  // reimplemented virtual methods:
1375  virtual void updateLayout() Q_DECL_OVERRIDE;
1376  virtual int elementCount() const Q_DECL_OVERRIDE { return rowCount()*columnCount(); }
1377  virtual QCPLayoutElement* elementAt(int index) const Q_DECL_OVERRIDE;
1378  virtual QCPLayoutElement* takeAt(int index) Q_DECL_OVERRIDE;
1379  virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE;
1380  virtual QList<QCPLayoutElement*> elements(bool recursive) const Q_DECL_OVERRIDE;
1381  virtual void simplify() Q_DECL_OVERRIDE;
1382  virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE;
1383  virtual QSize maximumOuterSizeHint() const Q_DECL_OVERRIDE;
1384 
1385  // non-virtual methods:
1386  QCPLayoutElement *element(int row, int column) const;
1387  bool addElement(int row, int column, QCPLayoutElement *element);
1388  bool addElement(QCPLayoutElement *element);
1389  bool hasElement(int row, int column);
1390  void expandTo(int newRowCount, int newColumnCount);
1391  void insertRow(int newIndex);
1392  void insertColumn(int newIndex);
1393  int rowColToIndex(int row, int column) const;
1394  void indexToRowCol(int index, int &row, int &column) const;
1395 
1396 protected:
1397  // property members:
1398  QList<QList<QCPLayoutElement*> > mElements;
1399  QList<double> mColumnStretchFactors;
1400  QList<double> mRowStretchFactors;
1401  int mColumnSpacing, mRowSpacing;
1402  int mWrap;
1403  FillOrder mFillOrder;
1404 
1405  // non-virtual methods:
1406  void getMinimumRowColSizes(QVector<int> *minColWidths, QVector<int> *minRowHeights) const;
1407  void getMaximumRowColSizes(QVector<int> *maxColWidths, QVector<int> *maxRowHeights) const;
1408 
1409 private:
1410  Q_DISABLE_COPY(QCPLayoutGrid)
1411 };
1412 Q_DECLARE_METATYPE(QCPLayoutGrid::FillOrder)
1413 
1414 
1415 class QCP_LIB_DECL QCPLayoutInset : public QCPLayout
1416 {
1417  Q_OBJECT
1418 public:
1419  /*!
1420  Defines how the placement and sizing is handled for a certain element in a QCPLayoutInset.
1421  */
1422  enum InsetPlacement { ipFree ///< The element may be positioned/sized arbitrarily, see \ref setInsetRect
1423  ,ipBorderAligned ///< The element is aligned to one of the layout sides, see \ref setInsetAlignment
1424  };
1425  Q_ENUMS(InsetPlacement)
1426 
1427  explicit QCPLayoutInset();
1428  virtual ~QCPLayoutInset() Q_DECL_OVERRIDE;
1429 
1430  // getters:
1431  InsetPlacement insetPlacement(int index) const;
1432  Qt::Alignment insetAlignment(int index) const;
1433  QRectF insetRect(int index) const;
1434 
1435  // setters:
1436  void setInsetPlacement(int index, InsetPlacement placement);
1437  void setInsetAlignment(int index, Qt::Alignment alignment);
1438  void setInsetRect(int index, const QRectF &rect);
1439 
1440  // reimplemented virtual methods:
1441  virtual void updateLayout() Q_DECL_OVERRIDE;
1442  virtual int elementCount() const Q_DECL_OVERRIDE;
1443  virtual QCPLayoutElement* elementAt(int index) const Q_DECL_OVERRIDE;
1444  virtual QCPLayoutElement* takeAt(int index) Q_DECL_OVERRIDE;
1445  virtual bool take(QCPLayoutElement* element) Q_DECL_OVERRIDE;
1446  virtual void simplify() Q_DECL_OVERRIDE {}
1447  virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
1448 
1449  // non-virtual methods:
1450  void addElement(QCPLayoutElement *element, Qt::Alignment alignment);
1451  void addElement(QCPLayoutElement *element, const QRectF &rect);
1452 
1453 protected:
1454  // property members:
1455  QList<QCPLayoutElement*> mElements;
1456  QList<InsetPlacement> mInsetPlacement;
1457  QList<Qt::Alignment> mInsetAlignment;
1458  QList<QRectF> mInsetRect;
1459 
1460 private:
1461  Q_DISABLE_COPY(QCPLayoutInset)
1462 };
1463 Q_DECLARE_METATYPE(QCPLayoutInset::InsetPlacement)
1464 
1465 /* end of 'src/layout.h' */
1466 
1467 
1468 /* including file 'src/lineending.h' */
1469 /* modified 2021-03-29T02:30:44, size 4426 */
1470 
1471 class QCP_LIB_DECL QCPLineEnding
1472 {
1473  Q_GADGET
1474 public:
1475  /*!
1476  Defines the type of ending decoration for line-like items, e.g. an arrow.
1477 
1478  \image html QCPLineEnding.png
1479 
1480  The width and length of these decorations can be controlled with the functions \ref setWidth
1481  and \ref setLength. Some decorations like \ref esDisc, \ref esSquare, \ref esDiamond and \ref esBar only
1482  support a width, the length property is ignored.
1483 
1484  \see QCPItemLine::setHead, QCPItemLine::setTail, QCPItemCurve::setHead, QCPItemCurve::setTail, QCPAxis::setLowerEnding, QCPAxis::setUpperEnding
1485  */
1486  enum EndingStyle { esNone ///< No ending decoration
1487  ,esFlatArrow ///< A filled arrow head with a straight/flat back (a triangle)
1488  ,esSpikeArrow ///< A filled arrow head with an indented back
1489  ,esLineArrow ///< A non-filled arrow head with open back
1490  ,esDisc ///< A filled circle
1491  ,esSquare ///< A filled square
1492  ,esDiamond ///< A filled diamond (45 degrees rotated square)
1493  ,esBar ///< A bar perpendicular to the line
1494  ,esHalfBar ///< A bar perpendicular to the line, pointing out to only one side (to which side can be changed with \ref setInverted)
1495  ,esSkewedBar ///< A bar that is skewed (skew controllable via \ref setLength)
1496  };
1497  Q_ENUMS(EndingStyle)
1498 
1499  QCPLineEnding();
1500  QCPLineEnding(EndingStyle style, double width=8, double length=10, bool inverted=false);
1501 
1502  // getters:
1503  EndingStyle style() const { return mStyle; }
1504  double width() const { return mWidth; }
1505  double length() const { return mLength; }
1506  bool inverted() const { return mInverted; }
1507 
1508  // setters:
1509  void setStyle(EndingStyle style);
1510  void setWidth(double width);
1511  void setLength(double length);
1512  void setInverted(bool inverted);
1513 
1514  // non-property methods:
1515  double boundingDistance() const;
1516  double realLength() const;
1517  void draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const;
1518  void draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const;
1519 
1520 protected:
1521  // property members:
1522  EndingStyle mStyle;
1523  double mWidth, mLength;
1524  bool mInverted;
1525 };
1526 Q_DECLARE_TYPEINFO(QCPLineEnding, Q_MOVABLE_TYPE);
1527 Q_DECLARE_METATYPE(QCPLineEnding::EndingStyle)
1528 
1529 /* end of 'src/lineending.h' */
1530 
1531 
1532 /* including file 'src/axis/labelpainter.h' */
1533 /* modified 2021-03-29T02:30:44, size 7086 */
1534 
1536 {
1537  Q_GADGET
1538 public:
1539  /*!
1540  TODO
1541  */
1542  enum AnchorMode { amRectangular ///<
1543  ,amSkewedUpright ///<
1544  ,amSkewedRotated ///<
1545  };
1546  Q_ENUMS(AnchorMode)
1547 
1548  /*!
1549  TODO
1550  */
1551  enum AnchorReferenceType { artNormal ///<
1552  ,artTangent ///<
1553  };
1554  Q_ENUMS(AnchorReferenceType)
1555 
1556  /*!
1557  TODO
1558  */
1559  enum AnchorSide { asLeft ///<
1560  ,asRight ///<
1561  ,asTop ///<
1562  ,asBottom ///<
1563  ,asTopLeft
1564  ,asTopRight
1565  ,asBottomRight
1566  ,asBottomLeft
1567  };
1568  Q_ENUMS(AnchorSide)
1569 
1570  explicit QCPLabelPainterPrivate(QCustomPlot *parentPlot);
1571  virtual ~QCPLabelPainterPrivate();
1572 
1573  // setters:
1574  void setAnchorSide(AnchorSide side);
1575  void setAnchorMode(AnchorMode mode);
1576  void setAnchorReference(const QPointF &pixelPoint);
1577  void setAnchorReferenceType(AnchorReferenceType type);
1578  void setFont(const QFont &font);
1579  void setColor(const QColor &color);
1580  void setPadding(int padding);
1581  void setRotation(double rotation);
1582  void setSubstituteExponent(bool enabled);
1583  void setMultiplicationSymbol(QChar symbol);
1584  void setAbbreviateDecimalPowers(bool enabled);
1585  void setCacheSize(int labelCount);
1586 
1587  // getters:
1588  AnchorMode anchorMode() const { return mAnchorMode; }
1589  AnchorSide anchorSide() const { return mAnchorSide; }
1590  QPointF anchorReference() const { return mAnchorReference; }
1591  AnchorReferenceType anchorReferenceType() const { return mAnchorReferenceType; }
1592  QFont font() const { return mFont; }
1593  QColor color() const { return mColor; }
1594  int padding() const { return mPadding; }
1595  double rotation() const { return mRotation; }
1596  bool substituteExponent() const { return mSubstituteExponent; }
1597  QChar multiplicationSymbol() const { return mMultiplicationSymbol; }
1598  bool abbreviateDecimalPowers() const { return mAbbreviateDecimalPowers; }
1599  int cacheSize() const;
1600 
1601  //virtual int size() const;
1602 
1603  // non-property methods:
1604  void drawTickLabel(QCPPainter *painter, const QPointF &tickPos, const QString &text);
1605  void clearCache();
1606 
1607  // constants that may be used with setMultiplicationSymbol:
1608  static const QChar SymbolDot;
1609  static const QChar SymbolCross;
1610 
1611 protected:
1612  struct CachedLabel
1613  {
1614  QPoint offset;
1615  QPixmap pixmap;
1616  };
1617  struct LabelData
1618  {
1619  AnchorSide side;
1620  double rotation; // angle in degrees
1621  QTransform transform; // the transform about the label anchor which is at (0, 0). Does not contain final absolute x/y positioning on the plot/axis
1622  QString basePart, expPart, suffixPart;
1623  QRect baseBounds, expBounds, suffixBounds;
1624  QRect totalBounds; // is in a coordinate system where label top left is at (0, 0)
1625  QRect rotatedTotalBounds; // is in a coordinate system where the label anchor is at (0, 0)
1626  QFont baseFont, expFont;
1627  QColor color;
1628  };
1629 
1630  // property members:
1631  AnchorMode mAnchorMode;
1632  AnchorSide mAnchorSide;
1633  QPointF mAnchorReference;
1634  AnchorReferenceType mAnchorReferenceType;
1635  QFont mFont;
1636  QColor mColor;
1637  int mPadding;
1638  double mRotation; // this is the rotation applied uniformly to all labels, not the heterogeneous rotation in amCircularRotated mode
1639  bool mSubstituteExponent;
1640  QChar mMultiplicationSymbol;
1641  bool mAbbreviateDecimalPowers;
1642  // non-property members:
1643  QCustomPlot *mParentPlot;
1644  QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters
1645  QCache<QString, CachedLabel> mLabelCache;
1646  QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox;
1647  int mLetterCapHeight, mLetterDescent;
1648 
1649  // introduced virtual methods:
1650  virtual void drawLabelMaybeCached(QCPPainter *painter, const QFont &font, const QColor &color, const QPointF &pos, AnchorSide side, double rotation, const QString &text);
1651  virtual QByteArray generateLabelParameterHash() const; // TODO: get rid of this in favor of invalidation flag upon setters?
1652 
1653  // non-virtual methods:
1654  QPointF getAnchorPos(const QPointF &tickPos);
1655  void drawText(QCPPainter *painter, const QPointF &pos, const LabelData &labelData) const;
1656  LabelData getTickLabelData(const QFont &font, const QColor &color, double rotation, AnchorSide side, const QString &text) const;
1657  void applyAnchorTransform(LabelData &labelData) const;
1658  //void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const;
1659  CachedLabel *createCachedLabel(const LabelData &labelData) const;
1660  QByteArray cacheKey(const QString &text, const QColor &color, double rotation, AnchorSide side) const;
1661  AnchorSide skewedAnchorSide(const QPointF &tickPos, double sideExpandHorz, double sideExpandVert) const;
1662  AnchorSide rotationCorrectedSide(AnchorSide side, double rotation) const;
1663  void analyzeFontMetrics();
1664 };
1665 Q_DECLARE_METATYPE(QCPLabelPainterPrivate::AnchorMode)
1666 Q_DECLARE_METATYPE(QCPLabelPainterPrivate::AnchorSide)
1667 
1668 
1669 /* end of 'src/axis/labelpainter.h' */
1670 
1671 
1672 /* including file 'src/axis/axisticker.h' */
1673 /* modified 2021-03-29T02:30:44, size 4230 */
1674 
1675 class QCP_LIB_DECL QCPAxisTicker
1676 {
1677  Q_GADGET
1678 public:
1679  /*!
1680  Defines the strategies that the axis ticker may follow when choosing the size of the tick step.
1681 
1682  \see setTickStepStrategy
1683  */
1685  {
1686  tssReadability ///< A nicely readable tick step is prioritized over matching the requested number of ticks (see \ref setTickCount)
1687  ,tssMeetTickCount ///< Less readable tick steps are allowed which in turn facilitates getting closer to the requested tick count
1688  };
1689  Q_ENUMS(TickStepStrategy)
1690 
1691  QCPAxisTicker();
1692  virtual ~QCPAxisTicker();
1693 
1694  // getters:
1695  TickStepStrategy tickStepStrategy() const { return mTickStepStrategy; }
1696  int tickCount() const { return mTickCount; }
1697  double tickOrigin() const { return mTickOrigin; }
1698 
1699  // setters:
1700  void setTickStepStrategy(TickStepStrategy strategy);
1701  void setTickCount(int count);
1702  void setTickOrigin(double origin);
1703 
1704  // introduced virtual methods:
1705  virtual void generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector<double> &ticks, QVector<double> *subTicks, QVector<QString> *tickLabels);
1706 
1707 protected:
1708  // property members:
1709  TickStepStrategy mTickStepStrategy;
1710  int mTickCount;
1711  double mTickOrigin;
1712 
1713  // introduced virtual methods:
1714  virtual double getTickStep(const QCPRange &range);
1715  virtual int getSubTickCount(double tickStep);
1716  virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision);
1717  virtual QVector<double> createTickVector(double tickStep, const QCPRange &range);
1718  virtual QVector<double> createSubTickVector(int subTickCount, const QVector<double> &ticks);
1719  virtual QVector<QString> createLabelVector(const QVector<double> &ticks, const QLocale &locale, QChar formatChar, int precision);
1720 
1721  // non-virtual methods:
1722  void trimTicks(const QCPRange &range, QVector<double> &ticks, bool keepOneOutlier) const;
1723  double pickClosest(double target, const QVector<double> &candidates) const;
1724  double getMantissa(double input, double *magnitude=nullptr) const;
1725  double cleanMantissa(double input) const;
1726 
1727 private:
1728  Q_DISABLE_COPY(QCPAxisTicker)
1729 
1730 };
1731 Q_DECLARE_METATYPE(QCPAxisTicker::TickStepStrategy)
1732 Q_DECLARE_METATYPE(QSharedPointer<QCPAxisTicker>)
1733 
1734 /* end of 'src/axis/axisticker.h' */
1735 
1736 
1737 /* including file 'src/axis/axistickerdatetime.h' */
1738 /* modified 2021-03-29T02:30:44, size 3600 */
1739 
1740 class QCP_LIB_DECL QCPAxisTickerDateTime : public QCPAxisTicker
1741 {
1742 public:
1744 
1745  // getters:
1746  QString dateTimeFormat() const { return mDateTimeFormat; }
1747  Qt::TimeSpec dateTimeSpec() const { return mDateTimeSpec; }
1748 # if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
1749  QTimeZone timeZone() const { return mTimeZone; }
1750 #endif
1751 
1752  // setters:
1753  void setDateTimeFormat(const QString &format);
1754  void setDateTimeSpec(Qt::TimeSpec spec);
1755 # if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
1756  void setTimeZone(const QTimeZone &zone);
1757 # endif
1758  void setTickOrigin(double origin); // hides base class method but calls baseclass implementation ("using" throws off IDEs and doxygen)
1759  void setTickOrigin(const QDateTime &origin);
1760 
1761  // static methods:
1762  static QDateTime keyToDateTime(double key);
1763  static double dateTimeToKey(const QDateTime &dateTime);
1764  static double dateTimeToKey(const QDate &date, Qt::TimeSpec timeSpec=Qt::LocalTime);
1765 
1766 protected:
1767  // property members:
1768  QString mDateTimeFormat;
1769  Qt::TimeSpec mDateTimeSpec;
1770 # if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
1771  QTimeZone mTimeZone;
1772 # endif
1773  // non-property members:
1774  enum DateStrategy {dsNone, dsUniformTimeInDay, dsUniformDayInMonth} mDateStrategy;
1775 
1776  // reimplemented virtual methods:
1777  virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE;
1778  virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE;
1779  virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE;
1780  virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE;
1781 };
1782 
1783 /* end of 'src/axis/axistickerdatetime.h' */
1784 
1785 
1786 /* including file 'src/axis/axistickertime.h' */
1787 /* modified 2021-03-29T02:30:44, size 3542 */
1788 
1789 class QCP_LIB_DECL QCPAxisTickerTime : public QCPAxisTicker
1790 {
1791  Q_GADGET
1792 public:
1793  /*!
1794  Defines the logical units in which fractions of time spans can be expressed.
1795 
1796  \see setFieldWidth, setTimeFormat
1797  */
1798  enum TimeUnit { tuMilliseconds ///< Milliseconds, one thousandth of a second (%%z in \ref setTimeFormat)
1799  ,tuSeconds ///< Seconds (%%s in \ref setTimeFormat)
1800  ,tuMinutes ///< Minutes (%%m in \ref setTimeFormat)
1801  ,tuHours ///< Hours (%%h in \ref setTimeFormat)
1802  ,tuDays ///< Days (%%d in \ref setTimeFormat)
1803  };
1804  Q_ENUMS(TimeUnit)
1805 
1807 
1808  // getters:
1809  QString timeFormat() const { return mTimeFormat; }
1810  int fieldWidth(TimeUnit unit) const { return mFieldWidth.value(unit); }
1811 
1812  // setters:
1813  void setTimeFormat(const QString &format);
1814  void setFieldWidth(TimeUnit unit, int width);
1815 
1816 protected:
1817  // property members:
1818  QString mTimeFormat;
1819  QHash<TimeUnit, int> mFieldWidth;
1820 
1821  // non-property members:
1822  TimeUnit mSmallestUnit, mBiggestUnit;
1823  QHash<TimeUnit, QString> mFormatPattern;
1824 
1825  // reimplemented virtual methods:
1826  virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE;
1827  virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE;
1828  virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE;
1829 
1830  // non-virtual methods:
1831  void replaceUnit(QString &text, TimeUnit unit, int value) const;
1832 };
1833 Q_DECLARE_METATYPE(QCPAxisTickerTime::TimeUnit)
1834 
1835 /* end of 'src/axis/axistickertime.h' */
1836 
1837 
1838 /* including file 'src/axis/axistickerfixed.h' */
1839 /* modified 2021-03-29T02:30:44, size 3308 */
1840 
1841 class QCP_LIB_DECL QCPAxisTickerFixed : public QCPAxisTicker
1842 {
1843  Q_GADGET
1844 public:
1845  /*!
1846  Defines how the axis ticker may modify the specified tick step (\ref setTickStep) in order to
1847  control the number of ticks in the axis range.
1848 
1849  \see setScaleStrategy
1850  */
1851  enum ScaleStrategy { ssNone ///< Modifications are not allowed, the specified tick step is absolutely fixed. This might cause a high tick density and overlapping labels if the axis range is zoomed out.
1852  ,ssMultiples ///< An integer multiple of the specified tick step is allowed. The used factor follows the base class properties of \ref setTickStepStrategy and \ref setTickCount.
1853  ,ssPowers ///< An integer power of the specified tick step is allowed.
1854  };
1855  Q_ENUMS(ScaleStrategy)
1856 
1858 
1859  // getters:
1860  double tickStep() const { return mTickStep; }
1861  ScaleStrategy scaleStrategy() const { return mScaleStrategy; }
1862 
1863  // setters:
1864  void setTickStep(double step);
1865  void setScaleStrategy(ScaleStrategy strategy);
1866 
1867 protected:
1868  // property members:
1869  double mTickStep;
1870  ScaleStrategy mScaleStrategy;
1871 
1872  // reimplemented virtual methods:
1873  virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE;
1874 };
1875 Q_DECLARE_METATYPE(QCPAxisTickerFixed::ScaleStrategy)
1876 
1877 /* end of 'src/axis/axistickerfixed.h' */
1878 
1879 
1880 /* including file 'src/axis/axistickertext.h' */
1881 /* modified 2021-03-29T02:30:44, size 3090 */
1882 
1883 class QCP_LIB_DECL QCPAxisTickerText : public QCPAxisTicker
1884 {
1885 public:
1887 
1888  // getters:
1889  QMap<double, QString> &ticks() { return mTicks; }
1890  int subTickCount() const { return mSubTickCount; }
1891 
1892  // setters:
1893  void setTicks(const QMap<double, QString> &ticks);
1894  void setTicks(const QVector<double> &positions, const QVector<QString> &labels);
1895  void setSubTickCount(int subTicks);
1896 
1897  // non-virtual methods:
1898  void clear();
1899  void addTick(double position, const QString &label);
1900  void addTicks(const QMap<double, QString> &ticks);
1901  void addTicks(const QVector<double> &positions, const QVector<QString> &labels);
1902 
1903 protected:
1904  // property members:
1905  QMap<double, QString> mTicks;
1906  int mSubTickCount;
1907 
1908  // reimplemented virtual methods:
1909  virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE;
1910  virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE;
1911  virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE;
1912  virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE;
1913 };
1914 
1915 /* end of 'src/axis/axistickertext.h' */
1916 
1917 
1918 /* including file 'src/axis/axistickerpi.h' */
1919 /* modified 2021-03-29T02:30:44, size 3911 */
1920 
1921 class QCP_LIB_DECL QCPAxisTickerPi : public QCPAxisTicker
1922 {
1923  Q_GADGET
1924 public:
1925  /*!
1926  Defines how fractions should be displayed in tick labels.
1927 
1928  \see setFractionStyle
1929  */
1930  enum FractionStyle { fsFloatingPoint ///< Fractions are displayed as regular decimal floating point numbers, e.g. "0.25" or "0.125".
1931  ,fsAsciiFractions ///< Fractions are written as rationals using ASCII characters only, e.g. "1/4" or "1/8"
1932  ,fsUnicodeFractions ///< Fractions are written using sub- and superscript UTF-8 digits and the fraction symbol.
1933  };
1934  Q_ENUMS(FractionStyle)
1935 
1936  QCPAxisTickerPi();
1937 
1938  // getters:
1939  QString piSymbol() const { return mPiSymbol; }
1940  double piValue() const { return mPiValue; }
1941  bool periodicity() const { return mPeriodicity; }
1942  FractionStyle fractionStyle() const { return mFractionStyle; }
1943 
1944  // setters:
1945  void setPiSymbol(QString symbol);
1946  void setPiValue(double pi);
1947  void setPeriodicity(int multiplesOfPi);
1948  void setFractionStyle(FractionStyle style);
1949 
1950 protected:
1951  // property members:
1952  QString mPiSymbol;
1953  double mPiValue;
1954  int mPeriodicity;
1955  FractionStyle mFractionStyle;
1956 
1957  // non-property members:
1958  double mPiTickStep; // size of one tick step in units of mPiValue
1959 
1960  // reimplemented virtual methods:
1961  virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE;
1962  virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE;
1963  virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE;
1964 
1965  // non-virtual methods:
1966  void simplifyFraction(int &numerator, int &denominator) const;
1967  QString fractionToString(int numerator, int denominator) const;
1968  QString unicodeFraction(int numerator, int denominator) const;
1969  QString unicodeSuperscript(int number) const;
1970  QString unicodeSubscript(int number) const;
1971 };
1972 Q_DECLARE_METATYPE(QCPAxisTickerPi::FractionStyle)
1973 
1974 /* end of 'src/axis/axistickerpi.h' */
1975 
1976 
1977 /* including file 'src/axis/axistickerlog.h' */
1978 /* modified 2021-03-29T02:30:44, size 2594 */
1979 
1980 class QCP_LIB_DECL QCPAxisTickerLog : public QCPAxisTicker
1981 {
1982 public:
1983  QCPAxisTickerLog();
1984 
1985  // getters:
1986  double logBase() const { return mLogBase; }
1987  int subTickCount() const { return mSubTickCount; }
1988 
1989  // setters:
1990  void setLogBase(double base);
1991  void setSubTickCount(int subTicks);
1992 
1993 protected:
1994  // property members:
1995  double mLogBase;
1996  int mSubTickCount;
1997 
1998  // non-property members:
1999  double mLogBaseLnInv;
2000 
2001  // reimplemented virtual methods:
2002  virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE;
2003  virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE;
2004 };
2005 
2006 /* end of 'src/axis/axistickerlog.h' */
2007 
2008 
2009 /* including file 'src/axis/axis.h' */
2010 /* modified 2021-03-29T02:30:44, size 20913 */
2011 
2012 class QCP_LIB_DECL QCPGrid :public QCPLayerable
2013 {
2014  Q_OBJECT
2015  /// \cond INCLUDE_QPROPERTIES
2016  Q_PROPERTY(bool subGridVisible READ subGridVisible WRITE setSubGridVisible)
2017  Q_PROPERTY(bool antialiasedSubGrid READ antialiasedSubGrid WRITE setAntialiasedSubGrid)
2018  Q_PROPERTY(bool antialiasedZeroLine READ antialiasedZeroLine WRITE setAntialiasedZeroLine)
2019  Q_PROPERTY(QPen pen READ pen WRITE setPen)
2020  Q_PROPERTY(QPen subGridPen READ subGridPen WRITE setSubGridPen)
2021  Q_PROPERTY(QPen zeroLinePen READ zeroLinePen WRITE setZeroLinePen)
2022  /// \endcond
2023 public:
2024  explicit QCPGrid(QCPAxis *parentAxis);
2025 
2026  // getters:
2027  bool subGridVisible() const { return mSubGridVisible; }
2028  bool antialiasedSubGrid() const { return mAntialiasedSubGrid; }
2029  bool antialiasedZeroLine() const { return mAntialiasedZeroLine; }
2030  QPen pen() const { return mPen; }
2031  QPen subGridPen() const { return mSubGridPen; }
2032  QPen zeroLinePen() const { return mZeroLinePen; }
2033 
2034  // setters:
2035  void setSubGridVisible(bool visible);
2036  void setAntialiasedSubGrid(bool enabled);
2037  void setAntialiasedZeroLine(bool enabled);
2038  void setPen(const QPen &pen);
2039  void setSubGridPen(const QPen &pen);
2040  void setZeroLinePen(const QPen &pen);
2041 
2042 protected:
2043  // property members:
2044  bool mSubGridVisible;
2045  bool mAntialiasedSubGrid, mAntialiasedZeroLine;
2046  QPen mPen, mSubGridPen, mZeroLinePen;
2047 
2048  // non-property members:
2049  QCPAxis *mParentAxis;
2050 
2051  // reimplemented virtual methods:
2052  virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
2053  virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
2054 
2055  // non-virtual methods:
2056  void drawGridLines(QCPPainter *painter) const;
2057  void drawSubGridLines(QCPPainter *painter) const;
2058 
2059  friend class QCPAxis;
2060 };
2061 
2062 
2063 class QCP_LIB_DECL QCPAxis : public QCPLayerable
2064 {
2065  Q_OBJECT
2066  /// \cond INCLUDE_QPROPERTIES
2067  Q_PROPERTY(AxisType axisType READ axisType)
2068  Q_PROPERTY(QCPAxisRect* axisRect READ axisRect)
2069  Q_PROPERTY(ScaleType scaleType READ scaleType WRITE setScaleType NOTIFY scaleTypeChanged)
2070  Q_PROPERTY(QCPRange range READ range WRITE setRange NOTIFY rangeChanged)
2071  Q_PROPERTY(bool rangeReversed READ rangeReversed WRITE setRangeReversed)
2072  Q_PROPERTY(QSharedPointer<QCPAxisTicker> ticker READ ticker WRITE setTicker)
2073  Q_PROPERTY(bool ticks READ ticks WRITE setTicks)
2074  Q_PROPERTY(bool tickLabels READ tickLabels WRITE setTickLabels)
2075  Q_PROPERTY(int tickLabelPadding READ tickLabelPadding WRITE setTickLabelPadding)
2076  Q_PROPERTY(QFont tickLabelFont READ tickLabelFont WRITE setTickLabelFont)
2077  Q_PROPERTY(QColor tickLabelColor READ tickLabelColor WRITE setTickLabelColor)
2078  Q_PROPERTY(double tickLabelRotation READ tickLabelRotation WRITE setTickLabelRotation)
2079  Q_PROPERTY(LabelSide tickLabelSide READ tickLabelSide WRITE setTickLabelSide)
2080  Q_PROPERTY(QString numberFormat READ numberFormat WRITE setNumberFormat)
2081  Q_PROPERTY(int numberPrecision READ numberPrecision WRITE setNumberPrecision)
2082  Q_PROPERTY(QVector<double> tickVector READ tickVector)
2083  Q_PROPERTY(QVector<QString> tickVectorLabels READ tickVectorLabels)
2084  Q_PROPERTY(int tickLengthIn READ tickLengthIn WRITE setTickLengthIn)
2085  Q_PROPERTY(int tickLengthOut READ tickLengthOut WRITE setTickLengthOut)
2086  Q_PROPERTY(bool subTicks READ subTicks WRITE setSubTicks)
2087  Q_PROPERTY(int subTickLengthIn READ subTickLengthIn WRITE setSubTickLengthIn)
2088  Q_PROPERTY(int subTickLengthOut READ subTickLengthOut WRITE setSubTickLengthOut)
2089  Q_PROPERTY(QPen basePen READ basePen WRITE setBasePen)
2090  Q_PROPERTY(QPen tickPen READ tickPen WRITE setTickPen)
2091  Q_PROPERTY(QPen subTickPen READ subTickPen WRITE setSubTickPen)
2092  Q_PROPERTY(QFont labelFont READ labelFont WRITE setLabelFont)
2093  Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor)
2094  Q_PROPERTY(QString label READ label WRITE setLabel)
2095  Q_PROPERTY(int labelPadding READ labelPadding WRITE setLabelPadding)
2096  Q_PROPERTY(int padding READ padding WRITE setPadding)
2097  Q_PROPERTY(int offset READ offset WRITE setOffset)
2098  Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectionChanged)
2099  Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectableChanged)
2100  Q_PROPERTY(QFont selectedTickLabelFont READ selectedTickLabelFont WRITE setSelectedTickLabelFont)
2101  Q_PROPERTY(QFont selectedLabelFont READ selectedLabelFont WRITE setSelectedLabelFont)
2102  Q_PROPERTY(QColor selectedTickLabelColor READ selectedTickLabelColor WRITE setSelectedTickLabelColor)
2103  Q_PROPERTY(QColor selectedLabelColor READ selectedLabelColor WRITE setSelectedLabelColor)
2104  Q_PROPERTY(QPen selectedBasePen READ selectedBasePen WRITE setSelectedBasePen)
2105  Q_PROPERTY(QPen selectedTickPen READ selectedTickPen WRITE setSelectedTickPen)
2106  Q_PROPERTY(QPen selectedSubTickPen READ selectedSubTickPen WRITE setSelectedSubTickPen)
2107  Q_PROPERTY(QCPLineEnding lowerEnding READ lowerEnding WRITE setLowerEnding)
2108  Q_PROPERTY(QCPLineEnding upperEnding READ upperEnding WRITE setUpperEnding)
2109  Q_PROPERTY(QCPGrid* grid READ grid)
2110  /// \endcond
2111 public:
2112  /*!
2113  Defines at which side of the axis rect the axis will appear. This also affects how the tick
2114  marks are drawn, on which side the labels are placed etc.
2115  */
2116  enum AxisType { atLeft = 0x01 ///< <tt>0x01</tt> Axis is vertical and on the left side of the axis rect
2117  ,atRight = 0x02 ///< <tt>0x02</tt> Axis is vertical and on the right side of the axis rect
2118  ,atTop = 0x04 ///< <tt>0x04</tt> Axis is horizontal and on the top side of the axis rect
2119  ,atBottom = 0x08 ///< <tt>0x08</tt> Axis is horizontal and on the bottom side of the axis rect
2120  };
2121  Q_ENUMS(AxisType)
2122  Q_FLAGS(AxisTypes)
2123  Q_DECLARE_FLAGS(AxisTypes, AxisType)
2124  /*!
2125  Defines on which side of the axis the tick labels (numbers) shall appear.
2126 
2127  \see setTickLabelSide
2128  */
2129  enum LabelSide { lsInside ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect
2130  ,lsOutside ///< Tick labels will be displayed outside the axis rect
2131  };
2132  Q_ENUMS(LabelSide)
2133  /*!
2134  Defines the scale of an axis.
2135  \see setScaleType
2136  */
2137  enum ScaleType { stLinear ///< Linear scaling
2138  ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed axis coordinates (possibly also \ref setTicker to a \ref QCPAxisTickerLog instance).
2139  };
2140  Q_ENUMS(ScaleType)
2141  /*!
2142  Defines the selectable parts of an axis.
2143  \see setSelectableParts, setSelectedParts
2144  */
2145  enum SelectablePart { spNone = 0 ///< None of the selectable parts
2146  ,spAxis = 0x001 ///< The axis backbone and tick marks
2147  ,spTickLabels = 0x002 ///< Tick labels (numbers) of this axis (as a whole, not individually)
2148  ,spAxisLabel = 0x004 ///< The axis label
2149  };
2150  Q_ENUMS(SelectablePart)
2151  Q_FLAGS(SelectableParts)
2152  Q_DECLARE_FLAGS(SelectableParts, SelectablePart)
2153 
2154  explicit QCPAxis(QCPAxisRect *parent, AxisType type);
2155  virtual ~QCPAxis() Q_DECL_OVERRIDE;
2156 
2157  // getters:
2158  AxisType axisType() const { return mAxisType; }
2159  QCPAxisRect *axisRect() const { return mAxisRect; }
2160  ScaleType scaleType() const { return mScaleType; }
2161  const QCPRange range() const { return mRange; }
2162  bool rangeReversed() const { return mRangeReversed; }
2163  QSharedPointer<QCPAxisTicker> ticker() const { return mTicker; }
2164  bool ticks() const { return mTicks; }
2165  bool tickLabels() const { return mTickLabels; }
2166  int tickLabelPadding() const;
2167  QFont tickLabelFont() const { return mTickLabelFont; }
2168  QColor tickLabelColor() const { return mTickLabelColor; }
2169  double tickLabelRotation() const;
2170  LabelSide tickLabelSide() const;
2171  QString numberFormat() const;
2172  int numberPrecision() const { return mNumberPrecision; }
2173  QVector<double> tickVector() const { return mTickVector; }
2174  QVector<QString> tickVectorLabels() const { return mTickVectorLabels; }
2175  int tickLengthIn() const;
2176  int tickLengthOut() const;
2177  bool subTicks() const { return mSubTicks; }
2178  int subTickLengthIn() const;
2179  int subTickLengthOut() const;
2180  QPen basePen() const { return mBasePen; }
2181  QPen tickPen() const { return mTickPen; }
2182  QPen subTickPen() const { return mSubTickPen; }
2183  QFont labelFont() const { return mLabelFont; }
2184  QColor labelColor() const { return mLabelColor; }
2185  QString label() const { return mLabel; }
2186  int labelPadding() const;
2187  int padding() const { return mPadding; }
2188  int offset() const;
2189  SelectableParts selectedParts() const { return mSelectedParts; }
2190  SelectableParts selectableParts() const { return mSelectableParts; }
2191  QFont selectedTickLabelFont() const { return mSelectedTickLabelFont; }
2192  QFont selectedLabelFont() const { return mSelectedLabelFont; }
2193  QColor selectedTickLabelColor() const { return mSelectedTickLabelColor; }
2194  QColor selectedLabelColor() const { return mSelectedLabelColor; }
2195  QPen selectedBasePen() const { return mSelectedBasePen; }
2196  QPen selectedTickPen() const { return mSelectedTickPen; }
2197  QPen selectedSubTickPen() const { return mSelectedSubTickPen; }
2198  QCPLineEnding lowerEnding() const;
2199  QCPLineEnding upperEnding() const;
2200  QCPGrid *grid() const { return mGrid; }
2201 
2202  // setters:
2203  Q_SLOT void setScaleType(QCPAxis::ScaleType type);
2204  Q_SLOT void setRange(const QCPRange &range);
2205  void setRange(double lower, double upper);
2206  void setRange(double position, double size, Qt::AlignmentFlag alignment);
2207  void setRangeLower(double lower);
2208  void setRangeUpper(double upper);
2209  void setRangeReversed(bool reversed);
2210  void setTicker(QSharedPointer<QCPAxisTicker> ticker);
2211  void setTicks(bool show);
2212  void setTickLabels(bool show);
2213  void setTickLabelPadding(int padding);
2214  void setTickLabelFont(const QFont &font);
2215  void setTickLabelColor(const QColor &color);
2216  void setTickLabelRotation(double degrees);
2217  void setTickLabelSide(LabelSide side);
2218  void setNumberFormat(const QString &formatCode);
2219  void setNumberPrecision(int precision);
2220  void setTickLength(int inside, int outside=0);
2221  void setTickLengthIn(int inside);
2222  void setTickLengthOut(int outside);
2223  void setSubTicks(bool show);
2224  void setSubTickLength(int inside, int outside=0);
2225  void setSubTickLengthIn(int inside);
2226  void setSubTickLengthOut(int outside);
2227  void setBasePen(const QPen &pen);
2228  void setTickPen(const QPen &pen);
2229  void setSubTickPen(const QPen &pen);
2230  void setLabelFont(const QFont &font);
2231  void setLabelColor(const QColor &color);
2232  void setLabel(const QString &str);
2233  void setLabelPadding(int padding);
2234  void setPadding(int padding);
2235  void setOffset(int offset);
2236  void setSelectedTickLabelFont(const QFont &font);
2237  void setSelectedLabelFont(const QFont &font);
2238  void setSelectedTickLabelColor(const QColor &color);
2239  void setSelectedLabelColor(const QColor &color);
2240  void setSelectedBasePen(const QPen &pen);
2241  void setSelectedTickPen(const QPen &pen);
2242  void setSelectedSubTickPen(const QPen &pen);
2243  Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts);
2244  Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts);
2245  void setLowerEnding(const QCPLineEnding &ending);
2246  void setUpperEnding(const QCPLineEnding &ending);
2247 
2248  // reimplemented virtual methods:
2249  virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
2250 
2251  // non-property methods:
2252  Qt::Orientation orientation() const { return mOrientation; }
2253  int pixelOrientation() const { return rangeReversed() != (orientation()==Qt::Vertical) ? -1 : 1; }
2254  void moveRange(double diff);
2255  void scaleRange(double factor);
2256  void scaleRange(double factor, double center);
2257  void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0);
2258  void rescale(bool onlyVisiblePlottables=false);
2259  double pixelToCoord(double value) const;
2260  double coordToPixel(double value) const;
2261  SelectablePart getPartAt(const QPointF &pos) const;
2262  QList<QCPAbstractPlottable*> plottables() const;
2263  QList<QCPGraph*> graphs() const;
2264  QList<QCPAbstractItem*> items() const;
2265 
2266  static AxisType marginSideToAxisType(QCP::MarginSide side);
2267  static Qt::Orientation orientation(AxisType type) { return type==atBottom || type==atTop ? Qt::Horizontal : Qt::Vertical; }
2268  static AxisType opposite(AxisType type);
2269 
2270 signals:
2271  void rangeChanged(const QCPRange &newRange);
2272  void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange);
2273  void scaleTypeChanged(QCPAxis::ScaleType scaleType);
2274  void selectionChanged(const QCPAxis::SelectableParts &parts);
2275  void selectableChanged(const QCPAxis::SelectableParts &parts);
2276 
2277 protected:
2278  // property members:
2279  // axis base:
2280  AxisType mAxisType;
2281  QCPAxisRect *mAxisRect;
2282  //int mOffset; // in QCPAxisPainter
2283  int mPadding;
2284  Qt::Orientation mOrientation;
2285  SelectableParts mSelectableParts, mSelectedParts;
2286  QPen mBasePen, mSelectedBasePen;
2287  //QCPLineEnding mLowerEnding, mUpperEnding; // in QCPAxisPainter
2288  // axis label:
2289  //int mLabelPadding; // in QCPAxisPainter
2290  QString mLabel;
2291  QFont mLabelFont, mSelectedLabelFont;
2292  QColor mLabelColor, mSelectedLabelColor;
2293  // tick labels:
2294  //int mTickLabelPadding; // in QCPAxisPainter
2295  bool mTickLabels;
2296  //double mTickLabelRotation; // in QCPAxisPainter
2297  QFont mTickLabelFont, mSelectedTickLabelFont;
2298  QColor mTickLabelColor, mSelectedTickLabelColor;
2299  int mNumberPrecision;
2300  QLatin1Char mNumberFormatChar;
2301  bool mNumberBeautifulPowers;
2302  //bool mNumberMultiplyCross; // QCPAxisPainter
2303  // ticks and subticks:
2304  bool mTicks;
2305  bool mSubTicks;
2306  //int mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut; // QCPAxisPainter
2307  QPen mTickPen, mSelectedTickPen;
2308  QPen mSubTickPen, mSelectedSubTickPen;
2309  // scale and range:
2310  QCPRange mRange;
2311  bool mRangeReversed;
2312  ScaleType mScaleType;
2313 
2314  // non-property members:
2315  QCPGrid *mGrid;
2316  QCPAxisPainterPrivate *mAxisPainter;
2318  QVector<double> mTickVector;
2319  QVector<QString> mTickVectorLabels;
2320  QVector<double> mSubTickVector;
2321  bool mCachedMarginValid;
2322  int mCachedMargin;
2323  bool mDragging;
2324  QCPRange mDragStartRange;
2325  QCP::AntialiasedElements mAADragBackup, mNotAADragBackup;
2326 
2327  // introduced virtual methods:
2328  virtual int calculateMargin();
2329 
2330  // reimplemented virtual methods:
2331  virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
2332  virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
2333  virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE;
2334  // events:
2335  virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
2336  virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE;
2337  // mouse events:
2338  virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE;
2339  virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE;
2340  virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE;
2341  virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
2342 
2343  // non-virtual methods:
2344  void setupTickVectors();
2345  QPen getBasePen() const;
2346  QPen getTickPen() const;
2347  QPen getSubTickPen() const;
2348  QFont getTickLabelFont() const;
2349  QFont getLabelFont() const;
2350  QColor getTickLabelColor() const;
2351  QColor getLabelColor() const;
2352 
2353 private:
2354  Q_DISABLE_COPY(QCPAxis)
2355 
2356  friend class QCustomPlot;
2357  friend class QCPGrid;
2358  friend class QCPAxisRect;
2359 };
2360 Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::SelectableParts)
2361 Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::AxisTypes)
2362 Q_DECLARE_METATYPE(QCPAxis::AxisType)
2363 Q_DECLARE_METATYPE(QCPAxis::LabelSide)
2364 Q_DECLARE_METATYPE(QCPAxis::ScaleType)
2365 Q_DECLARE_METATYPE(QCPAxis::SelectablePart)
2366 
2367 
2369 {
2370 public:
2371  explicit QCPAxisPainterPrivate(QCustomPlot *parentPlot);
2372  virtual ~QCPAxisPainterPrivate();
2373 
2374  virtual void draw(QCPPainter *painter);
2375  virtual int size();
2376  void clearCache();
2377 
2378  QRect axisSelectionBox() const { return mAxisSelectionBox; }
2379  QRect tickLabelsSelectionBox() const { return mTickLabelsSelectionBox; }
2380  QRect labelSelectionBox() const { return mLabelSelectionBox; }
2381 
2382  // public property members:
2383  QCPAxis::AxisType type;
2384  QPen basePen;
2385  QCPLineEnding lowerEnding, upperEnding; // directly accessed by QCPAxis setters/getters
2386  int labelPadding; // directly accessed by QCPAxis setters/getters
2387  QFont labelFont;
2388  QColor labelColor;
2389  QString label;
2390  int tickLabelPadding; // directly accessed by QCPAxis setters/getters
2391  double tickLabelRotation; // directly accessed by QCPAxis setters/getters
2392  QCPAxis::LabelSide tickLabelSide; // directly accessed by QCPAxis setters/getters
2393  bool substituteExponent;
2394  bool numberMultiplyCross; // directly accessed by QCPAxis setters/getters
2395  int tickLengthIn, tickLengthOut, subTickLengthIn, subTickLengthOut; // directly accessed by QCPAxis setters/getters
2396  QPen tickPen, subTickPen;
2397  QFont tickLabelFont;
2398  QColor tickLabelColor;
2399  QRect axisRect, viewportRect;
2400  int offset; // directly accessed by QCPAxis setters/getters
2401  bool abbreviateDecimalPowers;
2402  bool reversedEndings;
2403 
2404  QVector<double> subTickPositions;
2405  QVector<double> tickPositions;
2406  QVector<QString> tickLabels;
2407 
2408 protected:
2409  struct CachedLabel
2410  {
2411  QPointF offset;
2412  QPixmap pixmap;
2413  };
2414  struct TickLabelData
2415  {
2416  QString basePart, expPart, suffixPart;
2417  QRect baseBounds, expBounds, suffixBounds, totalBounds, rotatedTotalBounds;
2418  QFont baseFont, expFont;
2419  };
2420  QCustomPlot *mParentPlot;
2421  QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters
2422  QCache<QString, CachedLabel> mLabelCache;
2423  QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox;
2424 
2425  virtual QByteArray generateLabelParameterHash() const;
2426 
2427  virtual void placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize);
2428  virtual void drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const;
2429  virtual TickLabelData getTickLabelData(const QFont &font, const QString &text) const;
2430  virtual QPointF getTickLabelDrawOffset(const TickLabelData &labelData) const;
2431  virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const;
2432 };
2433 
2434 /* end of 'src/axis/axis.h' */
2435 
2436 
2437 /* including file 'src/scatterstyle.h' */
2438 /* modified 2021-03-29T02:30:44, size 7275 */
2439 
2440 class QCP_LIB_DECL QCPScatterStyle
2441 {
2442  Q_GADGET
2443 public:
2444  /*!
2445  Represents the various properties of a scatter style instance. For example, this enum is used
2446  to specify which properties of \ref QCPSelectionDecorator::setScatterStyle will be used when
2447  highlighting selected data points.
2448 
2449  Specific scatter properties can be transferred between \ref QCPScatterStyle instances via \ref
2450  setFromOther.
2451  */
2452  enum ScatterProperty { spNone = 0x00 ///< <tt>0x00</tt> None
2453  ,spPen = 0x01 ///< <tt>0x01</tt> The pen property, see \ref setPen
2454  ,spBrush = 0x02 ///< <tt>0x02</tt> The brush property, see \ref setBrush
2455  ,spSize = 0x04 ///< <tt>0x04</tt> The size property, see \ref setSize
2456  ,spShape = 0x08 ///< <tt>0x08</tt> The shape property, see \ref setShape
2457  ,spAll = 0xFF ///< <tt>0xFF</tt> All properties
2458  };
2459  Q_ENUMS(ScatterProperty)
2460  Q_FLAGS(ScatterProperties)
2461  Q_DECLARE_FLAGS(ScatterProperties, ScatterProperty)
2462 
2463  /*!
2464  Defines the shape used for scatter points.
2465 
2466  On plottables/items that draw scatters, the sizes of these visualizations (with exception of
2467  \ref ssDot and \ref ssPixmap) can be controlled with the \ref setSize function. Scatters are
2468  drawn with the pen and brush specified with \ref setPen and \ref setBrush.
2469  */
2470  enum ScatterShape { ssNone ///< no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines)
2471  ,ssDot ///< \enumimage{ssDot.png} a single pixel (use \ref ssDisc or \ref ssCircle if you want a round shape with a certain radius)
2472  ,ssCross ///< \enumimage{ssCross.png} a cross
2473  ,ssPlus ///< \enumimage{ssPlus.png} a plus
2474  ,ssCircle ///< \enumimage{ssCircle.png} a circle
2475  ,ssDisc ///< \enumimage{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle)
2476  ,ssSquare ///< \enumimage{ssSquare.png} a square
2477  ,ssDiamond ///< \enumimage{ssDiamond.png} a diamond
2478  ,ssStar ///< \enumimage{ssStar.png} a star with eight arms, i.e. a combination of cross and plus
2479  ,ssTriangle ///< \enumimage{ssTriangle.png} an equilateral triangle, standing on baseline
2480  ,ssTriangleInverted ///< \enumimage{ssTriangleInverted.png} an equilateral triangle, standing on corner
2481  ,ssCrossSquare ///< \enumimage{ssCrossSquare.png} a square with a cross inside
2482  ,ssPlusSquare ///< \enumimage{ssPlusSquare.png} a square with a plus inside
2483  ,ssCrossCircle ///< \enumimage{ssCrossCircle.png} a circle with a cross inside
2484  ,ssPlusCircle ///< \enumimage{ssPlusCircle.png} a circle with a plus inside
2485  ,ssPeace ///< \enumimage{ssPeace.png} a circle, with one vertical and two downward diagonal lines
2486  ,ssPixmap ///< a custom pixmap specified by \ref setPixmap, centered on the data point coordinates
2487  ,ssCustom ///< custom painter operations are performed per scatter (As QPainterPath, see \ref setCustomPath)
2488  };
2489  Q_ENUMS(ScatterShape)
2490 
2491  QCPScatterStyle();
2492  QCPScatterStyle(ScatterShape shape, double size=6);
2493  QCPScatterStyle(ScatterShape shape, const QColor &color, double size);
2494  QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size);
2495  QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size);
2496  QCPScatterStyle(const QPixmap &pixmap);
2497  QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush=Qt::NoBrush, double size=6);
2498 
2499  // getters:
2500  double size() const { return mSize; }
2501  ScatterShape shape() const { return mShape; }
2502  QPen pen() const { return mPen; }
2503  QBrush brush() const { return mBrush; }
2504  QPixmap pixmap() const { return mPixmap; }
2505  QPainterPath customPath() const { return mCustomPath; }
2506 
2507  // setters:
2508  void setFromOther(const QCPScatterStyle &other, ScatterProperties properties);
2509  void setSize(double size);
2510  void setShape(ScatterShape shape);
2511  void setPen(const QPen &pen);
2512  void setBrush(const QBrush &brush);
2513  void setPixmap(const QPixmap &pixmap);
2514  void setCustomPath(const QPainterPath &customPath);
2515 
2516  // non-property methods:
2517  bool isNone() const { return mShape == ssNone; }
2518  bool isPenDefined() const { return mPenDefined; }
2519  void undefinePen();
2520  void applyTo(QCPPainter *painter, const QPen &defaultPen) const;
2521  void drawShape(QCPPainter *painter, const QPointF &pos) const;
2522  void drawShape(QCPPainter *painter, double x, double y) const;
2523 
2524 protected:
2525  // property members:
2526  double mSize;
2527  ScatterShape mShape;
2528  QPen mPen;
2529  QBrush mBrush;
2530  QPixmap mPixmap;
2531  QPainterPath mCustomPath;
2532 
2533  // non-property members:
2534  bool mPenDefined;
2535 };
2536 Q_DECLARE_TYPEINFO(QCPScatterStyle, Q_MOVABLE_TYPE);
2537 Q_DECLARE_OPERATORS_FOR_FLAGS(QCPScatterStyle::ScatterProperties)
2538 Q_DECLARE_METATYPE(QCPScatterStyle::ScatterProperty)
2539 Q_DECLARE_METATYPE(QCPScatterStyle::ScatterShape)
2540 
2541 /* end of 'src/scatterstyle.h' */
2542 
2543 
2544 /* including file 'src/datacontainer.h' */
2545 /* modified 2021-03-29T02:30:44, size 34070 */
2546 
2547 /*! \relates QCPDataContainer
2548  Returns whether the sort key of \a a is less than the sort key of \a b.
2549 
2550  \see QCPDataContainer::sort
2551 */
2552 template <class DataType>
2553 inline bool qcpLessThanSortKey(const DataType &a, const DataType &b) { return a.sortKey() < b.sortKey(); }
2554 
2555 template <class DataType>
2556 class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp included below)
2557 {
2558 public:
2559  typedef typename QVector<DataType>::const_iterator const_iterator;
2560  typedef typename QVector<DataType>::iterator iterator;
2561 
2562  QCPDataContainer();
2563 
2564  // getters:
2565  int size() const { return mData.size()-mPreallocSize; }
2566  bool isEmpty() const { return size() == 0; }
2567  bool autoSqueeze() const { return mAutoSqueeze; }
2568 
2569  // setters:
2570  void setAutoSqueeze(bool enabled);
2571 
2572  // non-virtual methods:
2573  void set(const QCPDataContainer<DataType> &data);
2574  void set(const QVector<DataType> &data, bool alreadySorted=false);
2575  void add(const QCPDataContainer<DataType> &data);
2576  void add(const QVector<DataType> &data, bool alreadySorted=false);
2577  void add(const DataType &data);
2578  void removeBefore(double sortKey);
2579  void removeAfter(double sortKey);
2580  void remove(double sortKeyFrom, double sortKeyTo);
2581  void remove(double sortKey);
2582  void clear();
2583  void sort();
2584  void squeeze(bool preAllocation=true, bool postAllocation=true);
2585 
2586  const_iterator constBegin() const { return mData.constBegin()+mPreallocSize; }
2587  const_iterator constEnd() const { return mData.constEnd(); }
2588  iterator begin() { return mData.begin()+mPreallocSize; }
2589  iterator end() { return mData.end(); }
2590  const_iterator findBegin(double sortKey, bool expandedRange=true) const;
2591  const_iterator findEnd(double sortKey, bool expandedRange=true) const;
2592  const_iterator at(int index) const { return constBegin()+qBound(0, index, size()); }
2593  QCPRange keyRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth);
2594  QCPRange valueRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange());
2595  QCPDataRange dataRange() const { return QCPDataRange(0, size()); }
2596  void limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const;
2597 
2598 protected:
2599  // property members:
2600  bool mAutoSqueeze;
2601 
2602  // non-property memebers:
2603  QVector<DataType> mData;
2604  int mPreallocSize;
2605  int mPreallocIteration;
2606 
2607  // non-virtual methods:
2608  void preallocateGrow(int minimumPreallocSize);
2609  void performAutoSqueeze();
2610 };
2611 
2612 
2613 
2614 // include implementation in header since it is a class template:
2615 ////////////////////////////////////////////////////////////////////////////////////////////////////
2616 //////////////////// QCPDataContainer
2617 ////////////////////////////////////////////////////////////////////////////////////////////////////
2618 
2619 /*! \class QCPDataContainer
2620  \brief The generic data container for one-dimensional plottables
2621 
2622  This class template provides a fast container for data storage of one-dimensional data. The data
2623  type is specified as template parameter (called \a DataType in the following) and must provide
2624  some methods as described in the \ref qcpdatacontainer-datatype "next section".
2625 
2626  The data is stored in a sorted fashion, which allows very quick lookups by the sorted key as well
2627  as retrieval of ranges (see \ref findBegin, \ref findEnd, \ref keyRange) using binary search. The
2628  container uses a preallocation and a postallocation scheme, such that appending and prepending
2629  data (with respect to the sort key) is very fast and minimizes reallocations. If data is added
2630  which needs to be inserted between existing keys, the merge usually can be done quickly too,
2631  using the fact that existing data is always sorted. The user can further improve performance by
2632  specifying that added data is already itself sorted by key, if he can guarantee that this is the
2633  case (see for example \ref add(const QVector<DataType> &data, bool alreadySorted)).
2634 
2635  The data can be accessed with the provided const iterators (\ref constBegin, \ref constEnd). If
2636  it is necessary to alter existing data in-place, the non-const iterators can be used (\ref begin,
2637  \ref end). Changing data members that are not the sort key (for most data types called \a key) is
2638  safe from the container's perspective.
2639 
2640  Great care must be taken however if the sort key is modified through the non-const iterators. For
2641  performance reasons, the iterators don't automatically cause a re-sorting upon their
2642  manipulation. It is thus the responsibility of the user to leave the container in a sorted state
2643  when finished with the data manipulation, before calling any other methods on the container. A
2644  complete re-sort (e.g. after finishing all sort key manipulation) can be done by calling \ref
2645  sort. Failing to do so can not be detected by the container efficiently and will cause both
2646  rendering artifacts and potential data loss.
2647 
2648  Implementing one-dimensional plottables that make use of a \ref QCPDataContainer<T> is usually
2649  done by subclassing from \ref QCPAbstractPlottable1D "QCPAbstractPlottable1D<T>", which
2650  introduces an according \a mDataContainer member and some convenience methods.
2651 
2652  \section qcpdatacontainer-datatype Requirements for the DataType template parameter
2653 
2654  The template parameter <tt>DataType</tt> is the type of the stored data points. It must be
2655  trivially copyable and have the following public methods, preferably inline:
2656 
2657  \li <tt>double sortKey() const</tt>\n Returns the member variable of this data point that is the
2658  sort key, defining the ordering in the container. Often this variable is simply called \a key.
2659 
2660  \li <tt>static DataType fromSortKey(double sortKey)</tt>\n Returns a new instance of the data
2661  type initialized with its sort key set to \a sortKey.
2662 
2663  \li <tt>static bool sortKeyIsMainKey()</tt>\n Returns true if the sort key is equal to the main
2664  key (see method \c mainKey below). For most plottables this is the case. It is not the case for
2665  example for \ref QCPCurve, which uses \a t as sort key and \a key as main key. This is the reason
2666  why QCPCurve unlike QCPGraph can display parametric curves with loops.
2667 
2668  \li <tt>double mainKey() const</tt>\n Returns the variable of this data point considered the main
2669  key. This is commonly the variable that is used as the coordinate of this data point on the key
2670  axis of the plottable. This method is used for example when determining the automatic axis
2671  rescaling of key axes (\ref QCPAxis::rescale).
2672 
2673  \li <tt>double mainValue() const</tt>\n Returns the variable of this data point considered the
2674  main value. This is commonly the variable that is used as the coordinate of this data point on
2675  the value axis of the plottable.
2676 
2677  \li <tt>QCPRange valueRange() const</tt>\n Returns the range this data point spans in the value
2678  axis coordinate. If the data is single-valued (e.g. QCPGraphData), this is simply a range with
2679  both lower and upper set to the main data point value. However if the data points can represent
2680  multiple values at once (e.g QCPFinancialData with its \a high, \a low, \a open and \a close
2681  values at each \a key) this method should return the range those values span. This method is used
2682  for example when determining the automatic axis rescaling of value axes (\ref
2683  QCPAxis::rescale).
2684 */
2685 
2686 /* start documentation of inline functions */
2687 
2688 /*! \fn int QCPDataContainer<DataType>::size() const
2689 
2690  Returns the number of data points in the container.
2691 */
2692 
2693 /*! \fn bool QCPDataContainer<DataType>::isEmpty() const
2694 
2695  Returns whether this container holds no data points.
2696 */
2697 
2698 /*! \fn QCPDataContainer::const_iterator QCPDataContainer<DataType>::constBegin() const
2699 
2700  Returns a const iterator to the first data point in this container.
2701 */
2702 
2703 /*! \fn QCPDataContainer::const_iterator QCPDataContainer<DataType>::constEnd() const
2704 
2705  Returns a const iterator to the element past the last data point in this container.
2706 */
2707 
2708 /*! \fn QCPDataContainer::iterator QCPDataContainer<DataType>::begin() const
2709 
2710  Returns a non-const iterator to the first data point in this container.
2711 
2712  You can manipulate the data points in-place through the non-const iterators, but great care must
2713  be taken when manipulating the sort key of a data point, see \ref sort, or the detailed
2714  description of this class.
2715 */
2716 
2717 /*! \fn QCPDataContainer::iterator QCPDataContainer<DataType>::end() const
2718 
2719  Returns a non-const iterator to the element past the last data point in this container.
2720 
2721  You can manipulate the data points in-place through the non-const iterators, but great care must
2722  be taken when manipulating the sort key of a data point, see \ref sort, or the detailed
2723  description of this class.
2724 */
2725 
2726 /*! \fn QCPDataContainer::const_iterator QCPDataContainer<DataType>::at(int index) const
2727 
2728  Returns a const iterator to the element with the specified \a index. If \a index points beyond
2729  the available elements in this container, returns \ref constEnd, i.e. an iterator past the last
2730  valid element.
2731 
2732  You can use this method to easily obtain iterators from a \ref QCPDataRange, see the \ref
2733  dataselection-accessing "data selection page" for an example.
2734 */
2735 
2736 /*! \fn QCPDataRange QCPDataContainer::dataRange() const
2737 
2738  Returns a \ref QCPDataRange encompassing the entire data set of this container. This means the
2739  begin index of the returned range is 0, and the end index is \ref size.
2740 */
2741 
2742 /* end documentation of inline functions */
2743 
2744 /*!
2745  Constructs a QCPDataContainer used for plottable classes that represent a series of key-sorted
2746  data
2747 */
2748 template <class DataType>
2750  mAutoSqueeze(true),
2751  mPreallocSize(0),
2752  mPreallocIteration(0)
2753 {
2754 }
2755 
2756 /*!
2757  Sets whether the container automatically decides when to release memory from its post- and
2758  preallocation pools when data points are removed. By default this is enabled and for typical
2759  applications shouldn't be changed.
2760 
2761  If auto squeeze is disabled, you can manually decide when to release pre-/postallocation with
2762  \ref squeeze.
2763 */
2764 template <class DataType>
2766 {
2767  if (mAutoSqueeze != enabled)
2768  {
2769  mAutoSqueeze = enabled;
2770  if (mAutoSqueeze)
2771  performAutoSqueeze();
2772  }
2773 }
2774 
2775 /*! \overload
2776 
2777  Replaces the current data in this container with the provided \a data.
2778 
2779  \see add, remove
2780 */
2781 template <class DataType>
2783 {
2784  clear();
2785  add(data);
2786 }
2787 
2788 /*! \overload
2789 
2790  Replaces the current data in this container with the provided \a data
2791 
2792  If you can guarantee that the data points in \a data have ascending order with respect to the
2793  DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run.
2794 
2795  \see add, remove
2796 */
2797 template <class DataType>
2798 void QCPDataContainer<DataType>::set(const QVector<DataType> &data, bool alreadySorted)
2799 {
2800  mData = data;
2801  mPreallocSize = 0;
2802  mPreallocIteration = 0;
2803  if (!alreadySorted)
2804  sort();
2805 }
2806 
2807 /*! \overload
2808 
2809  Adds the provided \a data to the current data in this container.
2810 
2811  \see set, remove
2812 */
2813 template <class DataType>
2815 {
2816  if (data.isEmpty())
2817  return;
2818 
2819  const int n = data.size();
2820  const int oldSize = size();
2821 
2822  if (oldSize > 0 && !qcpLessThanSortKey<DataType>(*constBegin(), *(data.constEnd()-1))) // prepend if new data keys are all smaller than or equal to existing ones
2823  {
2824  if (mPreallocSize < n)
2825  preallocateGrow(n);
2826  mPreallocSize -= n;
2827  std::copy(data.constBegin(), data.constEnd(), begin());
2828  } else // don't need to prepend, so append and merge if necessary
2829  {
2830  mData.resize(mData.size()+n);
2831  std::copy(data.constBegin(), data.constEnd(), end()-n);
2832  if (oldSize > 0 && !qcpLessThanSortKey<DataType>(*(constEnd()-n-1), *(constEnd()-n))) // if appended range keys aren't all greater than existing ones, merge the two partitions
2833  std::inplace_merge(begin(), end()-n, end(), qcpLessThanSortKey<DataType>);
2834  }
2835 }
2836 
2837 /*!
2838  Adds the provided data points in \a data to the current data.
2839 
2840  If you can guarantee that the data points in \a data have ascending order with respect to the
2841  DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run.
2842 
2843  \see set, remove
2844 */
2845 template <class DataType>
2846 void QCPDataContainer<DataType>::add(const QVector<DataType> &data, bool alreadySorted)
2847 {
2848  if (data.isEmpty())
2849  return;
2850  if (isEmpty())
2851  {
2852  set(data, alreadySorted);
2853  return;
2854  }
2855 
2856  const int n = data.size();
2857  const int oldSize = size();
2858 
2859  if (alreadySorted && oldSize > 0 && !qcpLessThanSortKey<DataType>(*constBegin(), *(data.constEnd()-1))) // prepend if new data is sorted and keys are all smaller than or equal to existing ones
2860  {
2861  if (mPreallocSize < n)
2862  preallocateGrow(n);
2863  mPreallocSize -= n;
2864  std::copy(data.constBegin(), data.constEnd(), begin());
2865  } else // don't need to prepend, so append and then sort and merge if necessary
2866  {
2867  mData.resize(mData.size()+n);
2868  std::copy(data.constBegin(), data.constEnd(), end()-n);
2869  if (!alreadySorted) // sort appended subrange if it wasn't already sorted
2870  std::sort(end()-n, end(), qcpLessThanSortKey<DataType>);
2871  if (oldSize > 0 && !qcpLessThanSortKey<DataType>(*(constEnd()-n-1), *(constEnd()-n))) // if appended range keys aren't all greater than existing ones, merge the two partitions
2872  std::inplace_merge(begin(), end()-n, end(), qcpLessThanSortKey<DataType>);
2873  }
2874 }
2875 
2876 /*! \overload
2877 
2878  Adds the provided single data point to the current data.
2879 
2880  \see remove
2881 */
2882 template <class DataType>
2883 void QCPDataContainer<DataType>::add(const DataType &data)
2884 {
2885  if (isEmpty() || !qcpLessThanSortKey<DataType>(data, *(constEnd()-1))) // quickly handle appends if new data key is greater or equal to existing ones
2886  {
2887  mData.append(data);
2888  } else if (qcpLessThanSortKey<DataType>(data, *constBegin())) // quickly handle prepends using preallocated space
2889  {
2890  if (mPreallocSize < 1)
2891  preallocateGrow(1);
2892  --mPreallocSize;
2893  *begin() = data;
2894  } else // handle inserts, maintaining sorted keys
2895  {
2896  QCPDataContainer<DataType>::iterator insertionPoint = std::lower_bound(begin(), end(), data, qcpLessThanSortKey<DataType>);
2897  mData.insert(insertionPoint, data);
2898  }
2899 }
2900 
2901 /*!
2902  Removes all data points with (sort-)keys smaller than or equal to \a sortKey.
2903 
2904  \see removeAfter, remove, clear
2905 */
2906 template <class DataType>
2908 {
2909  QCPDataContainer<DataType>::iterator it = begin();
2910  QCPDataContainer<DataType>::iterator itEnd = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
2911  mPreallocSize += int(itEnd-it); // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it)
2912  if (mAutoSqueeze)
2913  performAutoSqueeze();
2914 }
2915 
2916 /*!
2917  Removes all data points with (sort-)keys greater than or equal to \a sortKey.
2918 
2919  \see removeBefore, remove, clear
2920 */
2921 template <class DataType>
2923 {
2924  QCPDataContainer<DataType>::iterator it = std::upper_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
2925  QCPDataContainer<DataType>::iterator itEnd = end();
2926  mData.erase(it, itEnd); // typically adds it to the postallocated block
2927  if (mAutoSqueeze)
2928  performAutoSqueeze();
2929 }
2930 
2931 /*!
2932  Removes all data points with (sort-)keys between \a sortKeyFrom and \a sortKeyTo. if \a
2933  sortKeyFrom is greater or equal to \a sortKeyTo, the function does nothing. To remove a single
2934  data point with known (sort-)key, use \ref remove(double sortKey).
2935 
2936  \see removeBefore, removeAfter, clear
2937 */
2938 template <class DataType>
2939 void QCPDataContainer<DataType>::remove(double sortKeyFrom, double sortKeyTo)
2940 {
2941  if (sortKeyFrom >= sortKeyTo || isEmpty())
2942  return;
2943 
2944  QCPDataContainer<DataType>::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKeyFrom), qcpLessThanSortKey<DataType>);
2945  QCPDataContainer<DataType>::iterator itEnd = std::upper_bound(it, end(), DataType::fromSortKey(sortKeyTo), qcpLessThanSortKey<DataType>);
2946  mData.erase(it, itEnd);
2947  if (mAutoSqueeze)
2948  performAutoSqueeze();
2949 }
2950 
2951 /*! \overload
2952 
2953  Removes a single data point at \a sortKey. If the position is not known with absolute (binary)
2954  precision, consider using \ref remove(double sortKeyFrom, double sortKeyTo) with a small
2955  fuzziness interval around the suspected position, depeding on the precision with which the
2956  (sort-)key is known.
2957 
2958  \see removeBefore, removeAfter, clear
2959 */
2960 template <class DataType>
2962 {
2963  QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
2964  if (it != end() && it->sortKey() == sortKey)
2965  {
2966  if (it == begin())
2967  ++mPreallocSize; // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it)
2968  else
2969  mData.erase(it);
2970  }
2971  if (mAutoSqueeze)
2972  performAutoSqueeze();
2973 }
2974 
2975 /*!
2976  Removes all data points.
2977 
2978  \see remove, removeAfter, removeBefore
2979 */
2980 template <class DataType>
2982 {
2983  mData.clear();
2984  mPreallocIteration = 0;
2985  mPreallocSize = 0;
2986 }
2987 
2988 /*!
2989  Re-sorts all data points in the container by their sort key.
2990 
2991  When setting, adding or removing points using the QCPDataContainer interface (\ref set, \ref add,
2992  \ref remove, etc.), the container makes sure to always stay in a sorted state such that a full
2993  resort is never necessary. However, if you choose to directly manipulate the sort key on data
2994  points by accessing and modifying it through the non-const iterators (\ref begin, \ref end), it
2995  is your responsibility to bring the container back into a sorted state before any other methods
2996  are called on it. This can be achieved by calling this method immediately after finishing the
2997  sort key manipulation.
2998 */
2999 template <class DataType>
3001 {
3002  std::sort(begin(), end(), qcpLessThanSortKey<DataType>);
3003 }
3004 
3005 /*!
3006  Frees all unused memory that is currently in the preallocation and postallocation pools.
3007 
3008  Note that QCPDataContainer automatically decides whether squeezing is necessary, if \ref
3009  setAutoSqueeze is left enabled. It should thus not be necessary to use this method for typical
3010  applications.
3011 
3012  The parameters \a preAllocation and \a postAllocation control whether pre- and/or post allocation
3013  should be freed, respectively.
3014 */
3015 template <class DataType>
3016 void QCPDataContainer<DataType>::squeeze(bool preAllocation, bool postAllocation)
3017 {
3018  if (preAllocation)
3019  {
3020  if (mPreallocSize > 0)
3021  {
3022  std::copy(begin(), end(), mData.begin());
3023  mData.resize(size());
3024  mPreallocSize = 0;
3025  }
3026  mPreallocIteration = 0;
3027  }
3028  if (postAllocation)
3029  mData.squeeze();
3030 }
3031 
3032 /*!
3033  Returns an iterator to the data point with a (sort-)key that is equal to, just below, or just
3034  above \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be
3035  considered, otherwise the one just above.
3036 
3037  This can be used in conjunction with \ref findEnd to iterate over data points within a given key
3038  range, including or excluding the bounding data points that are just beyond the specified range.
3039 
3040  If \a expandedRange is true but there are no data points below \a sortKey, \ref constBegin is
3041  returned.
3042 
3043  If the container is empty, returns \ref constEnd.
3044 
3045  \see findEnd, QCPPlottableInterface1D::findBegin
3046 */
3047 template <class DataType>
3048 typename QCPDataContainer<DataType>::const_iterator QCPDataContainer<DataType>::findBegin(double sortKey, bool expandedRange) const
3049 {
3050  if (isEmpty())
3051  return constEnd();
3052 
3053  QCPDataContainer<DataType>::const_iterator it = std::lower_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
3054  if (expandedRange && it != constBegin()) // also covers it == constEnd case, and we know --constEnd is valid because mData isn't empty
3055  --it;
3056  return it;
3057 }
3058 
3059 /*!
3060  Returns an iterator to the element after the data point with a (sort-)key that is equal to, just
3061  above or just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey
3062  will be considered, otherwise the one just below.
3063 
3064  This can be used in conjunction with \ref findBegin to iterate over data points within a given
3065  key range, including the bounding data points that are just below and above the specified range.
3066 
3067  If \a expandedRange is true but there are no data points above \a sortKey, \ref constEnd is
3068  returned.
3069 
3070  If the container is empty, \ref constEnd is returned.
3071 
3072  \see findBegin, QCPPlottableInterface1D::findEnd
3073 */
3074 template <class DataType>
3075 typename QCPDataContainer<DataType>::const_iterator QCPDataContainer<DataType>::findEnd(double sortKey, bool expandedRange) const
3076 {
3077  if (isEmpty())
3078  return constEnd();
3079 
3080  QCPDataContainer<DataType>::const_iterator it = std::upper_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
3081  if (expandedRange && it != constEnd())
3082  ++it;
3083  return it;
3084 }
3085 
3086 /*!
3087  Returns the range encompassed by the (main-)key coordinate of all data points. The output
3088  parameter \a foundRange indicates whether a sensible range was found. If this is false, you
3089  should not use the returned QCPRange (e.g. the data container is empty or all points have the
3090  same key).
3091 
3092  Use \a signDomain to control which sign of the key coordinates should be considered. This is
3093  relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a
3094  time.
3095 
3096  If the DataType reports that its main key is equal to the sort key (\a sortKeyIsMainKey), as is
3097  the case for most plottables, this method uses this fact and finds the range very quickly.
3098 
3099  \see valueRange
3100 */
3101 template <class DataType>
3103 {
3104  if (isEmpty())
3105  {
3106  foundRange = false;
3107  return QCPRange();
3108  }
3109  QCPRange range;
3110  bool haveLower = false;
3111  bool haveUpper = false;
3112  double current;
3113 
3114  QCPDataContainer<DataType>::const_iterator it = constBegin();
3115  QCPDataContainer<DataType>::const_iterator itEnd = constEnd();
3116  if (signDomain == QCP::sdBoth) // range may be anywhere
3117  {
3118  if (DataType::sortKeyIsMainKey()) // if DataType is sorted by main key (e.g. QCPGraph, but not QCPCurve), use faster algorithm by finding just first and last key with non-NaN value
3119  {
3120  while (it != itEnd) // find first non-nan going up from left
3121  {
3122  if (!qIsNaN(it->mainValue()))
3123  {
3124  range.lower = it->mainKey();
3125  haveLower = true;
3126  break;
3127  }
3128  ++it;
3129  }
3130  it = itEnd;
3131  while (it != constBegin()) // find first non-nan going down from right
3132  {
3133  --it;
3134  if (!qIsNaN(it->mainValue()))
3135  {
3136  range.upper = it->mainKey();
3137  haveUpper = true;
3138  break;
3139  }
3140  }
3141  } else // DataType is not sorted by main key, go through all data points and accordingly expand range
3142  {
3143  while (it != itEnd)
3144  {
3145  if (!qIsNaN(it->mainValue()))
3146  {
3147  current = it->mainKey();
3148  if (current < range.lower || !haveLower)
3149  {
3150  range.lower = current;
3151  haveLower = true;
3152  }
3153  if (current > range.upper || !haveUpper)
3154  {
3155  range.upper = current;
3156  haveUpper = true;
3157  }
3158  }
3159  ++it;
3160  }
3161  }
3162  } else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain
3163  {
3164  while (it != itEnd)
3165  {
3166  if (!qIsNaN(it->mainValue()))
3167  {
3168  current = it->mainKey();
3169  if ((current < range.lower || !haveLower) && current < 0)
3170  {
3171  range.lower = current;
3172  haveLower = true;
3173  }
3174  if ((current > range.upper || !haveUpper) && current < 0)
3175  {
3176  range.upper = current;
3177  haveUpper = true;
3178  }
3179  }
3180  ++it;
3181  }
3182  } else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain
3183  {
3184  while (it != itEnd)
3185  {
3186  if (!qIsNaN(it->mainValue()))
3187  {
3188  current = it->mainKey();
3189  if ((current < range.lower || !haveLower) && current > 0)
3190  {
3191  range.lower = current;
3192  haveLower = true;
3193  }
3194  if ((current > range.upper || !haveUpper) && current > 0)
3195  {
3196  range.upper = current;
3197  haveUpper = true;
3198  }
3199  }
3200  ++it;
3201  }
3202  }
3203 
3204  foundRange = haveLower && haveUpper;
3205  return range;
3206 }
3207 
3208 /*!
3209  Returns the range encompassed by the value coordinates of the data points in the specified key
3210  range (\a inKeyRange), using the full \a DataType::valueRange reported by the data points. The
3211  output parameter \a foundRange indicates whether a sensible range was found. If this is false,
3212  you should not use the returned QCPRange (e.g. the data container is empty or all points have the
3213  same value).
3214 
3215  If \a inKeyRange has both lower and upper bound set to zero (is equal to <tt>QCPRange()</tt>),
3216  all data points are considered, without any restriction on the keys.
3217 
3218  Use \a signDomain to control which sign of the value coordinates should be considered. This is
3219  relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a
3220  time.
3221 
3222  \see keyRange
3223 */
3224 template <class DataType>
3225 QCPRange QCPDataContainer<DataType>::valueRange(bool &foundRange, QCP::SignDomain signDomain, const QCPRange &inKeyRange)
3226 {
3227  if (isEmpty())
3228  {
3229  foundRange = false;
3230  return QCPRange();
3231  }
3232  QCPRange range;
3233  const bool restrictKeyRange = inKeyRange != QCPRange();
3234  bool haveLower = false;
3235  bool haveUpper = false;
3236  QCPRange current;
3237  QCPDataContainer<DataType>::const_iterator itBegin = constBegin();
3238  QCPDataContainer<DataType>::const_iterator itEnd = constEnd();
3239  if (DataType::sortKeyIsMainKey() && restrictKeyRange)
3240  {
3241  itBegin = findBegin(inKeyRange.lower, false);
3242  itEnd = findEnd(inKeyRange.upper, false);
3243  }
3244  if (signDomain == QCP::sdBoth) // range may be anywhere
3245  {
3246  for (QCPDataContainer<DataType>::const_iterator it = itBegin; it != itEnd; ++it)
3247  {
3248  if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper))
3249  continue;
3250  current = it->valueRange();
3251  if ((current.lower < range.lower || !haveLower) && !qIsNaN(current.lower))
3252  {
3253  range.lower = current.lower;
3254  haveLower = true;
3255  }
3256  if ((current.upper > range.upper || !haveUpper) && !qIsNaN(current.upper))
3257  {
3258  range.upper = current.upper;
3259  haveUpper = true;
3260  }
3261  }
3262  } else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain
3263  {
3264  for (QCPDataContainer<DataType>::const_iterator it = itBegin; it != itEnd; ++it)
3265  {
3266  if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper))
3267  continue;
3268  current = it->valueRange();
3269  if ((current.lower < range.lower || !haveLower) && current.lower < 0 && !qIsNaN(current.lower))
3270  {
3271  range.lower = current.lower;
3272  haveLower = true;
3273  }
3274  if ((current.upper > range.upper || !haveUpper) && current.upper < 0 && !qIsNaN(current.upper))
3275  {
3276  range.upper = current.upper;
3277  haveUpper = true;
3278  }
3279  }
3280  } else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain
3281  {
3282  for (QCPDataContainer<DataType>::const_iterator it = itBegin; it != itEnd; ++it)
3283  {
3284  if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper))
3285  continue;
3286  current = it->valueRange();
3287  if ((current.lower < range.lower || !haveLower) && current.lower > 0 && !qIsNaN(current.lower))
3288  {
3289  range.lower = current.lower;
3290  haveLower = true;
3291  }
3292  if ((current.upper > range.upper || !haveUpper) && current.upper > 0 && !qIsNaN(current.upper))
3293  {
3294  range.upper = current.upper;
3295  haveUpper = true;
3296  }
3297  }
3298  }
3299 
3300  foundRange = haveLower && haveUpper;
3301  return range;
3302 }
3303 
3304 /*!
3305  Makes sure \a begin and \a end mark a data range that is both within the bounds of this data
3306  container's data, as well as within the specified \a dataRange. The initial range described by
3307  the passed iterators \a begin and \a end is never expanded, only contracted if necessary.
3308 
3309  This function doesn't require for \a dataRange to be within the bounds of this data container's
3310  valid range.
3311 */
3312 template <class DataType>
3313 void QCPDataContainer<DataType>::limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const
3314 {
3315  QCPDataRange iteratorRange(int(begin-constBegin()), int(end-constBegin()));
3316  iteratorRange = iteratorRange.bounded(dataRange.bounded(this->dataRange()));
3317  begin = constBegin()+iteratorRange.begin();
3318  end = constBegin()+iteratorRange.end();
3319 }
3320 
3321 /*! \internal
3322 
3323  Increases the preallocation pool to have a size of at least \a minimumPreallocSize. Depending on
3324  the preallocation history, the container will grow by more than requested, to speed up future
3325  consecutive size increases.
3326 
3327  if \a minimumPreallocSize is smaller than or equal to the current preallocation pool size, this
3328  method does nothing.
3329 */
3330 template <class DataType>
3331 void QCPDataContainer<DataType>::preallocateGrow(int minimumPreallocSize)
3332 {
3333  if (minimumPreallocSize <= mPreallocSize)
3334  return;
3335 
3336  int newPreallocSize = minimumPreallocSize;
3337  newPreallocSize += (1u<<qBound(4, mPreallocIteration+4, 15)) - 12; // do 4 up to 32768-12 preallocation, doubling in each intermediate iteration
3338  ++mPreallocIteration;
3339 
3340  int sizeDifference = newPreallocSize-mPreallocSize;
3341  mData.resize(mData.size()+sizeDifference);
3342  std::copy_backward(mData.begin()+mPreallocSize, mData.end()-sizeDifference, mData.end());
3343  mPreallocSize = newPreallocSize;
3344 }
3345 
3346 /*! \internal
3347 
3348  This method decides, depending on the total allocation size and the size of the unused pre- and
3349  postallocation pools, whether it is sensible to reduce the pools in order to free up unused
3350  memory. It then possibly calls \ref squeeze to do the deallocation.
3351 
3352  If \ref setAutoSqueeze is enabled, this method is called automatically each time data points are
3353  removed from the container (e.g. \ref remove).
3354 
3355  \note when changing the decision parameters, care must be taken not to cause a back-and-forth
3356  between squeezing and reallocation due to the growth strategy of the internal QVector and \ref
3357  preallocateGrow. The hysteresis between allocation and deallocation should be made high enough
3358  (at the expense of possibly larger unused memory from time to time).
3359 */
3360 template <class DataType>
3362 {
3363  const int totalAlloc = mData.capacity();
3364  const int postAllocSize = totalAlloc-mData.size();
3365  const int usedSize = size();
3366  bool shrinkPostAllocation = false;
3367  bool shrinkPreAllocation = false;
3368  if (totalAlloc > 650000) // if allocation is larger, shrink earlier with respect to total used size
3369  {
3370  shrinkPostAllocation = postAllocSize > usedSize*1.5; // QVector grow strategy is 2^n for static data. Watch out not to oscillate!
3371  shrinkPreAllocation = mPreallocSize*10 > usedSize;
3372  } else if (totalAlloc > 1000) // below 10 MiB raw data be generous with preallocated memory, below 1k points don't even bother
3373  {
3374  shrinkPostAllocation = postAllocSize > usedSize*5;
3375  shrinkPreAllocation = mPreallocSize > usedSize*1.5; // preallocation can grow into postallocation, so can be smaller
3376  }
3377 
3378  if (shrinkPreAllocation || shrinkPostAllocation)
3379  squeeze(shrinkPreAllocation, shrinkPostAllocation);
3380 }
3381 
3382 
3383 /* end of 'src/datacontainer.h' */
3384 
3385 
3386 /* including file 'src/plottable.h' */
3387 /* modified 2021-03-29T02:30:44, size 8461 */
3388 
3389 class QCP_LIB_DECL QCPSelectionDecorator
3390 {
3391  Q_GADGET
3392 public:
3394  virtual ~QCPSelectionDecorator();
3395 
3396  // getters:
3397  QPen pen() const { return mPen; }
3398  QBrush brush() const { return mBrush; }
3399  QCPScatterStyle scatterStyle() const { return mScatterStyle; }
3400  QCPScatterStyle::ScatterProperties usedScatterProperties() const { return mUsedScatterProperties; }
3401 
3402  // setters:
3403  void setPen(const QPen &pen);
3404  void setBrush(const QBrush &brush);
3405  void setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties=QCPScatterStyle::spPen);
3406  void setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties);
3407 
3408  // non-virtual methods:
3409  void applyPen(QCPPainter *painter) const;
3410  void applyBrush(QCPPainter *painter) const;
3411  QCPScatterStyle getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const;
3412 
3413  // introduced virtual methods:
3414  virtual void copyFrom(const QCPSelectionDecorator *other);
3415  virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection);
3416 
3417 protected:
3418  // property members:
3419  QPen mPen;
3420  QBrush mBrush;
3421  QCPScatterStyle mScatterStyle;
3422  QCPScatterStyle::ScatterProperties mUsedScatterProperties;
3423  // non-property members:
3424  QCPAbstractPlottable *mPlottable;
3425 
3426  // introduced virtual methods:
3427  virtual bool registerWithPlottable(QCPAbstractPlottable *plottable);
3428 
3429 private:
3430  Q_DISABLE_COPY(QCPSelectionDecorator)
3431  friend class QCPAbstractPlottable;
3432 };
3433 Q_DECLARE_METATYPE(QCPSelectionDecorator*)
3434 
3435 
3436 class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable
3437 {
3438  Q_OBJECT
3439  /// \cond INCLUDE_QPROPERTIES
3440  Q_PROPERTY(QString name READ name WRITE setName)
3441  Q_PROPERTY(bool antialiasedFill READ antialiasedFill WRITE setAntialiasedFill)
3442  Q_PROPERTY(bool antialiasedScatters READ antialiasedScatters WRITE setAntialiasedScatters)
3443  Q_PROPERTY(QPen pen READ pen WRITE setPen)
3444  Q_PROPERTY(QBrush brush READ brush WRITE setBrush)
3445  Q_PROPERTY(QCPAxis* keyAxis READ keyAxis WRITE setKeyAxis)
3446  Q_PROPERTY(QCPAxis* valueAxis READ valueAxis WRITE setValueAxis)
3447  Q_PROPERTY(QCP::SelectionType selectable READ selectable WRITE setSelectable NOTIFY selectableChanged)
3450  /// \endcond
3451 public:
3452  QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis);
3453  virtual ~QCPAbstractPlottable() Q_DECL_OVERRIDE;
3454 
3455  // getters:
3456  QString name() const { return mName; }
3457  bool antialiasedFill() const { return mAntialiasedFill; }
3458  bool antialiasedScatters() const { return mAntialiasedScatters; }
3459  QPen pen() const { return mPen; }
3460  QBrush brush() const { return mBrush; }
3461  QCPAxis *keyAxis() const { return mKeyAxis.data(); }
3462  QCPAxis *valueAxis() const { return mValueAxis.data(); }
3463  QCP::SelectionType selectable() const { return mSelectable; }
3464  bool selected() const { return !mSelection.isEmpty(); }
3465  QCPDataSelection selection() const { return mSelection; }
3466  QCPSelectionDecorator *selectionDecorator() const { return mSelectionDecorator; }
3467 
3468  // setters:
3469  void setName(const QString &name);
3470  void setAntialiasedFill(bool enabled);
3471  void setAntialiasedScatters(bool enabled);
3472  void setPen(const QPen &pen);
3473  void setBrush(const QBrush &brush);
3474  void setKeyAxis(QCPAxis *axis);
3475  void setValueAxis(QCPAxis *axis);
3476  Q_SLOT void setSelectable(QCP::SelectionType selectable);
3479 
3480  // introduced virtual methods:
3481  virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE = 0; // actually introduced in QCPLayerable as non-pure, but we want to force reimplementation for plottables
3482  virtual QCPPlottableInterface1D *interface1D() { return nullptr; }
3483  virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const = 0;
3484  virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const = 0;
3485 
3486  // non-property methods:
3487  void coordsToPixels(double key, double value, double &x, double &y) const;
3488  const QPointF coordsToPixels(double key, double value) const;
3489  void pixelsToCoords(double x, double y, double &key, double &value) const;
3490  void pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const;
3491  void rescaleAxes(bool onlyEnlarge=false) const;
3492  void rescaleKeyAxis(bool onlyEnlarge=false) const;
3493  void rescaleValueAxis(bool onlyEnlarge=false, bool inKeyRange=false) const;
3494  bool addToLegend(QCPLegend *legend);
3495  bool addToLegend();
3496  bool removeFromLegend(QCPLegend *legend) const;
3497  bool removeFromLegend() const;
3498 
3499 signals:
3500  void selectionChanged(bool selected);
3502  void selectableChanged(QCP::SelectionType selectable);
3503 
3504 protected:
3505  // property members:
3506  QString mName;
3507  bool mAntialiasedFill, mAntialiasedScatters;
3508  QPen mPen;
3509  QBrush mBrush;
3510  QPointer<QCPAxis> mKeyAxis, mValueAxis;
3511  QCP::SelectionType mSelectable;
3512  QCPDataSelection mSelection;
3513  QCPSelectionDecorator *mSelectionDecorator;
3514 
3515  // reimplemented virtual methods:
3516  virtual QRect clipRect() const Q_DECL_OVERRIDE;
3517  virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0;
3518  virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE;
3519  void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
3520  // events:
3521  virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
3522  virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE;
3523 
3524  // introduced virtual methods:
3525  virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const = 0;
3526 
3527  // non-virtual methods:
3528  void applyFillAntialiasingHint(QCPPainter *painter) const;
3529  void applyScattersAntialiasingHint(QCPPainter *painter) const;
3530 
3531 private:
3533 
3534  friend class QCustomPlot;
3535  friend class QCPAxis;
3536  friend class QCPPlottableLegendItem;
3537 };
3538 
3539 
3540 /* end of 'src/plottable.h' */
3541 
3542 
3543 /* including file 'src/item.h' */
3544 /* modified 2021-03-29T02:30:44, size 9425 */
3545 
3546 class QCP_LIB_DECL QCPItemAnchor
3547 {
3548  Q_GADGET
3549 public:
3550  QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId=-1);
3551  virtual ~QCPItemAnchor();
3552 
3553  // getters:
3554  QString name() const { return mName; }
3555  virtual QPointF pixelPosition() const;
3556 
3557 protected:
3558  // property members:
3559  QString mName;
3560 
3561  // non-property members:
3562  QCustomPlot *mParentPlot;
3563  QCPAbstractItem *mParentItem;
3564  int mAnchorId;
3565  QSet<QCPItemPosition*> mChildrenX, mChildrenY;
3566 
3567  // introduced virtual methods:
3568  virtual QCPItemPosition *toQCPItemPosition() { return nullptr; }
3569 
3570  // non-virtual methods:
3571  void addChildX(QCPItemPosition* pos); // called from pos when this anchor is set as parent
3572  void removeChildX(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted
3573  void addChildY(QCPItemPosition* pos); // called from pos when this anchor is set as parent
3574  void removeChildY(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted
3575 
3576 private:
3578 
3579  friend class QCPItemPosition;
3580 };
3581 
3582 
3583 
3584 class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor
3585 {
3586  Q_GADGET
3587 public:
3588  /*!
3589  Defines the ways an item position can be specified. Thus it defines what the numbers passed to
3590  \ref setCoords actually mean.
3591 
3592  \see setType
3593  */
3594  enum PositionType { ptAbsolute ///< Static positioning in pixels, starting from the top left corner of the viewport/widget.
3595  ,ptViewportRatio ///< Static positioning given by a fraction of the viewport size. For example, if you call setCoords(0, 0), the position will be at the top
3596  ///< left corner of the viewport/widget. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and
3597  ///< vertically at the top of the viewport/widget, etc.
3598  ,ptAxisRectRatio ///< Static positioning given by a fraction of the axis rect size (see \ref setAxisRect). For example, if you call setCoords(0, 0), the position will be at the top
3599  ///< left corner of the axis rect. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and
3600  ///< vertically at the top of the axis rect, etc. You can also go beyond the axis rect by providing negative coordinates or coordinates larger than 1.
3601  ,ptPlotCoords ///< Dynamic positioning at a plot coordinate defined by two axes (see \ref setAxes).
3602  };
3603  Q_ENUMS(PositionType)
3604 
3605  QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name);
3606  virtual ~QCPItemPosition() Q_DECL_OVERRIDE;
3607 
3608  // getters:
3609  PositionType type() const { return typeX(); }
3610  PositionType typeX() const { return mPositionTypeX; }
3611  PositionType typeY() const { return mPositionTypeY; }
3612  QCPItemAnchor *parentAnchor() const { return parentAnchorX(); }
3613  QCPItemAnchor *parentAnchorX() const { return mParentAnchorX; }
3614  QCPItemAnchor *parentAnchorY() const { return mParentAnchorY; }
3615  double key() const { return mKey; }
3616  double value() const { return mValue; }
3617  QPointF coords() const { return QPointF(mKey, mValue); }
3618  QCPAxis *keyAxis() const { return mKeyAxis.data(); }
3619  QCPAxis *valueAxis() const { return mValueAxis.data(); }
3620  QCPAxisRect *axisRect() const;
3621  virtual QPointF pixelPosition() const Q_DECL_OVERRIDE;
3622 
3623  // setters:
3624  void setType(PositionType type);
3625  void setTypeX(PositionType type);
3626  void setTypeY(PositionType type);
3627  bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false);
3628  bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false);
3629  bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false);
3630  void setCoords(double key, double value);
3631  void setCoords(const QPointF &pos);
3632  void setAxes(QCPAxis* keyAxis, QCPAxis* valueAxis);
3633  void setAxisRect(QCPAxisRect *axisRect);
3634  void setPixelPosition(const QPointF &pixelPosition);
3635 
3636 protected:
3637  // property members:
3638  PositionType mPositionTypeX, mPositionTypeY;
3639  QPointer<QCPAxis> mKeyAxis, mValueAxis;
3640  QPointer<QCPAxisRect> mAxisRect;
3641  double mKey, mValue;
3642  QCPItemAnchor *mParentAnchorX, *mParentAnchorY;
3643 
3644  // reimplemented virtual methods:
3645  virtual QCPItemPosition *toQCPItemPosition() Q_DECL_OVERRIDE { return this; }
3646 
3647 private:
3648  Q_DISABLE_COPY(QCPItemPosition)
3649 
3650 };
3651 Q_DECLARE_METATYPE(QCPItemPosition::PositionType)
3652 
3653 
3654 class QCP_LIB_DECL QCPAbstractItem : public QCPLayerable
3655 {
3656  Q_OBJECT
3657  /// \cond INCLUDE_QPROPERTIES
3658  Q_PROPERTY(bool clipToAxisRect READ clipToAxisRect WRITE setClipToAxisRect)
3659  Q_PROPERTY(QCPAxisRect* clipAxisRect READ clipAxisRect WRITE setClipAxisRect)
3660  Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged)
3661  Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged)
3662  /// \endcond
3663 public:
3664  explicit QCPAbstractItem(QCustomPlot *parentPlot);
3665  virtual ~QCPAbstractItem() Q_DECL_OVERRIDE;
3666 
3667  // getters:
3668  bool clipToAxisRect() const { return mClipToAxisRect; }
3669  QCPAxisRect *clipAxisRect() const;
3670  bool selectable() const { return mSelectable; }
3671  bool selected() const { return mSelected; }
3672 
3673  // setters:
3674  void setClipToAxisRect(bool clip);
3675  void setClipAxisRect(QCPAxisRect *rect);
3676  Q_SLOT void setSelectable(bool selectable);
3677  Q_SLOT void setSelected(bool selected);
3678 
3679  // reimplemented virtual methods:
3680  virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE = 0;
3681 
3682  // non-virtual methods:
3683  QList<QCPItemPosition*> positions() const { return mPositions; }
3684  QList<QCPItemAnchor*> anchors() const { return mAnchors; }
3685  QCPItemPosition *position(const QString &name) const;
3686  QCPItemAnchor *anchor(const QString &name) const;
3687  bool hasAnchor(const QString &name) const;
3688 
3689 signals:
3690  void selectionChanged(bool selected);
3691  void selectableChanged(bool selectable);
3692 
3693 protected:
3694  // property members:
3695  bool mClipToAxisRect;
3696  QPointer<QCPAxisRect> mClipAxisRect;
3697  QList<QCPItemPosition*> mPositions;
3698  QList<QCPItemAnchor*> mAnchors;
3699  bool mSelectable, mSelected;
3700 
3701  // reimplemented virtual methods:
3702  virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE;
3703  virtual QRect clipRect() const Q_DECL_OVERRIDE;
3704  virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
3705  virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0;
3706  // events:
3707  virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
3708  virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE;
3709 
3710  // introduced virtual methods:
3711  virtual QPointF anchorPixelPosition(int anchorId) const;
3712 
3713  // non-virtual methods:
3714  double rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const;
3715  QCPItemPosition *createPosition(const QString &name);
3716  QCPItemAnchor *createAnchor(const QString &name, int anchorId);
3717 
3718 private:
3719  Q_DISABLE_COPY(QCPAbstractItem)
3720 
3721  friend class QCustomPlot;
3722  friend class QCPItemAnchor;
3723 };
3724 
3725 /* end of 'src/item.h' */
3726 
3727 
3728 /* including file 'src/core.h' */
3729 /* modified 2021-03-29T02:30:44, size 19304 */
3730 
3731 class QCP_LIB_DECL QCustomPlot : public QWidget
3732 {
3733  Q_OBJECT
3734  /// \cond INCLUDE_QPROPERTIES
3735  Q_PROPERTY(QRect viewport READ viewport WRITE setViewport)
3736  Q_PROPERTY(QPixmap background READ background WRITE setBackground)
3737  Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled)
3738  Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode)
3739  Q_PROPERTY(QCPLayoutGrid* plotLayout READ plotLayout)
3740  Q_PROPERTY(bool autoAddPlottableToLegend READ autoAddPlottableToLegend WRITE setAutoAddPlottableToLegend)
3741  Q_PROPERTY(int selectionTolerance READ selectionTolerance WRITE setSelectionTolerance)
3742  Q_PROPERTY(bool noAntialiasingOnDrag READ noAntialiasingOnDrag WRITE setNoAntialiasingOnDrag)
3743  Q_PROPERTY(Qt::KeyboardModifier multiSelectModifier READ multiSelectModifier WRITE setMultiSelectModifier)
3744  Q_PROPERTY(bool openGl READ openGl WRITE setOpenGl)
3745  /// \endcond
3746 public:
3747  /*!
3748  Defines how a layer should be inserted relative to an other layer.
3749 
3750  \see addLayer, moveLayer
3751  */
3752  enum LayerInsertMode { limBelow ///< Layer is inserted below other layer
3753  ,limAbove ///< Layer is inserted above other layer
3754  };
3755  Q_ENUMS(LayerInsertMode)
3756 
3757  /*!
3758  Defines with what timing the QCustomPlot surface is refreshed after a replot.
3759 
3760  \see replot
3761  */
3762  enum RefreshPriority { rpImmediateRefresh ///< Replots immediately and repaints the widget immediately by calling QWidget::repaint() after the replot
3763  ,rpQueuedRefresh ///< Replots immediately, but queues the widget repaint, by calling QWidget::update() after the replot. This way multiple redundant widget repaints can be avoided.
3764  ,rpRefreshHint ///< Whether to use immediate or queued refresh depends on whether the plotting hint \ref QCP::phImmediateRefresh is set, see \ref setPlottingHints.
3765  ,rpQueuedReplot ///< Queues the entire replot for the next event loop iteration. This way multiple redundant replots can be avoided. The actual replot is then done with \ref rpRefreshHint priority.
3766  };
3767  Q_ENUMS(RefreshPriority)
3768 
3769  explicit QCustomPlot(QWidget *parent = nullptr);
3770  virtual ~QCustomPlot() Q_DECL_OVERRIDE;
3771 
3772  // getters:
3773  QRect viewport() const { return mViewport; }
3774  double bufferDevicePixelRatio() const { return mBufferDevicePixelRatio; }
3775  QPixmap background() const { return mBackgroundPixmap; }
3776  bool backgroundScaled() const { return mBackgroundScaled; }
3777  Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; }
3778  QCPLayoutGrid *plotLayout() const { return mPlotLayout; }
3779  QCP::AntialiasedElements antialiasedElements() const { return mAntialiasedElements; }
3780  QCP::AntialiasedElements notAntialiasedElements() const { return mNotAntialiasedElements; }
3781  bool autoAddPlottableToLegend() const { return mAutoAddPlottableToLegend; }
3782  const QCP::Interactions interactions() const { return mInteractions; }
3783  int selectionTolerance() const { return mSelectionTolerance; }
3784  bool noAntialiasingOnDrag() const { return mNoAntialiasingOnDrag; }
3785  QCP::PlottingHints plottingHints() const { return mPlottingHints; }
3786  Qt::KeyboardModifier multiSelectModifier() const { return mMultiSelectModifier; }
3787  QCP::SelectionRectMode selectionRectMode() const { return mSelectionRectMode; }
3788  QCPSelectionRect *selectionRect() const { return mSelectionRect; }
3789  bool openGl() const { return mOpenGl; }
3790 
3791  // setters:
3792  void setViewport(const QRect &rect);
3793  void setBufferDevicePixelRatio(double ratio);
3794  void setBackground(const QPixmap &pm);
3795  void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding);
3796  void setBackground(const QBrush &brush);
3797  void setBackgroundScaled(bool scaled);
3798  void setBackgroundScaledMode(Qt::AspectRatioMode mode);
3799  void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements);
3800  void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true);
3801  void setNotAntialiasedElements(const QCP::AntialiasedElements &notAntialiasedElements);
3802  void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true);
3803  void setAutoAddPlottableToLegend(bool on);
3804  void setInteractions(const QCP::Interactions &interactions);
3805  void setInteraction(const QCP::Interaction &interaction, bool enabled=true);
3806  void setSelectionTolerance(int pixels);
3807  void setNoAntialiasingOnDrag(bool enabled);
3808  void setPlottingHints(const QCP::PlottingHints &hints);
3809  void setPlottingHint(QCP::PlottingHint hint, bool enabled=true);
3810  void setMultiSelectModifier(Qt::KeyboardModifier modifier);
3811  void setSelectionRectMode(QCP::SelectionRectMode mode);
3812  void setSelectionRect(QCPSelectionRect *selectionRect);
3813  void setOpenGl(bool enabled, int multisampling=16);
3814 
3815  // non-property methods:
3816  // plottable interface:
3817  QCPAbstractPlottable *plottable(int index);
3818  QCPAbstractPlottable *plottable();
3819  bool removePlottable(QCPAbstractPlottable *plottable);
3820  bool removePlottable(int index);
3821  int clearPlottables();
3822  int plottableCount() const;
3823  QList<QCPAbstractPlottable*> selectedPlottables() const;
3824  template<class PlottableType>
3825  PlottableType *plottableAt(const QPointF &pos, bool onlySelectable=false, int *dataIndex=nullptr) const;
3826  QCPAbstractPlottable *plottableAt(const QPointF &pos, bool onlySelectable=false, int *dataIndex=nullptr) const;
3827  bool hasPlottable(QCPAbstractPlottable *plottable) const;
3828 
3829  // specialized interface for QCPGraph:
3830  QCPGraph *graph(int index) const;
3831  QCPGraph *graph() const;
3832  QCPGraph *addGraph(QCPAxis *keyAxis=nullptr, QCPAxis *valueAxis=nullptr);
3833  bool removeGraph(QCPGraph *graph);
3834  bool removeGraph(int index);
3835  int clearGraphs();
3836  int graphCount() const;
3837  QList<QCPGraph*> selectedGraphs() const;
3838 
3839  // item interface:
3840  QCPAbstractItem *item(int index) const;
3841  QCPAbstractItem *item() const;
3842  bool removeItem(QCPAbstractItem *item);
3843  bool removeItem(int index);
3844  int clearItems();
3845  int itemCount() const;
3846  QList<QCPAbstractItem*> selectedItems() const;
3847  template<class ItemType>
3848  ItemType *itemAt(const QPointF &pos, bool onlySelectable=false) const;
3849  QCPAbstractItem *itemAt(const QPointF &pos, bool onlySelectable=false) const;
3850  bool hasItem(QCPAbstractItem *item) const;
3851 
3852  // layer interface:
3853  QCPLayer *layer(const QString &name) const;
3854  QCPLayer *layer(int index) const;
3855  QCPLayer *currentLayer() const;
3856  bool setCurrentLayer(const QString &name);
3857  bool setCurrentLayer(QCPLayer *layer);
3858  int layerCount() const;
3859  bool addLayer(const QString &name, QCPLayer *otherLayer=nullptr, LayerInsertMode insertMode=limAbove);
3860  bool removeLayer(QCPLayer *layer);
3861  bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove);
3862 
3863  // axis rect/layout interface:
3864  int axisRectCount() const;
3865  QCPAxisRect* axisRect(int index=0) const;
3866  QList<QCPAxisRect*> axisRects() const;
3867  QCPLayoutElement* layoutElementAt(const QPointF &pos) const;
3868  QCPAxisRect* axisRectAt(const QPointF &pos) const;
3869  Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false);
3870 
3871  QList<QCPAxis*> selectedAxes() const;
3872  QList<QCPLegend*> selectedLegends() const;
3873  Q_SLOT void deselectAll();
3874 
3875  bool savePdf(const QString &fileName, int width=0, int height=0, QCP::ExportPen exportPen=QCP::epAllowCosmetic, const QString &pdfCreator=QString(), const QString &pdfTitle=QString());
3876  bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch);
3877  bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch);
3878  bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch);
3879  bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch);
3880  QPixmap toPixmap(int width=0, int height=0, double scale=1.0);
3881  void toPainter(QCPPainter *painter, int width=0, int height=0);
3882  Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpRefreshHint);
3883  double replotTime(bool average=false) const;
3884 
3885  QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2;
3887 
3888 signals:
3889  void mouseDoubleClick(QMouseEvent *event);
3890  void mousePress(QMouseEvent *event);
3891  void mouseMove(QMouseEvent *event);
3892  void mouseRelease(QMouseEvent *event);
3893  void mouseWheel(QWheelEvent *event);
3894 
3895  void plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event);
3896  void plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event);
3897  void itemClick(QCPAbstractItem *item, QMouseEvent *event);
3898  void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event);
3899  void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event);
3900  void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event);
3901  void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event);
3902  void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event);
3903 
3904  void selectionChangedByUser();
3905  void beforeReplot();
3906  void afterLayout();
3907  void afterReplot();
3908 
3909 protected:
3910  // property members:
3911  QRect mViewport;
3912  double mBufferDevicePixelRatio;
3913  QCPLayoutGrid *mPlotLayout;
3914  bool mAutoAddPlottableToLegend;
3915  QList<QCPAbstractPlottable*> mPlottables;
3916  QList<QCPGraph*> mGraphs; // extra list of plottables also in mPlottables that are of type QCPGraph
3917  QList<QCPAbstractItem*> mItems;
3918  QList<QCPLayer*> mLayers;
3919  QCP::AntialiasedElements mAntialiasedElements, mNotAntialiasedElements;
3920  QCP::Interactions mInteractions;
3921  int mSelectionTolerance;
3922  bool mNoAntialiasingOnDrag;
3923  QBrush mBackgroundBrush;
3924  QPixmap mBackgroundPixmap;
3925  QPixmap mScaledBackgroundPixmap;
3926  bool mBackgroundScaled;
3927  Qt::AspectRatioMode mBackgroundScaledMode;
3928  QCPLayer *mCurrentLayer;
3929  QCP::PlottingHints mPlottingHints;
3930  Qt::KeyboardModifier mMultiSelectModifier;
3931  QCP::SelectionRectMode mSelectionRectMode;
3932  QCPSelectionRect *mSelectionRect;
3933  bool mOpenGl;
3934 
3935  // non-property members:
3937  QPoint mMousePressPos;
3938  bool mMouseHasMoved;
3939  QPointer<QCPLayerable> mMouseEventLayerable;
3940  QPointer<QCPLayerable> mMouseSignalLayerable;
3941  QVariant mMouseEventLayerableDetails;
3942  QVariant mMouseSignalLayerableDetails;
3943  bool mReplotting;
3944  bool mReplotQueued;
3945  double mReplotTime, mReplotTimeAverage;
3946  int mOpenGlMultisamples;
3947  QCP::AntialiasedElements mOpenGlAntialiasedElementsBackup;
3948  bool mOpenGlCacheLabelsBackup;
3949 #ifdef QCP_OPENGL_FBO
3950  QSharedPointer<QOpenGLContext> mGlContext;
3951  QSharedPointer<QSurface> mGlSurface;
3952  QSharedPointer<QOpenGLPaintDevice> mGlPaintDevice;
3953 #endif
3954 
3955  // reimplemented virtual methods:
3956  virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE;
3957  virtual QSize sizeHint() const Q_DECL_OVERRIDE;
3958  virtual void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
3959  virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
3960  virtual bool event( QEvent *event ) override;
3961  virtual void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
3962  virtual void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
3963  virtual void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
3964  virtual void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
3965  virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
3966 
3967  // introduced virtual methods:
3968  virtual void draw(QCPPainter *painter);
3969  virtual void updateLayout();
3970  virtual void axisRemoved(QCPAxis *axis);
3971  virtual void legendRemoved(QCPLegend *legend);
3972  Q_SLOT virtual void processRectSelection(QRect rect, QMouseEvent *event);
3973  Q_SLOT virtual void processRectZoom(QRect rect, QMouseEvent *event);
3974  Q_SLOT virtual void processPointSelection(QMouseEvent *event);
3975 
3976  // non-virtual methods:
3977  bool registerPlottable(QCPAbstractPlottable *plottable);
3978  bool registerGraph(QCPGraph *graph);
3979  bool registerItem(QCPAbstractItem* item);
3980  void updateLayerIndices() const;
3981  QCPLayerable *layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=nullptr) const;
3982  QList<QCPLayerable*> layerableListAt(const QPointF &pos, bool onlySelectable, QList<QVariant> *selectionDetails=nullptr) const;
3983  void drawBackground(QCPPainter *painter);
3984  void setupPaintBuffers();
3985  QCPAbstractPaintBuffer *createPaintBuffer();
3986  bool hasInvalidatedPaintBuffers();
3987  bool setupOpenGl();
3988  void freeOpenGl();
3989 
3990  friend class QCPLegend;
3991  friend class QCPAxis;
3992  friend class QCPLayer;
3993  friend class QCPAxisRect;
3994  friend class QCPAbstractPlottable;
3995  friend class QCPGraph;
3996  friend class QCPAbstractItem;
3997 };
3998 Q_DECLARE_METATYPE(QCustomPlot::LayerInsertMode)
3999 Q_DECLARE_METATYPE(QCustomPlot::RefreshPriority)
4000 
4001 
4002 // implementation of template functions:
4003 
4004 /*!
4005  Returns the plottable at the pixel position \a pos. The plottable type (a QCPAbstractPlottable
4006  subclass) that shall be taken into consideration can be specified via the template parameter.
4007 
4008  Plottables that only consist of single lines (like graphs) have a tolerance band around them, see
4009  \ref setSelectionTolerance. If multiple plottables come into consideration, the one closest to \a
4010  pos is returned.
4011 
4012  If \a onlySelectable is true, only plottables that are selectable
4013  (QCPAbstractPlottable::setSelectable) are considered.
4014 
4015  if \a dataIndex is non-null, it is set to the index of the plottable's data point that is closest
4016  to \a pos.
4017 
4018  If there is no plottable of the specified type at \a pos, returns \c nullptr.
4019 
4020  \see itemAt, layoutElementAt
4021 */
4022 template<class PlottableType>
4023 PlottableType *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable, int *dataIndex) const
4024 {
4025  PlottableType *resultPlottable = 0;
4026  QVariant resultDetails;
4027  double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value
4028 
4029  foreach (QCPAbstractPlottable *plottable, mPlottables)
4030  {
4031  PlottableType *currentPlottable = qobject_cast<PlottableType*>(plottable);
4032  if (!currentPlottable || (onlySelectable && !currentPlottable->selectable())) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPAbstractPlottable::selectable
4033  continue;
4034  if (currentPlottable->clipRect().contains(pos.toPoint())) // only consider clicks where the plottable is actually visible
4035  {
4036  QVariant details;
4037  double currentDistance = currentPlottable->selectTest(pos, false, dataIndex ? &details : nullptr);
4038  if (currentDistance >= 0 && currentDistance < resultDistance)
4039  {
4040  resultPlottable = currentPlottable;
4041  resultDetails = details;
4042  resultDistance = currentDistance;
4043  }
4044  }
4045  }
4046 
4047  if (resultPlottable && dataIndex)
4048  {
4049  QCPDataSelection sel = resultDetails.value<QCPDataSelection>();
4050  if (!sel.isEmpty())
4051  *dataIndex = sel.dataRange(0).begin();
4052  }
4053  return resultPlottable;
4054 }
4055 
4056 /*!
4057  Returns the item at the pixel position \a pos. The item type (a QCPAbstractItem subclass) that shall be
4058  taken into consideration can be specified via the template parameter. Items that only consist of single
4059  lines (e.g. \ref QCPItemLine or \ref QCPItemCurve) have a tolerance band around them, see \ref
4060  setSelectionTolerance. If multiple items come into consideration, the one closest to \a pos is returned.
4061 
4062  If \a onlySelectable is true, only items that are selectable (QCPAbstractItem::setSelectable) are
4063  considered.
4064 
4065  If there is no item at \a pos, returns \c nullptr.
4066 
4067  \see plottableAt, layoutElementAt
4068 */
4069 template<class ItemType>
4070 ItemType *QCustomPlot::itemAt(const QPointF &pos, bool onlySelectable) const
4071 {
4072  ItemType *resultItem = 0;
4073  double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value
4074 
4075  foreach (QCPAbstractItem *item, mItems)
4076  {
4077  ItemType *currentItem = qobject_cast<ItemType*>(item);
4078  if (!currentItem || (onlySelectable && !currentItem->selectable())) // we could have also passed onlySelectable to the selectTest function, but checking here is faster, because we have access to QCPAbstractItem::selectable
4079  continue;
4080  if (!currentItem->clipToAxisRect() || currentItem->clipRect().contains(pos.toPoint())) // only consider clicks inside axis cliprect of the item if actually clipped to it
4081  {
4082  double currentDistance = currentItem->selectTest(pos, false);
4083  if (currentDistance >= 0 && currentDistance < resultDistance)
4084  {
4085  resultItem = currentItem;
4086  resultDistance = currentDistance;
4087  }
4088  }
4089  }
4090 
4091  return resultItem;
4092 }
4093 
4094 
4095 
4096 /* end of 'src/core.h' */
4097 
4098 
4099 /* including file 'src/plottable1d.h' */
4100 /* modified 2021-03-29T02:30:44, size 25638 */
4101 
4103 {
4104 public:
4105  virtual ~QCPPlottableInterface1D() = default;
4106  // introduced pure virtual methods:
4107  virtual int dataCount() const = 0;
4108  virtual double dataMainKey(int index) const = 0;
4109  virtual double dataSortKey(int index) const = 0;
4110  virtual double dataMainValue(int index) const = 0;
4111  virtual QCPRange dataValueRange(int index) const = 0;
4112  virtual QPointF dataPixelPosition(int index) const = 0;
4113  virtual bool sortKeyIsMainKey() const = 0;
4114  virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const = 0;
4115  virtual int findBegin(double sortKey, bool expandedRange=true) const = 0;
4116  virtual int findEnd(double sortKey, bool expandedRange=true) const = 0;
4117 };
4118 
4119 template <class DataType>
4120 class QCPAbstractPlottable1D : public QCPAbstractPlottable, public QCPPlottableInterface1D // no QCP_LIB_DECL, template class ends up in header (cpp included below)
4121 {
4122  // No Q_OBJECT macro due to template class
4123 
4124 public:
4125  QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis);
4126  virtual ~QCPAbstractPlottable1D() Q_DECL_OVERRIDE;
4127 
4128  // virtual methods of 1d plottable interface:
4129  virtual int dataCount() const Q_DECL_OVERRIDE;
4130  virtual double dataMainKey(int index) const Q_DECL_OVERRIDE;
4131  virtual double dataSortKey(int index) const Q_DECL_OVERRIDE;
4132  virtual double dataMainValue(int index) const Q_DECL_OVERRIDE;
4133  virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE;
4134  virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE;
4135  virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE;
4136  virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE;
4137  virtual int findBegin(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE;
4138  virtual int findEnd(double sortKey, bool expandedRange=true) const Q_DECL_OVERRIDE;
4139 
4140  // reimplemented virtual methods:
4141  virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
4142  virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; }
4143 
4144 protected:
4145  // property members:
4147 
4148  // helpers for subclasses:
4149  void getDataSegments(QList<QCPDataRange> &selectedSegments, QList<QCPDataRange> &unselectedSegments) const;
4150  void drawPolyline(QCPPainter *painter, const QVector<QPointF> &lineData) const;
4151 
4152 private:
4154 
4155 };
4156 
4157 
4158 
4159 // include implementation in header since it is a class template:
4160 ////////////////////////////////////////////////////////////////////////////////////////////////////
4161 //////////////////// QCPPlottableInterface1D
4162 ////////////////////////////////////////////////////////////////////////////////////////////////////
4163 
4164 /*! \class QCPPlottableInterface1D
4165  \brief Defines an abstract interface for one-dimensional plottables
4166 
4167  This class contains only pure virtual methods which define a common interface to the data
4168  of one-dimensional plottables.
4169 
4170  For example, it is implemented by the template class \ref QCPAbstractPlottable1D (the preferred
4171  base class for one-dimensional plottables). So if you use that template class as base class of
4172  your one-dimensional plottable, you won't have to care about implementing the 1d interface
4173  yourself.
4174 
4175  If your plottable doesn't derive from \ref QCPAbstractPlottable1D but still wants to provide a 1d
4176  interface (e.g. like \ref QCPErrorBars does), you should inherit from both \ref
4177  QCPAbstractPlottable and \ref QCPPlottableInterface1D and accordingly reimplement the pure
4178  virtual methods of the 1d interface, matching your data container. Also, reimplement \ref
4179  QCPAbstractPlottable::interface1D to return the \c this pointer.
4180 
4181  If you have a \ref QCPAbstractPlottable pointer, you can check whether it implements this
4182  interface by calling \ref QCPAbstractPlottable::interface1D and testing it for a non-zero return
4183  value. If it indeed implements this interface, you may use it to access the plottable's data
4184  without needing to know the exact type of the plottable or its data point type.
4185 */
4186 
4187 /* start documentation of pure virtual functions */
4188 
4189 /*! \fn virtual int QCPPlottableInterface1D::dataCount() const = 0;
4190 
4191  Returns the number of data points of the plottable.
4192 */
4193 
4194 /*! \fn virtual QCPDataSelection QCPPlottableInterface1D::selectTestRect(const QRectF &rect, bool onlySelectable) const = 0;
4195 
4196  Returns a data selection containing all the data points of this plottable which are contained (or
4197  hit by) \a rect. This is used mainly in the selection rect interaction for data selection (\ref
4198  dataselection "data selection mechanism").
4199 
4200  If \a onlySelectable is true, an empty QCPDataSelection is returned if this plottable is not
4201  selectable (i.e. if \ref QCPAbstractPlottable::setSelectable is \ref QCP::stNone).
4202 
4203  \note \a rect must be a normalized rect (positive or zero width and height). This is especially
4204  important when using the rect of \ref QCPSelectionRect::accepted, which is not necessarily
4205  normalized. Use <tt>QRect::normalized()</tt> when passing a rect which might not be normalized.
4206 */
4207 
4208 /*! \fn virtual double QCPPlottableInterface1D::dataMainKey(int index) const = 0
4209 
4210  Returns the main key of the data point at the given \a index.
4211 
4212  What the main key is, is defined by the plottable's data type. See the \ref
4213  qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4214  convention.
4215 */
4216 
4217 /*! \fn virtual double QCPPlottableInterface1D::dataSortKey(int index) const = 0
4218 
4219  Returns the sort key of the data point at the given \a index.
4220 
4221  What the sort key is, is defined by the plottable's data type. See the \ref
4222  qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4223  convention.
4224 */
4225 
4226 /*! \fn virtual double QCPPlottableInterface1D::dataMainValue(int index) const = 0
4227 
4228  Returns the main value of the data point at the given \a index.
4229 
4230  What the main value is, is defined by the plottable's data type. See the \ref
4231  qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4232  convention.
4233 */
4234 
4235 /*! \fn virtual QCPRange QCPPlottableInterface1D::dataValueRange(int index) const = 0
4236 
4237  Returns the value range of the data point at the given \a index.
4238 
4239  What the value range is, is defined by the plottable's data type. See the \ref
4240  qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4241  convention.
4242 */
4243 
4244 /*! \fn virtual QPointF QCPPlottableInterface1D::dataPixelPosition(int index) const = 0
4245 
4246  Returns the pixel position on the widget surface at which the data point at the given \a index
4247  appears.
4248 
4249  Usually this corresponds to the point of \ref dataMainKey/\ref dataMainValue, in pixel
4250  coordinates. However, depending on the plottable, this might be a different apparent position
4251  than just a coord-to-pixel transform of those values. For example, \ref QCPBars apparent data
4252  values can be shifted depending on their stacking, bar grouping or configured base value.
4253 */
4254 
4255 /*! \fn virtual bool QCPPlottableInterface1D::sortKeyIsMainKey() const = 0
4256 
4257  Returns whether the sort key (\ref dataSortKey) is identical to the main key (\ref dataMainKey).
4258 
4259  What the sort and main keys are, is defined by the plottable's data type. See the \ref
4260  qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4261  convention.
4262 */
4263 
4264 /*! \fn virtual int QCPPlottableInterface1D::findBegin(double sortKey, bool expandedRange) const = 0
4265 
4266  Returns the index of the data point with a (sort-)key that is equal to, just below, or just above
4267  \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be considered,
4268  otherwise the one just above.
4269 
4270  This can be used in conjunction with \ref findEnd to iterate over data points within a given key
4271  range, including or excluding the bounding data points that are just beyond the specified range.
4272 
4273  If \a expandedRange is true but there are no data points below \a sortKey, 0 is returned.
4274 
4275  If the container is empty, returns 0 (in that case, \ref findEnd will also return 0, so a loop
4276  using these methods will not iterate over the index 0).
4277 
4278  \see findEnd, QCPDataContainer::findBegin
4279 */
4280 
4281 /*! \fn virtual int QCPPlottableInterface1D::findEnd(double sortKey, bool expandedRange) const = 0
4282 
4283  Returns the index one after the data point with a (sort-)key that is equal to, just above, or
4284  just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey will be
4285  considered, otherwise the one just below.
4286 
4287  This can be used in conjunction with \ref findBegin to iterate over data points within a given
4288  key range, including the bounding data points that are just below and above the specified range.
4289 
4290  If \a expandedRange is true but there are no data points above \a sortKey, the index just above the
4291  highest data point is returned.
4292 
4293  If the container is empty, returns 0.
4294 
4295  \see findBegin, QCPDataContainer::findEnd
4296 */
4297 
4298 /* end documentation of pure virtual functions */
4299 
4300 
4301 ////////////////////////////////////////////////////////////////////////////////////////////////////
4302 //////////////////// QCPAbstractPlottable1D
4303 ////////////////////////////////////////////////////////////////////////////////////////////////////
4304 
4305 /*! \class QCPAbstractPlottable1D
4306  \brief A template base class for plottables with one-dimensional data
4307 
4308  This template class derives from \ref QCPAbstractPlottable and from the abstract interface \ref
4309  QCPPlottableInterface1D. It serves as a base class for all one-dimensional data (i.e. data with
4310  one key dimension), such as \ref QCPGraph and QCPCurve.
4311 
4312  The template parameter \a DataType is the type of the data points of this plottable (e.g. \ref
4313  QCPGraphData or \ref QCPCurveData). The main purpose of this base class is to provide the member
4314  \a mDataContainer (a shared pointer to a \ref QCPDataContainer "QCPDataContainer<DataType>") and
4315  implement the according virtual methods of the \ref QCPPlottableInterface1D, such that most
4316  subclassed plottables don't need to worry about this anymore.
4317 
4318  Further, it provides a convenience method for retrieving selected/unselected data segments via
4319  \ref getDataSegments. This is useful when subclasses implement their \ref draw method and need to
4320  draw selected segments with a different pen/brush than unselected segments (also see \ref
4321  QCPSelectionDecorator).
4322 
4323  This class implements basic functionality of \ref QCPAbstractPlottable::selectTest and \ref
4324  QCPPlottableInterface1D::selectTestRect, assuming point-like data points, based on the 1D data
4325  interface. In spite of that, most plottable subclasses will want to reimplement those methods
4326  again, to provide a more accurate hit test based on their specific data visualization geometry.
4327 */
4328 
4329 /* start documentation of inline functions */
4330 
4331 /*! \fn QCPPlottableInterface1D *QCPAbstractPlottable1D::interface1D()
4332 
4333  Returns a \ref QCPPlottableInterface1D pointer to this plottable, providing access to its 1D
4334  interface.
4335 
4336  \seebaseclassmethod
4337 */
4338 
4339 /* end documentation of inline functions */
4340 
4341 /*!
4342  Forwards \a keyAxis and \a valueAxis to the \ref QCPAbstractPlottable::QCPAbstractPlottable
4343  "QCPAbstractPlottable" constructor and allocates the \a mDataContainer.
4344 */
4345 template <class DataType>
4347  QCPAbstractPlottable(keyAxis, valueAxis),
4348  mDataContainer(new QCPDataContainer<DataType>)
4349 {
4350 }
4351 
4352 template <class DataType>
4354 {
4355 }
4356 
4357 /*!
4358  \copydoc QCPPlottableInterface1D::dataCount
4359 */
4360 template <class DataType>
4362 {
4363  return mDataContainer->size();
4364 }
4365 
4366 /*!
4367  \copydoc QCPPlottableInterface1D::dataMainKey
4368 */
4369 template <class DataType>
4371 {
4372  if (index >= 0 && index < mDataContainer->size())
4373  {
4374  return (mDataContainer->constBegin()+index)->mainKey();
4375  } else
4376  {
4377  qDebug() << Q_FUNC_INFO << "Index out of bounds" << index;
4378  return 0;
4379  }
4380 }
4381 
4382 /*!
4383  \copydoc QCPPlottableInterface1D::dataSortKey
4384 */
4385 template <class DataType>
4387 {
4388  if (index >= 0 && index < mDataContainer->size())
4389  {
4390  return (mDataContainer->constBegin()+index)->sortKey();
4391  } else
4392  {
4393  qDebug() << Q_FUNC_INFO << "Index out of bounds" << index;
4394  return 0;
4395  }
4396 }
4397 
4398 /*!
4399  \copydoc QCPPlottableInterface1D::dataMainValue
4400 */
4401 template <class DataType>
4403 {
4404  if (index >= 0 && index < mDataContainer->size())
4405  {
4406  return (mDataContainer->constBegin()+index)->mainValue();
4407  } else
4408  {
4409  qDebug() << Q_FUNC_INFO << "Index out of bounds" << index;
4410  return 0;
4411  }
4412 }
4413 
4414 /*!
4415  \copydoc QCPPlottableInterface1D::dataValueRange
4416 */
4417 template <class DataType>
4419 {
4420  if (index >= 0 && index < mDataContainer->size())
4421  {
4422  return (mDataContainer->constBegin()+index)->valueRange();
4423  } else
4424  {
4425  qDebug() << Q_FUNC_INFO << "Index out of bounds" << index;
4426  return QCPRange(0, 0);
4427  }
4428 }
4429 
4430 /*!
4431  \copydoc QCPPlottableInterface1D::dataPixelPosition
4432 */
4433 template <class DataType>
4435 {
4436  if (index >= 0 && index < mDataContainer->size())
4437  {
4438  const typename QCPDataContainer<DataType>::const_iterator it = mDataContainer->constBegin()+index;
4439  return coordsToPixels(it->mainKey(), it->mainValue());
4440  } else
4441  {
4442  qDebug() << Q_FUNC_INFO << "Index out of bounds" << index;
4443  return QPointF();
4444  }
4445 }
4446 
4447 /*!
4448  \copydoc QCPPlottableInterface1D::sortKeyIsMainKey
4449 */
4450 template <class DataType>
4452 {
4453  return DataType::sortKeyIsMainKey();
4454 }
4455 
4456 /*!
4457  Implements a rect-selection algorithm assuming the data (accessed via the 1D data interface) is
4458  point-like. Most subclasses will want to reimplement this method again, to provide a more
4459  accurate hit test based on the true data visualization geometry.
4460 
4461  \seebaseclassmethod
4462 */
4463 template <class DataType>
4465 {
4466  QCPDataSelection result;
4467  if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty())
4468  return result;
4469  if (!mKeyAxis || !mValueAxis)
4470  return result;
4471 
4472  // convert rect given in pixels to ranges given in plot coordinates:
4473  double key1, value1, key2, value2;
4474  pixelsToCoords(rect.topLeft(), key1, value1);
4475  pixelsToCoords(rect.bottomRight(), key2, value2);
4476  QCPRange keyRange(key1, key2); // QCPRange normalizes internally so we don't have to care about whether key1 < key2
4477  QCPRange valueRange(value1, value2);
4478  typename QCPDataContainer<DataType>::const_iterator begin = mDataContainer->constBegin();
4479  typename QCPDataContainer<DataType>::const_iterator end = mDataContainer->constEnd();
4480  if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval:
4481  {
4482  begin = mDataContainer->findBegin(keyRange.lower, false);
4483  end = mDataContainer->findEnd(keyRange.upper, false);
4484  }
4485  if (begin == end)
4486  return result;
4487 
4488  int currentSegmentBegin = -1; // -1 means we're currently not in a segment that's contained in rect
4489  for (typename QCPDataContainer<DataType>::const_iterator it=begin; it!=end; ++it)
4490  {
4491  if (currentSegmentBegin == -1)
4492  {
4493  if (valueRange.contains(it->mainValue()) && keyRange.contains(it->mainKey())) // start segment
4494  currentSegmentBegin = int(it-mDataContainer->constBegin());
4495  } else if (!valueRange.contains(it->mainValue()) || !keyRange.contains(it->mainKey())) // segment just ended
4496  {
4497  result.addDataRange(QCPDataRange(currentSegmentBegin, int(it-mDataContainer->constBegin())), false);
4498  currentSegmentBegin = -1;
4499  }
4500  }
4501  // process potential last segment:
4502  if (currentSegmentBegin != -1)
4503  result.addDataRange(QCPDataRange(currentSegmentBegin, int(end-mDataContainer->constBegin())), false);
4504 
4505  result.simplify();
4506  return result;
4507 }
4508 
4509 /*!
4510  \copydoc QCPPlottableInterface1D::findBegin
4511 */
4512 template <class DataType>
4513 int QCPAbstractPlottable1D<DataType>::findBegin(double sortKey, bool expandedRange) const
4514 {
4515  return int(mDataContainer->findBegin(sortKey, expandedRange)-mDataContainer->constBegin());
4516 }
4517 
4518 /*!
4519  \copydoc QCPPlottableInterface1D::findEnd
4520 */
4521 template <class DataType>
4522 int QCPAbstractPlottable1D<DataType>::findEnd(double sortKey, bool expandedRange) const
4523 {
4524  return int(mDataContainer->findEnd(sortKey, expandedRange)-mDataContainer->constBegin());
4525 }
4526 
4527 /*!
4528  Implements a point-selection algorithm assuming the data (accessed via the 1D data interface) is
4529  point-like. Most subclasses will want to reimplement this method again, to provide a more
4530  accurate hit test based on the true data visualization geometry.
4531 
4532  If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data point
4533  to \a pos.
4534 
4535  \seebaseclassmethod
4536 */
4537 template <class DataType>
4538 double QCPAbstractPlottable1D<DataType>::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const
4539 {
4540  if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty())
4541  return -1;
4542  if (!mKeyAxis || !mValueAxis)
4543  return -1;
4544 
4545  QCPDataSelection selectionResult;
4546  double minDistSqr = (std::numeric_limits<double>::max)();
4547  int minDistIndex = mDataContainer->size();
4548 
4549  typename QCPDataContainer<DataType>::const_iterator begin = mDataContainer->constBegin();
4550  typename QCPDataContainer<DataType>::const_iterator end = mDataContainer->constEnd();
4551  if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval:
4552  {
4553  // determine which key range comes into question, taking selection tolerance around pos into account:
4554  double posKeyMin, posKeyMax, dummy;
4555  pixelsToCoords(pos-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy);
4556  pixelsToCoords(pos+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy);
4557  if (posKeyMin > posKeyMax)
4558  qSwap(posKeyMin, posKeyMax);
4559  begin = mDataContainer->findBegin(posKeyMin, true);
4560  end = mDataContainer->findEnd(posKeyMax, true);
4561  }
4562  if (begin == end)
4563  return -1;
4564  QCPRange keyRange(mKeyAxis->range());
4565  QCPRange valueRange(mValueAxis->range());
4566  for (typename QCPDataContainer<DataType>::const_iterator it=begin; it!=end; ++it)
4567  {
4568  const double mainKey = it->mainKey();
4569  const double mainValue = it->mainValue();
4570  if (keyRange.contains(mainKey) && valueRange.contains(mainValue)) // make sure data point is inside visible range, for speedup in cases where sort key isn't main key and we iterate over all points
4571  {
4572  const double currentDistSqr = QCPVector2D(coordsToPixels(mainKey, mainValue)-pos).lengthSquared();
4573  if (currentDistSqr < minDistSqr)
4574  {
4575  minDistSqr = currentDistSqr;
4576  minDistIndex = int(it-mDataContainer->constBegin());
4577  }
4578  }
4579  }
4580  if (minDistIndex != mDataContainer->size())
4581  selectionResult.addDataRange(QCPDataRange(minDistIndex, minDistIndex+1), false);
4582 
4583  selectionResult.simplify();
4584  if (details)
4585  details->setValue(selectionResult);
4586  return qSqrt(minDistSqr);
4587 }
4588 
4589 /*!
4590  Splits all data into selected and unselected segments and outputs them via \a selectedSegments
4591  and \a unselectedSegments, respectively.
4592 
4593  This is useful when subclasses implement their \ref draw method and need to draw selected
4594  segments with a different pen/brush than unselected segments (also see \ref
4595  QCPSelectionDecorator).
4596 
4597  \see setSelection
4598 */
4599 template <class DataType>
4601 {
4602  selectedSegments.clear();
4603  unselectedSegments.clear();
4604  if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty
4605  {
4606  if (selected())
4607  selectedSegments << QCPDataRange(0, dataCount());
4608  else
4609  unselectedSegments << QCPDataRange(0, dataCount());
4610  } else
4611  {
4612  QCPDataSelection sel(selection());
4613  sel.simplify();
4614  selectedSegments = sel.dataRanges();
4615  unselectedSegments = sel.inverse(QCPDataRange(0, dataCount())).dataRanges();
4616  }
4617 }
4618 
4619 /*!
4620  A helper method which draws a line with the passed \a painter, according to the pixel data in \a
4621  lineData. NaN points create gaps in the line, as expected from QCustomPlot's plottables (this is
4622  the main difference to QPainter's regular drawPolyline, which handles NaNs by lagging or
4623  crashing).
4624 
4625  Further it uses a faster line drawing technique based on \ref QCPPainter::drawLine rather than \c
4626  QPainter::drawPolyline if the configured \ref QCustomPlot::setPlottingHints() and \a painter
4627  style allows.
4628 */
4629 template <class DataType>
4631 {
4632  // if drawing lines in plot (instead of PDF), reduce 1px lines to cosmetic, because at least in
4633  // Qt6 drawing of "1px" width lines is much slower even though it has same appearance apart from
4634  // High-DPI. In High-DPI cases people must set a pen width slightly larger than 1.0 to get
4635  // correct DPI scaling of width, but of course with performance penalty.
4636  if (!painter->modes().testFlag(QCPPainter::pmVectorized) &&
4637  qFuzzyCompare(painter->pen().widthF(), 1.0))
4638  {
4639  QPen newPen = painter->pen();
4640  newPen.setWidth(0);
4641  painter->setPen(newPen);
4642  }
4643 
4644  // if drawing solid line and not in PDF, use much faster line drawing instead of polyline:
4645  if (mParentPlot->plottingHints().testFlag(QCP::phFastPolylines) &&
4646  painter->pen().style() == Qt::SolidLine &&
4647  !painter->modes().testFlag(QCPPainter::pmVectorized) &&
4648  !painter->modes().testFlag(QCPPainter::pmNoCaching))
4649  {
4650  int i = 0;
4651  bool lastIsNan = false;
4652  const int lineDataSize = lineData.size();
4653  while (i < lineDataSize && (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()))) // make sure first point is not NaN
4654  ++i;
4655  ++i; // because drawing works in 1 point retrospect
4656  while (i < lineDataSize)
4657  {
4658  if (!qIsNaN(lineData.at(i).y()) && !qIsNaN(lineData.at(i).x())) // NaNs create a gap in the line
4659  {
4660  if (!lastIsNan)
4661  painter->drawLine(lineData.at(i-1), lineData.at(i));
4662  else
4663  lastIsNan = false;
4664  } else
4665  lastIsNan = true;
4666  ++i;
4667  }
4668  } else
4669  {
4670  int segmentStart = 0;
4671  int i = 0;
4672  const int lineDataSize = lineData.size();
4673  while (i < lineDataSize)
4674  {
4675  if (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()) || qIsInf(lineData.at(i).y())) // NaNs create a gap in the line. Also filter Infs which make drawPolyline block
4676  {
4677  painter->drawPolyline(lineData.constData()+segmentStart, i-segmentStart); // i, because we don't want to include the current NaN point
4678  segmentStart = i+1;
4679  }
4680  ++i;
4681  }
4682  // draw last segment:
4683  painter->drawPolyline(lineData.constData()+segmentStart, lineDataSize-segmentStart);
4684  }
4685 }
4686 
4687 
4688 /* end of 'src/plottable1d.h' */
4689 
4690 
4691 /* including file 'src/colorgradient.h' */
4692 /* modified 2021-03-29T02:30:44, size 7262 */
4693 
4694 class QCP_LIB_DECL QCPColorGradient
4695 {
4696  Q_GADGET
4697 public:
4698  /*!
4699  Defines the color spaces in which color interpolation between gradient stops can be performed.
4700 
4701  \see setColorInterpolation
4702  */
4703  enum ColorInterpolation { ciRGB ///< Color channels red, green and blue are linearly interpolated
4704  ,ciHSV ///< Color channels hue, saturation and value are linearly interpolated (The hue is interpolated over the shortest angle distance)
4705  };
4706  Q_ENUMS(ColorInterpolation)
4707 
4708  /*!
4709  Defines how NaN data points shall appear in the plot.
4710 
4711  \see setNanHandling, setNanColor
4712  */
4713  enum NanHandling { nhNone ///< NaN data points are not explicitly handled and shouldn't occur in the data (this gives slight performance improvement)
4714  ,nhLowestColor ///< NaN data points appear as the lowest color defined in this QCPColorGradient
4715  ,nhHighestColor ///< NaN data points appear as the highest color defined in this QCPColorGradient
4716  ,nhTransparent ///< NaN data points appear transparent
4717  ,nhNanColor ///< NaN data points appear as the color defined with \ref setNanColor
4718  };
4719  Q_ENUMS(NanHandling)
4720 
4721  /*!
4722  Defines the available presets that can be loaded with \ref loadPreset. See the documentation
4723  there for an image of the presets.
4724  */
4725  enum GradientPreset { gpGrayscale ///< Continuous lightness from black to white (suited for non-biased data representation)
4726  ,gpHot ///< Continuous lightness from black over firey colors to white (suited for non-biased data representation)
4727  ,gpCold ///< Continuous lightness from black over icey colors to white (suited for non-biased data representation)
4728  ,gpNight ///< Continuous lightness from black over weak blueish colors to white (suited for non-biased data representation)
4729  ,gpCandy ///< Blue over pink to white
4730  ,gpGeography ///< Colors suitable to represent different elevations on geographical maps
4731  ,gpIon ///< Half hue spectrum from black over purple to blue and finally green (creates banding illusion but allows more precise magnitude estimates)
4732  ,gpThermal ///< Colors suitable for thermal imaging, ranging from dark blue over purple to orange, yellow and white
4733  ,gpPolar ///< Colors suitable to emphasize polarity around the center, with blue for negative, black in the middle and red for positive values
4734  ,gpSpectrum ///< An approximation of the visible light spectrum (creates banding illusion but allows more precise magnitude estimates)
4735  ,gpJet ///< Hue variation similar to a spectrum, often used in numerical visualization (creates banding illusion but allows more precise magnitude estimates)
4736  ,gpHues ///< Full hue cycle, with highest and lowest color red (suitable for periodic data, such as angles and phases, see \ref setPeriodic)
4737  };
4738  Q_ENUMS(GradientPreset)
4739 
4740  QCPColorGradient();
4741  QCPColorGradient(GradientPreset preset);
4742  bool operator==(const QCPColorGradient &other) const;
4743  bool operator!=(const QCPColorGradient &other) const { return !(*this == other); }
4744 
4745  // getters:
4746  int levelCount() const { return mLevelCount; }
4747  QMap<double, QColor> colorStops() const { return mColorStops; }
4748  ColorInterpolation colorInterpolation() const { return mColorInterpolation; }
4749  NanHandling nanHandling() const { return mNanHandling; }
4750  QColor nanColor() const { return mNanColor; }
4751  bool periodic() const { return mPeriodic; }
4752 
4753  // setters:
4754  void setLevelCount(int n);
4755  void setColorStops(const QMap<double, QColor> &colorStops);
4756  void setColorStopAt(double position, const QColor &color);
4757  void setColorInterpolation(ColorInterpolation interpolation);
4758  void setNanHandling(NanHandling handling);
4759  void setNanColor(const QColor &color);
4760  void setPeriodic(bool enabled);
4761 
4762  // non-property methods:
4763  void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false);
4764  void colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false);
4765  QRgb color(double position, const QCPRange &range, bool logarithmic=false);
4766  void loadPreset(GradientPreset preset);
4767  void clearColorStops();
4768  QCPColorGradient inverted() const;
4769 
4770 protected:
4771  // property members:
4772  int mLevelCount;
4773  QMap<double, QColor> mColorStops;
4774  ColorInterpolation mColorInterpolation;
4775  NanHandling mNanHandling;
4776  QColor mNanColor;
4777  bool mPeriodic;
4778 
4779  // non-property members:
4780  QVector<QRgb> mColorBuffer; // have colors premultiplied with alpha (for usage with QImage::Format_ARGB32_Premultiplied)
4781  bool mColorBufferInvalidated;
4782 
4783  // non-virtual methods:
4784  bool stopsUseAlpha() const;
4785  void updateColorBuffer();
4786 };
4787 Q_DECLARE_METATYPE(QCPColorGradient::ColorInterpolation)
4788 Q_DECLARE_METATYPE(QCPColorGradient::NanHandling)
4789 Q_DECLARE_METATYPE(QCPColorGradient::GradientPreset)
4790 
4791 /* end of 'src/colorgradient.h' */
4792 
4793 
4794 /* including file 'src/selectiondecorator-bracket.h' */
4795 /* modified 2021-03-29T02:30:44, size 4458 */
4796 
4798 {
4799  Q_GADGET
4800 public:
4801 
4802  /*!
4803  Defines which shape is drawn at the boundaries of selected data ranges.
4804 
4805  Some of the bracket styles further allow specifying a height and/or width, see \ref
4806  setBracketHeight and \ref setBracketWidth.
4807  */
4808  enum BracketStyle { bsSquareBracket ///< A square bracket is drawn.
4809  ,bsHalfEllipse ///< A half ellipse is drawn. The size of the ellipse is given by the bracket width/height properties.
4810  ,bsEllipse ///< An ellipse is drawn. The size of the ellipse is given by the bracket width/height properties.
4811  ,bsPlus ///< A plus is drawn.
4812  ,bsUserStyle ///< Start custom bracket styles at this index when subclassing and reimplementing \ref drawBracket.
4813  };
4814  Q_ENUMS(BracketStyle)
4815 
4817  virtual ~QCPSelectionDecoratorBracket() Q_DECL_OVERRIDE;
4818 
4819  // getters:
4820  QPen bracketPen() const { return mBracketPen; }
4821  QBrush bracketBrush() const { return mBracketBrush; }
4822  int bracketWidth() const { return mBracketWidth; }
4823  int bracketHeight() const { return mBracketHeight; }
4824  BracketStyle bracketStyle() const { return mBracketStyle; }
4825  bool tangentToData() const { return mTangentToData; }
4826  int tangentAverage() const { return mTangentAverage; }
4827 
4828  // setters:
4829  void setBracketPen(const QPen &pen);
4830  void setBracketBrush(const QBrush &brush);
4831  void setBracketWidth(int width);
4832  void setBracketHeight(int height);
4833  void setBracketStyle(BracketStyle style);
4834  void setTangentToData(bool enabled);
4835  void setTangentAverage(int pointCount);
4836 
4837  // introduced virtual methods:
4838  virtual void drawBracket(QCPPainter *painter, int direction) const;
4839 
4840  // virtual methods:
4841  virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection) Q_DECL_OVERRIDE;
4842 
4843 protected:
4844  // property members:
4845  QPen mBracketPen;
4846  QBrush mBracketBrush;
4847  int mBracketWidth;
4848  int mBracketHeight;
4849  BracketStyle mBracketStyle;
4850  bool mTangentToData;
4851  int mTangentAverage;
4852 
4853  // non-virtual methods:
4854  double getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const;
4855  QPointF getPixelCoordinates(const QCPPlottableInterface1D *interface1d, int dataIndex) const;
4856 
4857 };
4859 
4860 /* end of 'src/selectiondecorator-bracket.h' */
4861 
4862 
4863 /* including file 'src/layoutelements/layoutelement-axisrect.h' */
4864 /* modified 2021-03-29T02:30:44, size 7529 */
4865 
4866 class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement
4867 {
4868  Q_OBJECT
4869  /// \cond INCLUDE_QPROPERTIES
4870  Q_PROPERTY(QPixmap background READ background WRITE setBackground)
4871  Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled)
4872  Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode)
4873  Q_PROPERTY(Qt::Orientations rangeDrag READ rangeDrag WRITE setRangeDrag)
4874  Q_PROPERTY(Qt::Orientations rangeZoom READ rangeZoom WRITE setRangeZoom)
4875  /// \endcond
4876 public:
4877  explicit QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes=true);
4878  virtual ~QCPAxisRect() Q_DECL_OVERRIDE;
4879 
4880  // getters:
4881  QPixmap background() const { return mBackgroundPixmap; }
4882  QBrush backgroundBrush() const { return mBackgroundBrush; }
4883  bool backgroundScaled() const { return mBackgroundScaled; }
4884  Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; }
4885  Qt::Orientations rangeDrag() const { return mRangeDrag; }
4886  Qt::Orientations rangeZoom() const { return mRangeZoom; }
4887  QCPAxis *rangeDragAxis(Qt::Orientation orientation);
4888  QCPAxis *rangeZoomAxis(Qt::Orientation orientation);
4889  QList<QCPAxis*> rangeDragAxes(Qt::Orientation orientation);
4890  QList<QCPAxis*> rangeZoomAxes(Qt::Orientation orientation);
4891  double rangeZoomFactor(Qt::Orientation orientation);
4892 
4893  // setters:
4894  void setBackground(const QPixmap &pm);
4895  void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding);
4896  void setBackground(const QBrush &brush);
4897  void setBackgroundScaled(bool scaled);
4898  void setBackgroundScaledMode(Qt::AspectRatioMode mode);
4899  void setRangeDrag(Qt::Orientations orientations);
4900  void setRangeZoom(Qt::Orientations orientations);
4901  void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical);
4902  void setRangeDragAxes(QList<QCPAxis*> axes);
4903  void setRangeDragAxes(QList<QCPAxis*> horizontal, QList<QCPAxis*> vertical);
4904  void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical);
4905  void setRangeZoomAxes(QList<QCPAxis*> axes);
4906  void setRangeZoomAxes(QList<QCPAxis*> horizontal, QList<QCPAxis*> vertical);
4907  void setRangeZoomFactor(double horizontalFactor, double verticalFactor);
4908  void setRangeZoomFactor(double factor);
4909 
4910  // non-property methods:
4911  int axisCount(QCPAxis::AxisType type) const;
4912  QCPAxis *axis(QCPAxis::AxisType type, int index=0) const;
4913  QList<QCPAxis*> axes(QCPAxis::AxisTypes types) const;
4914  QList<QCPAxis*> axes() const;
4915  QCPAxis *addAxis(QCPAxis::AxisType type, QCPAxis *axis=nullptr);
4916  QList<QCPAxis*> addAxes(QCPAxis::AxisTypes types);
4917  bool removeAxis(QCPAxis *axis);
4918  QCPLayoutInset *insetLayout() const { return mInsetLayout; }
4919 
4920  void zoom(const QRectF &pixelRect);
4921  void zoom(const QRectF &pixelRect, const QList<QCPAxis*> &affectedAxes);
4922  void setupFullAxesBox(bool connectRanges=false);
4923  QList<QCPAbstractPlottable*> plottables() const;
4924  QList<QCPGraph*> graphs() const;
4925  QList<QCPAbstractItem*> items() const;
4926 
4927  // read-only interface imitating a QRect:
4928  int left() const { return mRect.left(); }
4929  int right() const { return mRect.right(); }
4930  int top() const { return mRect.top(); }
4931  int bottom() const { return mRect.bottom(); }
4932  int width() const { return mRect.width(); }
4933  int height() const { return mRect.height(); }
4934  QSize size() const { return mRect.size(); }
4935  QPoint topLeft() const { return mRect.topLeft(); }
4936  QPoint topRight() const { return mRect.topRight(); }
4937  QPoint bottomLeft() const { return mRect.bottomLeft(); }
4938  QPoint bottomRight() const { return mRect.bottomRight(); }
4939  QPoint center() const { return mRect.center(); }
4940 
4941  // reimplemented virtual methods:
4942  virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE;
4943  virtual QList<QCPLayoutElement*> elements(bool recursive) const Q_DECL_OVERRIDE;
4944 
4945 protected:
4946  // property members:
4947  QBrush mBackgroundBrush;
4948  QPixmap mBackgroundPixmap;
4949  QPixmap mScaledBackgroundPixmap;
4950  bool mBackgroundScaled;
4951  Qt::AspectRatioMode mBackgroundScaledMode;
4952  QCPLayoutInset *mInsetLayout;
4953  Qt::Orientations mRangeDrag, mRangeZoom;
4954  QList<QPointer<QCPAxis> > mRangeDragHorzAxis, mRangeDragVertAxis;
4955  QList<QPointer<QCPAxis> > mRangeZoomHorzAxis, mRangeZoomVertAxis;
4956  double mRangeZoomFactorHorz, mRangeZoomFactorVert;
4957 
4958  // non-property members:
4959  QList<QCPRange> mDragStartHorzRange, mDragStartVertRange;
4960  QCP::AntialiasedElements mAADragBackup, mNotAADragBackup;
4961  bool mDragging;
4963 
4964  // reimplemented virtual methods:
4965  virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
4966  virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
4967  virtual int calculateAutoMargin(QCP::MarginSide side) Q_DECL_OVERRIDE;
4968  virtual void layoutChanged() Q_DECL_OVERRIDE;
4969  // events:
4970  virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE;
4971  virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE;
4972  virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE;
4973  virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;
4974 
4975  // non-property methods:
4976  void drawBackground(QCPPainter *painter);
4977  void updateAxesOffset(QCPAxis::AxisType type);
4978 
4979 private:
4980  Q_DISABLE_COPY(QCPAxisRect)
4981 
4982  friend class QCustomPlot;
4983 };
4984 
4985 
4986 /* end of 'src/layoutelements/layoutelement-axisrect.h' */
4987 
4988 
4989 /* including file 'src/layoutelements/layoutelement-legend.h' */
4990 /* modified 2021-03-29T02:30:44, size 10425 */
4991 
4992 class QCP_LIB_DECL QCPAbstractLegendItem : public QCPLayoutElement
4993 {
4994  Q_OBJECT
4995  /// \cond INCLUDE_QPROPERTIES
4996  Q_PROPERTY(QCPLegend* parentLegend READ parentLegend)
4997  Q_PROPERTY(QFont font READ font WRITE setFont)
4998  Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor)
4999  Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont)
5000  Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor)
5001  Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectionChanged)
5002  Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectableChanged)
5003  /// \endcond
5004 public:
5005  explicit QCPAbstractLegendItem(QCPLegend *parent);
5006 
5007  // getters:
5008  QCPLegend *parentLegend() const { return mParentLegend; }
5009  QFont font() const { return mFont; }
5010  QColor textColor() const { return mTextColor; }
5011  QFont selectedFont() const { return mSelectedFont; }
5012  QColor selectedTextColor() const { return mSelectedTextColor; }
5013  bool selectable() const { return mSelectable; }
5014  bool selected() const { return mSelected; }
5015 
5016  // setters:
5017  void setFont(const QFont &font);
5018  void setTextColor(const QColor &color);
5019  void setSelectedFont(const QFont &font);
5020  void setSelectedTextColor(const QColor &color);
5021  Q_SLOT void setSelectable(bool selectable);
5022  Q_SLOT void setSelected(bool selected);
5023 
5024  // reimplemented virtual methods:
5025  virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
5026 
5027 signals:
5028  void selectionChanged(bool selected);
5029  void selectableChanged(bool selectable);
5030 
5031 protected:
5032  // property members:
5033  QCPLegend *mParentLegend;
5034  QFont mFont;
5035  QColor mTextColor;
5036  QFont mSelectedFont;
5037  QColor mSelectedTextColor;
5038  bool mSelectable, mSelected;
5039 
5040  // reimplemented virtual methods:
5041  virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE;
5042  virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE;
5043  virtual QRect clipRect() const Q_DECL_OVERRIDE;
5044  virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0;
5045  // events:
5046  virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
5047  virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE;
5048 
5049 private:
5050  Q_DISABLE_COPY(QCPAbstractLegendItem)
5051 
5052  friend class QCPLegend;
5053 };
5054 
5055 
5057 {
5058  Q_OBJECT
5059 public:
5061 
5062  // getters:
5063  QCPAbstractPlottable *plottable() { return mPlottable; }
5064 
5065 protected:
5066  // property members:
5067  QCPAbstractPlottable *mPlottable;
5068 
5069  // reimplemented virtual methods:
5070  virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE;
5071  virtual QSize minimumOuterSizeHint() const Q_DECL_OVERRIDE;
5072 
5073  // non-virtual methods:
5074  QPen getIconBorderPen() const;
5075  QColor getTextColor() const;
5076  QFont getFont() const;
5077 };
5078 
5079 
5080 class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid
5081 {
5082  Q_OBJECT
5083  /// \cond INCLUDE_QPROPERTIES
5084  Q_PROPERTY(QPen borderPen READ borderPen WRITE setBorderPen)
5085  Q_PROPERTY(QBrush brush READ brush WRITE setBrush)
5086  Q_PROPERTY(QFont font READ font WRITE setFont)
5087  Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor)
5088  Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize)
5089  Q_PROPERTY(int iconTextPadding READ iconTextPadding WRITE setIconTextPadding)
5090  Q_PROPERTY(QPen iconBorderPen READ iconBorderPen WRITE setIconBorderPen)
5091  Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectionChanged)
5092  Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectableChanged)
5093  Q_PROPERTY(QPen selectedBorderPen READ selectedBorderPen WRITE setSelectedBorderPen)
5094  Q_PROPERTY(QPen selectedIconBorderPen READ selectedIconBorderPen WRITE setSelectedIconBorderPen)
5095  Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush)
5096  Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont)
5097  Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor)
5098  /// \endcond
5099 public:
5100  /*!
5101  Defines the selectable parts of a legend
5102 
5103  \see setSelectedParts, setSelectableParts
5104  */
5105  enum SelectablePart { spNone = 0x000 ///< <tt>0x000</tt> None
5106  ,spLegendBox = 0x001 ///< <tt>0x001</tt> The legend box (frame)
5107  ,spItems = 0x002 ///< <tt>0x002</tt> Legend items individually (see \ref selectedItems)
5108  };
5109  Q_ENUMS(SelectablePart)
5110  Q_FLAGS(SelectableParts)
5111  Q_DECLARE_FLAGS(SelectableParts, SelectablePart)
5112 
5113  explicit QCPLegend();
5114  virtual ~QCPLegend() Q_DECL_OVERRIDE;
5115 
5116  // getters:
5117  QPen borderPen() const { return mBorderPen; }
5118  QBrush brush() const { return mBrush; }
5119  QFont font() const { return mFont; }
5120  QColor textColor() const { return mTextColor; }
5121  QSize iconSize() const { return mIconSize; }
5122  int iconTextPadding() const { return mIconTextPadding; }
5123  QPen iconBorderPen() const { return mIconBorderPen; }
5124  SelectableParts selectableParts() const { return mSelectableParts; }
5125  SelectableParts selectedParts() const;
5126  QPen selectedBorderPen() const { return mSelectedBorderPen; }
5127  QPen selectedIconBorderPen() const { return mSelectedIconBorderPen; }
5128  QBrush selectedBrush() const { return mSelectedBrush; }
5129  QFont selectedFont() const { return mSelectedFont; }
5130  QColor selectedTextColor() const { return mSelectedTextColor; }
5131 
5132  // setters:
5133  void setBorderPen(const QPen &pen);
5134  void setBrush(const QBrush &brush);
5135  void setFont(const QFont &font);
5136  void setTextColor(const QColor &color);
5137  void setIconSize(const QSize &size);
5138  void setIconSize(int width, int height);
5139  void setIconTextPadding(int padding);
5140  void setIconBorderPen(const QPen &pen);
5141  Q_SLOT void setSelectableParts(const SelectableParts &selectableParts);
5142  Q_SLOT void setSelectedParts(const SelectableParts &selectedParts);
5143  void setSelectedBorderPen(const QPen &pen);
5144  void setSelectedIconBorderPen(const QPen &pen);
5145  void setSelectedBrush(const QBrush &brush);
5146  void setSelectedFont(const QFont &font);
5147  void setSelectedTextColor(const QColor &color);
5148 
5149  // reimplemented virtual methods:
5150  virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
5151 
5152  // non-virtual methods:
5153  QCPAbstractLegendItem *item(int index) const;
5154  QCPPlottableLegendItem *itemWithPlottable(const QCPAbstractPlottable *plottable) const;
5155  int itemCount() const;
5156  bool hasItem(QCPAbstractLegendItem *item) const;
5157  bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const;
5158  bool addItem(QCPAbstractLegendItem *item);
5159  bool removeItem(int index);
5160  bool removeItem(QCPAbstractLegendItem *item);
5161  void clearItems();
5162  QList<QCPAbstractLegendItem*> selectedItems() const;
5163 
5164 signals:
5165  void selectionChanged(QCPLegend::SelectableParts parts);
5166  void selectableChanged(QCPLegend::SelectableParts parts);
5167 
5168 protected:
5169  // property members:
5170  QPen mBorderPen, mIconBorderPen;
5171  QBrush mBrush;
5172  QFont mFont;
5173