Kstars
qcustomplot.h
144 class QCP { // when in moc-run, make it look like a class, so we get Q_GADGET, Q_ENUMS/Q_FLAGS features in namespace
166 \see QCustomPlot::savePng, QCustomPlot::saveJpg, QCustomPlot::saveBmp, QCustomPlot::saveRastered
178 enum ExportPen { epNoCosmetic ///< Cosmetic pens are converted to pens with pixel width 1 when exporting
179 ,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)
209 Defines what objects of a plot can be forcibly drawn antialiased/not antialiased. If an object is
210 neither forcibly drawn antialiased nor forcibly drawn not antialiased, it is up to the respective
224 ,aeScatters = 0x0080 ///< <tt>0x0080</tt> Scatter symbols of plottables (excluding scatter symbols of type ssPixmap)
227 ,aeOther = 0x8000 ///< <tt>0x8000</tt> Other elements that don't fit into any of the existing categories
239 ,phFastPolylines = 0x001 ///< <tt>0x001</tt> Graph/Curve lines are drawn with a faster method. This reduces the quality especially of the line segment
240 ///< joins, thus is most effective for pen sizes larger than 1. It is only used for solid line pens.
241 ,phImmediateRefresh = 0x002 ///< <tt>0x002</tt> causes an immediate repaint() instead of a soft update() when QCustomPlot::replot() is called with parameter \ref QCustomPlot::rpRefreshHint.
242 ///< This is set by default to prevent the plot from freezing on fast consecutive replots (e.g. user drags ranges with mouse).
243 ,phCacheLabels = 0x004 ///< <tt>0x004</tt> axis (tick) labels will be cached as pixmaps, increasing replot performance.
255 ,iRangeDrag = 0x001 ///< <tt>0x001</tt> Axis ranges are draggable (see \ref QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeDragAxes)
256 ,iRangeZoom = 0x002 ///< <tt>0x002</tt> Axis ranges are zoomable with the mouse wheel (see \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeZoomAxes)
257 ,iMultiSelect = 0x004 ///< <tt>0x004</tt> The user can select multiple objects by holding the modifier set by \ref QCustomPlot::setMultiSelectModifier while clicking
258 ,iSelectPlottables = 0x008 ///< <tt>0x008</tt> Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable)
259 ,iSelectAxes = 0x010 ///< <tt>0x010</tt> Axes are selectable (or parts of them, see QCPAxis::setSelectableParts)
260 ,iSelectLegend = 0x020 ///< <tt>0x020</tt> Legends are selectable (or their child items, see QCPLegend::setSelectableParts)
261 ,iSelectItems = 0x040 ///< <tt>0x040</tt> Items are selectable (Rectangles, Arrows, Textitems, etc. see \ref QCPAbstractItem)
262 ,iSelectOther = 0x080 ///< <tt>0x080</tt> All other objects are selectable (e.g. your own derived layerables, other layout elements,...)
263 ,iSelectPlottablesBeyondAxisRect = 0x100 ///< <tt>0x100</tt> When performing plottable selection/hit tests, this flag extends the sensitive area beyond the axis rect
272 enum SelectionRectMode { srmNone ///< The selection rect is disabled, and all mouse events are forwarded to the underlying objects, e.g. for axis range dragging
273 ,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.
274 ,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.)
275 ,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.
297 ,stWhole ///< Selection behaves like \ref stMultipleDataRanges, but if there are any data points selected, the entire plottable is drawn as selected.
364 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
439 inline const QCPVector2D operator*(double factor, const QCPVector2D &vec) { return QCPVector2D(vec.mX*factor, vec.mY*factor); }
440 inline const QCPVector2D operator*(const QCPVector2D &vec, double factor) { return QCPVector2D(vec.mX*factor, vec.mY*factor); }
441 inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor) { return QCPVector2D(vec.mX/divisor, vec.mY/divisor); }
442 inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX+vec2.mX, vec1.mY+vec2.mY); }
443 inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX-vec2.mX, vec1.mY-vec2.mY); }
444 inline const QCPVector2D operator-(const QCPVector2D &vec) { return QCPVector2D(-vec.mX, -vec.mY); }
467 Defines special modes the painter can operate in. They disable or enable certain subsets of features/fixes/workarounds,
470 enum PainterMode { pmDefault = 0x00 ///< <tt>0x00</tt> Default mode for painting on screen devices
471 ,pmVectorized = 0x01 ///< <tt>0x01</tt> Mode for vectorized painting (e.g. PDF export). For example, this prevents some antialiasing fixes.
472 ,pmNoCaching = 0x02 ///< <tt>0x02</tt> Mode for all sorts of exports (e.g. PNG, PDF,...). For example, this prevents using cached pixmap labels
473 ,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.)
603 explicit QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer<QOpenGLContext> glContext, QWeakPointer<QOpenGLPaintDevice> glPaintDevice);
649 enum LayerMode { lmLogical ///< Layer is used only for rendering order, and shares paint buffer with all other adjacent logical layers.
650 ,lmBuffered ///< Layer has its own paint buffer and may be replotted individually (see \ref replot).
709 QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=nullptr);
726 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const;
749 virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged);
762 void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const;
786 bool operator==(const QCPRange& other) const { return lower == other.lower && upper == other.upper; }
902 bool operator==(const QCPDataRange& other) const { return mBegin == other.mBegin && mEnd == other.mEnd; }
921 QCPDataRange adjusted(int changeBegin, int changeEnd) const { return QCPDataRange(mBegin+changeBegin, mEnd+changeEnd); }
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);
949 friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b);
950 friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b);
951 friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b);
976 inline static bool lessThanDataRangeBegin(const QCPDataRange &a, const QCPDataRange &b) { return a.begin() < b.begin(); }
982 Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
993 Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
1004 Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
1015 Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
1162 QList<QCPLayoutElement*> elements(QCP::MarginSide side) const { return mChildren.value(side); }
1196 Q_PROPERTY(SizeConstraintRect sizeConstraintRect READ sizeConstraintRect WRITE setSizeConstraintRect)
1203 enum UpdatePhase { upPreparation ///< Phase used for any type of preparation that needs to be done before margin calculation and layout
1212 margins (e.g. in the case of a QCPAxisRect the axis labels), whereas the inner rect (\ref rect)
1217 enum SizeConstraintRect { scrInnerRect ///< Minimum/Maximum size constraints apply to inner rect
1218 , scrOuterRect ///< Minimum/Maximum size constraints apply to outer rect, thus include layout element margins
1235 QCPMarginGroup *marginGroup(QCP::MarginSide side) const { return mMarginGroups.value(side, nullptr); }
1257 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
1274 virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE { Q_UNUSED(painter) }
1318 QVector<int> getSectionSizes(QVector<int> maxSizes, QVector<int> minSizes, QVector<double> stretchFactors, int totalSize) const;
1334 Q_PROPERTY(QList<double> columnStretchFactors READ columnStretchFactors WRITE setColumnStretchFactors)
1350 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.
1351 ,foColumnsFirst ///< Columns are filled first, and a new element is wrapped to the next row if the column count would exceed \ref setWrap.
1426 enum InsetPlacement { ipFree ///< The element may be positioned/sized arbitrarily, see \ref setInsetRect
1427 ,ipBorderAligned ///< The element is aligned to one of the layout sides, see \ref setInsetAlignment
1451 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
1485 and \ref setLength. Some decorations like \ref esDisc, \ref esSquare, \ref esDiamond and \ref esBar only
1488 \see QCPItemLine::setHead, QCPItemLine::setTail, QCPItemCurve::setHead, QCPItemCurve::setTail, QCPAxis::setLowerEnding, QCPAxis::setUpperEnding
1498 ,esHalfBar ///< A bar perpendicular to the line, pointing out to only one side (to which side can be changed with \ref setInverted)
1625 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
1642 double mRotation; // this is the rotation applied uniformly to all labels, not the heterogeneous rotation in amCircularRotated mode
1648 QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters
1654 virtual void drawLabelMaybeCached(QCPPainter *painter, const QFont &font, const QColor &color, const QPointF &pos, AnchorSide side, double rotation, const QString &text);
1655 virtual QByteArray generateLabelParameterHash() const; // TODO: get rid of this in favor of invalidation flag upon setters?
1660 LabelData getTickLabelData(const QFont &font, const QColor &color, double rotation, AnchorSide side, const QString &text) const;
1662 //void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const;
1664 QByteArray cacheKey(const QString &text, const QColor &color, double rotation, AnchorSide side) const;
1665 AnchorSide skewedAnchorSide(const QPointF &tickPos, double sideExpandHorz, double sideExpandVert) const;
1684 Defines the strategies that the axis ticker may follow when choosing the size of the tick step.
1690 tssReadability ///< A nicely readable tick step is prioritized over matching the requested number of ticks (see \ref setTickCount)
1691 ,tssMeetTickCount ///< Less readable tick steps are allowed which in turn facilitates getting closer to the requested tick count
1709 virtual void generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector<double> &ticks, QVector<double> *subTicks, QVector<QString> *tickLabels);
1720 virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision);
1723 virtual QVector<QString> createLabelVector(const QVector<double> &ticks, const QLocale &locale, QChar formatChar, int precision);
1762 void setTickOrigin(double origin); // hides base class method but calls baseclass implementation ("using" throws off IDEs and doxygen)
1783 virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE;
1784 virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE;
1802 enum TimeUnit { tuMilliseconds ///< Milliseconds, one thousandth of a second (%%z in \ref setTimeFormat)
1832 virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE;
1855 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.
1856 ,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.
1915 virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE;
1916 virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE;
1934 enum FractionStyle { fsFloatingPoint ///< Fractions are displayed as regular decimal floating point numbers, e.g. "0.25" or "0.125".
1935 ,fsAsciiFractions ///< Fractions are written as rationals using ASCII characters only, e.g. "1/4" or "1/8"
1936 ,fsUnicodeFractions ///< Fractions are written using sub- and superscript UTF-8 digits and the fraction symbol.
1967 virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE;
2007 virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE;
2102 Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectionChanged)
2103 Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectableChanged)
2104 Q_PROPERTY(QFont selectedTickLabelFont READ selectedTickLabelFont WRITE setSelectedTickLabelFont)
2106 Q_PROPERTY(QColor selectedTickLabelColor READ selectedTickLabelColor WRITE setSelectedTickLabelColor)
2120 enum AxisType { atLeft = 0x01 ///< <tt>0x01</tt> Axis is vertical and on the left side of the axis rect
2133 enum LabelSide { lsInside ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect
2142 ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed axis coordinates (possibly also \ref setTicker to a \ref QCPAxisTickerLog instance).
2253 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
2257 int pixelOrientation() const { return rangeReversed() != (orientation()==Qt::Vertical) ? -1 : 1; }
2271 static Qt::Orientation orientation(AxisType type) { return type==atBottom || type==atTop ? Qt::Horizontal : Qt::Vertical; }
2339 virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
2399 int tickLengthIn, tickLengthOut, subTickLengthIn, subTickLengthOut; // directly accessed by QCPAxis setters/getters
2425 QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters
2431 virtual void placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize);
2432 virtual void drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const;
2435 virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const;
2474 enum ScatterShape { ssNone ///< no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines)
2475 ,ssDot ///< \enumimage{ssDot.png} a single pixel (use \ref ssDisc or \ref ssCircle if you want a round shape with a certain radius)
2479 ,ssDisc ///< \enumimage{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle)
2482 ,ssStar ///< \enumimage{ssStar.png} a star with eight arms, i.e. a combination of cross and plus
2484 ,ssTriangleInverted ///< \enumimage{ssTriangleInverted.png} an equilateral triangle, standing on corner
2489 ,ssPeace ///< \enumimage{ssPeace.png} a circle, with one vertical and two downward diagonal lines
2490 ,ssPixmap ///< a custom pixmap specified by \ref setPixmap, centered on the data point coordinates
2491 ,ssCustom ///< custom painter operations are performed per scatter (As QPainterPath, see \ref setCustomPath)
2501 QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush=Qt::NoBrush, double size=6);
2557 inline bool qcpLessThanSortKey(const DataType &a, const DataType &b) { return a.sortKey() < b.sortKey(); }
2560 class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp included below)
2598 QCPRange valueRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange());
2600 void limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const;
2619 ////////////////////////////////////////////////////////////////////////////////////////////////////
2621 ////////////////////////////////////////////////////////////////////////////////////////////////////
2626 This class template provides a fast container for data storage of one-dimensional data. The data
2630 The data is stored in a sorted fashion, which allows very quick lookups by the sorted key as well
2631 as retrieval of ranges (see \ref findBegin, \ref findEnd, \ref keyRange) using binary search. The
2635 using the fact that existing data is always sorted. The user can further improve performance by
2636 specifying that added data is already itself sorted by key, if he can guarantee that this is the
2639 The data can be accessed with the provided const iterators (\ref constBegin, \ref constEnd). If
2640 it is necessary to alter existing data in-place, the non-const iterators can be used (\ref begin,
2641 \ref end). Changing data members that are not the sort key (for most data types called \a key) is
2644 Great care must be taken however if the sort key is modified through the non-const iterators. For
2646 manipulation. It is thus the responsibility of the user to leave the container in a sorted state
2661 \li <tt>double sortKey() const</tt>\n Returns the member variable of this data point that is the
2667 \li <tt>static bool sortKeyIsMainKey()</tt>\n Returns true if the sort key is equal to the main
2668 key (see method \c mainKey below). For most plottables this is the case. It is not the case for
2669 example for \ref QCPCurve, which uses \a t as sort key and \a key as main key. This is the reason
2672 \li <tt>double mainKey() const</tt>\n Returns the variable of this data point considered the main
2673 key. This is commonly the variable that is used as the coordinate of this data point on the key
2681 \li <tt>QCPRange valueRange() const</tt>\n Returns the range this data point spans in the value
2683 both lower and upper set to the main data point value. However if the data points can represent
2685 values at each \a key) this method should return the range those values span. This method is used
2716 You can manipulate the data points in-place through the non-const iterators, but great care must
2725 You can manipulate the data points in-place through the non-const iterators, but great care must
2733 the available elements in this container, returns \ref constEnd, i.e. an iterator past the last
2826 if (oldSize > 0 && !qcpLessThanSortKey<DataType>(*constBegin(), *(data.constEnd()-1))) // prepend if new data keys are all smaller than or equal to existing ones
2836 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
2863 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
2875 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
2889 if (isEmpty() || !qcpLessThanSortKey<DataType>(data, *(constEnd()-1))) // quickly handle appends if new data key is greater or equal to existing ones
2892 } else if (qcpLessThanSortKey<DataType>(data, *constBegin())) // quickly handle prepends using preallocated space
2900 QCPDataContainer<DataType>::iterator insertionPoint = std::lower_bound(begin(), end(), data, qcpLessThanSortKey<DataType>);
2914 QCPDataContainer<DataType>::iterator itEnd = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
2915 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)
2928 QCPDataContainer<DataType>::iterator it = std::upper_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
2948 QCPDataContainer<DataType>::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKeyFrom), qcpLessThanSortKey<DataType>);
2949 QCPDataContainer<DataType>::iterator itEnd = std::upper_bound(it, end(), DataType::fromSortKey(sortKeyTo), qcpLessThanSortKey<DataType>);
2967 QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
2971 ++mPreallocSize; // don't actually delete, just add it to the preallocated block (if it gets too large, squeeze will take care of it)
2995 When setting, adding or removing points using the QCPDataContainer interface (\ref set, \ref add,
2998 points by accessing and modifying it through the non-const iterators (\ref begin, \ref end), it
2999 is your responsibility to bring the container back into a sorted state before any other methods
3016 The parameters \a preAllocation and \a postAllocation control whether pre- and/or post allocation
3041 This can be used in conjunction with \ref findEnd to iterate over data points within a given key
3042 range, including or excluding the bounding data points that are just beyond the specified range.
3052 typename QCPDataContainer<DataType>::const_iterator QCPDataContainer<DataType>::findBegin(double sortKey, bool expandedRange) const
3057 QCPDataContainer<DataType>::const_iterator it = std::lower_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
3058 if (expandedRange && it != constBegin()) // also covers it == constEnd case, and we know --constEnd is valid because mData isn't empty
3064 Returns an iterator to the element after the data point with a (sort-)key that is equal to, just
3065 above or just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey
3069 key range, including the bounding data points that are just below and above the specified range.
3079 typename QCPDataContainer<DataType>::const_iterator QCPDataContainer<DataType>::findEnd(double sortKey, bool expandedRange) const
3084 QCPDataContainer<DataType>::const_iterator it = std::upper_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
3100 If the DataType reports that its main key is equal to the sort key (\a sortKeyIsMainKey), as is
3122 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
3145 } else // DataType is not sorted by main key, go through all data points and accordingly expand range
3216 you should not use the returned QCPRange (e.g. the data container is empty or all points have the
3229 QCPRange QCPDataContainer<DataType>::valueRange(bool &foundRange, QCP::SignDomain signDomain, const QCPRange &inKeyRange)
3252 if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper))
3270 if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper))
3273 if ((current.lower < range.lower || !haveLower) && current.lower < 0 && !qIsNaN(current.lower))
3278 if ((current.upper > range.upper || !haveUpper) && current.upper < 0 && !qIsNaN(current.upper))
3288 if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper))
3291 if ((current.lower < range.lower || !haveLower) && current.lower > 0 && !qIsNaN(current.lower))
3296 if ((current.upper > range.upper || !haveUpper) && current.upper > 0 && !qIsNaN(current.upper))
3313 This function doesn't require for \a dataRange to be within the bounds of this data container's
3317 void QCPDataContainer<DataType>::limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const
3327 Increases the preallocation pool to have a size of at least \a minimumPreallocSize. Depending on
3331 if \a minimumPreallocSize is smaller than or equal to the current preallocation pool size, this
3341 newPreallocSize += (1u<<qBound(4, mPreallocIteration+4, 15)) - 12; // do 4 up to 32768-12 preallocation, doubling in each intermediate iteration
3352 This method decides, depending on the total allocation size and the size of the unused pre- and
3356 If \ref setAutoSqueeze is enabled, this method is called automatically each time data points are
3372 if (totalAlloc > 650000) // if allocation is larger, shrink earlier with respect to total used size
3374 shrinkPostAllocation = postAllocSize > usedSize*1.5; // QVector grow strategy is 2^n for static data. Watch out not to oscillate!
3376 } else if (totalAlloc > 1000) // below 10 MiB raw data be generous with preallocated memory, below 1k points don't even bother
3379 shrinkPreAllocation = mPreallocSize > usedSize*1.5; // preallocation can grow into postallocation, so can be smaller
3404 QCPScatterStyle::ScatterProperties usedScatterProperties() const { return mUsedScatterProperties; }
3409 void setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties=QCPScatterStyle::spPen);
3451 Q_PROPERTY(QCP::SelectionType selectable READ selectable WRITE setSelectable NOTIFY selectableChanged)
3452 Q_PROPERTY(QCPDataSelection selection READ selection WRITE setSelection NOTIFY selectionChanged)
3453 Q_PROPERTY(QCPSelectionDecorator* selectionDecorator READ selectionDecorator WRITE setSelectionDecorator)
3485 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
3487 virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const = 0;
3488 virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const = 0;
3525 virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
3554 QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId=-1);
3576 void removeChildX(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted
3578 void removeChildY(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted
3598 enum PositionType { ptAbsolute ///< Static positioning in pixels, starting from the top left corner of the viewport/widget.
3599 ,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
3600 ///< 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
3602 ,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
3603 ///< 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
3604 ///< 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.
3605 ,ptPlotCoords ///< Dynamic positioning at a plot coordinate defined by two axes (see \ref setAxes).
3684 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE = 0;
3711 virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
3742 Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode)
3744 Q_PROPERTY(bool autoAddPlottableToLegend READ autoAddPlottableToLegend WRITE setAutoAddPlottableToLegend)
3747 Q_PROPERTY(Qt::KeyboardModifier multiSelectModifier READ multiSelectModifier WRITE setMultiSelectModifier)
3766 enum RefreshPriority { rpImmediateRefresh ///< Replots immediately and repaints the widget immediately by calling QWidget::repaint() after the replot
3767 ,rpQueuedRefresh ///< Replots immediately, but queues the widget repaint, by calling QWidget::update() after the replot. This way multiple redundant widget repaints can be avoided.
3768 ,rpRefreshHint ///< Whether to use immediate or queued refresh depends on whether the plotting hint \ref QCP::phImmediateRefresh is set, see \ref setPlottingHints.
3769 ,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.
3799 void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding);
3806 void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true);
3829 PlottableType *plottableAt(const QPointF &pos, bool onlySelectable=false, int *dataIndex=nullptr) const;
3830 QCPAbstractPlottable *plottableAt(const QPointF &pos, bool onlySelectable=false, int *dataIndex=nullptr) const;
3863 bool addLayer(const QString &name, QCPLayer *otherLayer=nullptr, LayerInsertMode insertMode=limAbove);
3879 bool savePdf(const QString &fileName, int width=0, int height=0, QCP::ExportPen exportPen=QCP::epAllowCosmetic, const QString &pdfCreator=QString(), const QString &pdfTitle=QString());
3880 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);
3881 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);
3882 bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch);
3883 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);
3920 QList<QCPGraph*> mGraphs; // extra list of plottables also in mPlottables that are of type QCPGraph
3985 QCPLayerable *layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=nullptr) const;
3986 QList<QCPLayerable*> layerableListAt(const QPointF &pos, bool onlySelectable, QList<QVariant> *selectionDetails=nullptr) const;
4012 Plottables that only consist of single lines (like graphs) have a tolerance band around them, see
4013 \ref setSelectionTolerance. If multiple plottables come into consideration, the one closest to \a
4019 if \a dataIndex is non-null, it is set to the index of the plottable's data point that is closest
4027 PlottableType *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable, int *dataIndex) const
4031 double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value
4036 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
4038 if (currentPlottable->clipRect().contains(pos.toPoint())) // only consider clicks where the plottable is actually visible
4041 double currentDistance = currentPlottable->selectTest(pos, false, dataIndex ? &details : nullptr);
4061 Returns the item at the pixel position \a pos. The item type (a QCPAbstractItem subclass) that shall be
4062 taken into consideration can be specified via the template parameter. Items that only consist of single
4064 setSelectionTolerance. If multiple items come into consideration, the one closest to \a pos is returned.
4066 If \a onlySelectable is true, only items that are selectable (QCPAbstractItem::setSelectable) are
4077 double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value
4082 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
4084 if (!currentItem->clipToAxisRect() || currentItem->clipRect().contains(pos.toPoint())) // only consider clicks inside axis cliprect of the item if actually clipped to it
4124 class QCPAbstractPlottable1D : public QCPAbstractPlottable, public QCPPlottableInterface1D // no QCP_LIB_DECL, template class ends up in header (cpp included below)
4140 virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE;
4145 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
4153 void getDataSegments(QList<QCPDataRange> &selectedSegments, QList<QCPDataRange> &unselectedSegments) const;
4164 ////////////////////////////////////////////////////////////////////////////////////////////////////
4166 ////////////////////////////////////////////////////////////////////////////////////////////////////
4174 For example, it is implemented by the template class \ref QCPAbstractPlottable1D (the preferred
4179 If your plottable doesn't derive from \ref QCPAbstractPlottable1D but still wants to provide a 1d
4186 interface by calling \ref QCPAbstractPlottable::interface1D and testing it for a non-zero return
4198 /*! \fn virtual QCPDataSelection QCPPlottableInterface1D::selectTestRect(const QRectF &rect, bool onlySelectable) const = 0;
4200 Returns a data selection containing all the data points of this plottable which are contained (or
4201 hit by) \a rect. This is used mainly in the selection rect interaction for data selection (\ref
4207 \note \a rect must be a normalized rect (positive or zero width and height). This is especially
4209 normalized. Use <tt>QRect::normalized()</tt> when passing a rect which might not be normalized.
4217 qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4226 qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4235 qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4244 qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4261 Returns whether the sort key (\ref dataSortKey) is identical to the main key (\ref dataMainKey).
4264 qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4268 /*! \fn virtual int QCPPlottableInterface1D::findBegin(double sortKey, bool expandedRange) const = 0
4270 Returns the index of the data point with a (sort-)key that is equal to, just below, or just above
4271 \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be considered,
4274 This can be used in conjunction with \ref findEnd to iterate over data points within a given key
4275 range, including or excluding the bounding data points that are just beyond the specified range.
4285 /*! \fn virtual int QCPPlottableInterface1D::findEnd(double sortKey, bool expandedRange) const = 0
4288 just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey will be
4292 key range, including the bounding data points that are just below and above the specified range.
4294 If \a expandedRange is true but there are no data points above \a sortKey, the index just above the
4305 ////////////////////////////////////////////////////////////////////////////////////////////////////
4307 ////////////////////////////////////////////////////////////////////////////////////////////////////
4312 This template class derives from \ref QCPAbstractPlottable and from the abstract interface \ref
4313 QCPPlottableInterface1D. It serves as a base class for all one-dimensional data (i.e. data with
4317 QCPGraphData or \ref QCPCurveData). The main purpose of this base class is to provide the member
4318 \a mDataContainer (a shared pointer to a \ref QCPDataContainer "QCPDataContainer<DataType>") and
4323 \ref getDataSegments. This is useful when subclasses implement their \ref draw method and need to
4330 again, to provide a more accurate hit test based on their specific data visualization geometry.
4350 QCPAbstractPlottable1D<DataType>::QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis) :
4442 const typename QCPDataContainer<DataType>::const_iterator it = mDataContainer->constBegin()+index;
4461 Implements a rect-selection algorithm assuming the data (accessed via the 1D data interface) is
4468 QCPDataSelection QCPAbstractPlottable1D<DataType>::selectTestRect(const QRectF &rect, bool onlySelectable) const
4480 QCPRange keyRange(key1, key2); // QCPRange normalizes internally so we don't have to care about whether key1 < key2
4484 if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval:
4492 int currentSegmentBegin = -1; // -1 means we're currently not in a segment that's contained in rect
4499 } else if (!valueRange.contains(it->mainValue()) || !keyRange.contains(it->mainKey())) // segment just ended
4501 result.addDataRange(QCPDataRange(currentSegmentBegin, int(it-mDataContainer->constBegin())), false);
4507 result.addDataRange(QCPDataRange(currentSegmentBegin, int(end-mDataContainer->constBegin())), false);
4532 Implements a point-selection algorithm assuming the data (accessed via the 1D data interface) is
4536 If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data point
4542 double QCPAbstractPlottable1D<DataType>::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const
4555 if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval:
4557 // determine which key range comes into question, taking selection tolerance around pos into account:
4559 pixelsToCoords(pos-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy);
4560 pixelsToCoords(pos+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy);
4574 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
4576 const double currentDistSqr = QCPVector2D(coordsToPixels(mainKey, mainValue)-pos).lengthSquared();
4604 void QCPAbstractPlottable1D<DataType>::getDataSegments(QList<QCPDataRange> &selectedSegments, QList<QCPDataRange> &unselectedSegments) const
4608 if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty
4624 A helper method which draws a line with the passed \a painter, according to the pixel data in \a
4625 lineData. NaN points create gaps in the line, as expected from QCustomPlot's plottables (this is
4629 Further it uses a faster line drawing technique based on \ref QCPPainter::drawLine rather than \c
4634 void QCPAbstractPlottable1D<DataType>::drawPolyline(QCPPainter *painter, const QVector<QPointF> &lineData) const
4636 // if drawing lines in plot (instead of PDF), reduce 1px lines to cosmetic, because at least in
4637 // Qt6 drawing of "1px" width lines is much slower even though it has same appearance apart from
4657 while (i < lineDataSize && (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()))) // make sure first point is not NaN
4662 if (!qIsNaN(lineData.at(i).y()) && !qIsNaN(lineData.at(i).x())) // NaNs create a gap in the line
4679 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
4681 painter->drawPolyline(lineData.constData()+segmentStart, i-segmentStart); // i, because we don't want to include the current NaN point
4707 enum ColorInterpolation { ciRGB ///< Color channels red, green and blue are linearly interpolated
4708 ,ciHSV ///< Color channels hue, saturation and value are linearly interpolated (The hue is interpolated over the shortest angle distance)
4717 enum NanHandling { nhNone ///< NaN data points are not explicitly handled and shouldn't occur in the data (this gives slight performance improvement)
4718 ,nhLowestColor ///< NaN data points appear as the lowest color defined in this QCPColorGradient
4719 ,nhHighestColor ///< NaN data points appear as the highest color defined in this QCPColorGradient
4729 enum GradientPreset { gpGrayscale ///< Continuous lightness from black to white (suited for non-biased data representation)
4730 ,gpHot ///< Continuous lightness from black over firey colors to white (suited for non-biased data representation)
4731 ,gpCold ///< Continuous lightness from black over icey colors to white (suited for non-biased data representation)
4732 ,gpNight ///< Continuous lightness from black over weak blueish colors to white (suited for non-biased data representation)
4735 ,gpIon ///< Half hue spectrum from black over purple to blue and finally green (creates banding illusion but allows more precise magnitude estimates)
4736 ,gpThermal ///< Colors suitable for thermal imaging, ranging from dark blue over purple to orange, yellow and white
4737 ,gpPolar ///< Colors suitable to emphasize polarity around the center, with blue for negative, black in the middle and red for positive values
4738 ,gpSpectrum ///< An approximation of the visible light spectrum (creates banding illusion but allows more precise magnitude estimates)
4739 ,gpJet ///< Hue variation similar to a spectrum, often used in numerical visualization (creates banding illusion but allows more precise magnitude estimates)
4740 ,gpHues ///< Full hue cycle, with highest and lowest color red (suitable for periodic data, such as angles and phases, see \ref setPeriodic)
4767 void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false);
4768 void colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false);
4784 QVector<QRgb> mColorBuffer; // have colors premultiplied with alpha (for usage with QImage::Format_ARGB32_Premultiplied)
4813 ,bsHalfEllipse ///< A half ellipse is drawn. The size of the ellipse is given by the bracket width/height properties.
4814 ,bsEllipse ///< An ellipse is drawn. The size of the ellipse is given by the bracket width/height properties.
4816 ,bsUserStyle ///< Start custom bracket styles at this index when subclassing and reimplementing \ref drawBracket.
4858 double getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const;
4876 Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode)
4899 void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding);
5029 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
5050 virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
5095 Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectionChanged)
5096 Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectableChanged)
5098 Q_PROPERTY(QPen selectedIconBorderPen READ selectedIconBorderPen WRITE setSelectedIconBorderPen)
5154 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;