Kstars
qcustomplot.h
160// Qt version < 6.2.0: to get metatypes Q_GADGET/Q_ENUMS/Q_FLAGS in namespace we have to make it look like a class during moc-run
161#if QT_VERSION >= 0x060200 // don't use QT_VERSION_CHECK here, some moc versions don't understand it
193 \see QCustomPlot::savePng, QCustomPlot::saveJpg, QCustomPlot::saveBmp, QCustomPlot::saveRastered
205enum ExportPen { epNoCosmetic ///< Cosmetic pens are converted to pens with pixel width 1 when exporting
206 ,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)
236 Defines what objects of a plot can be forcibly drawn antialiased/not antialiased. If an object is
237 neither forcibly drawn antialiased nor forcibly drawn not antialiased, it is up to the respective
251 ,aeScatters = 0x0080 ///< <tt>0x0080</tt> Scatter symbols of plottables (excluding scatter symbols of type ssPixmap)
254 ,aeOther = 0x8000 ///< <tt>0x8000</tt> Other elements that don't fit into any of the existing categories
266 ,phFastPolylines = 0x001 ///< <tt>0x001</tt> Graph/Curve lines are drawn with a faster method. This reduces the quality especially of the line segment
267 ///< joins, thus is most effective for pen sizes larger than 1. It is only used for solid line pens.
268 ,phImmediateRefresh = 0x002 ///< <tt>0x002</tt> causes an immediate repaint() instead of a soft update() when QCustomPlot::replot() is called with parameter \ref QCustomPlot::rpRefreshHint.
269 ///< This is set by default to prevent the plot from freezing on fast consecutive replots (e.g. user drags ranges with mouse).
270 ,phCacheLabels = 0x004 ///< <tt>0x004</tt> axis (tick) labels will be cached as pixmaps, increasing replot performance.
282 ,iRangeDrag = 0x001 ///< <tt>0x001</tt> Axis ranges are draggable (see \ref QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeDragAxes)
283 ,iRangeZoom = 0x002 ///< <tt>0x002</tt> Axis ranges are zoomable with the mouse wheel (see \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeZoomAxes)
284 ,iMultiSelect = 0x004 ///< <tt>0x004</tt> The user can select multiple objects by holding the modifier set by \ref QCustomPlot::setMultiSelectModifier while clicking
285 ,iSelectPlottables = 0x008 ///< <tt>0x008</tt> Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable)
286 ,iSelectAxes = 0x010 ///< <tt>0x010</tt> Axes are selectable (or parts of them, see QCPAxis::setSelectableParts)
287 ,iSelectLegend = 0x020 ///< <tt>0x020</tt> Legends are selectable (or their child items, see QCPLegend::setSelectableParts)
288 ,iSelectItems = 0x040 ///< <tt>0x040</tt> Items are selectable (Rectangles, Arrows, Textitems, etc. see \ref QCPAbstractItem)
289 ,iSelectOther = 0x080 ///< <tt>0x080</tt> All other objects are selectable (e.g. your own derived layerables, other layout elements,...)
290 ,iSelectPlottablesBeyondAxisRect = 0x100 ///< <tt>0x100</tt> When performing plottable selection/hit tests, this flag extends the sensitive area beyond the axis rect
299enum SelectionRectMode { srmNone ///< The selection rect is disabled, and all mouse events are forwarded to the underlying objects, e.g. for axis range dragging
300 ,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.
301 ,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.)
419// for older Qt versions we have to declare the enums/flags as metatypes outside the namespace using Q_DECLARE_METATYPE:
492inline const QCPVector2D operator*(double factor, const QCPVector2D &vec) { return QCPVector2D(vec.mX*factor, vec.mY*factor); }
493inline const QCPVector2D operator*(const QCPVector2D &vec, double factor) { return QCPVector2D(vec.mX*factor, vec.mY*factor); }
494inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor) { return QCPVector2D(vec.mX/divisor, vec.mY/divisor); }
495inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX+vec2.mX, vec1.mY+vec2.mY); }
496inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX-vec2.mX, vec1.mY-vec2.mY); }
497inline const QCPVector2D operator-(const QCPVector2D &vec) { return QCPVector2D(-vec.mX, -vec.mY); }
520 Defines special modes the painter can operate in. They disable or enable certain subsets of features/fixes/workarounds,
523 enum PainterMode { pmDefault = 0x00 ///< <tt>0x00</tt> Default mode for painting on screen devices
524 ,pmVectorized = 0x01 ///< <tt>0x01</tt> Mode for vectorized painting (e.g. PDF export). For example, this prevents some antialiasing fixes.
525 ,pmNoCaching = 0x02 ///< <tt>0x02</tt> Mode for all sorts of exports (e.g. PNG, PDF,...). For example, this prevents using cached pixmap labels
526 ,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.)
656 explicit QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer<QOpenGLContext> glContext, QWeakPointer<QOpenGLPaintDevice> glPaintDevice);
702 enum LayerMode { lmLogical ///< Layer is used only for rendering order, and shares paint buffer with all other adjacent logical layers.
703 ,lmBuffered ///< Layer has its own paint buffer and may be replotted individually (see \ref replot).
762 QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=nullptr);
779 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const;
802 virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged);
815 void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const;
839 bool operator==(const QCPRange& other) const { return lower == other.lower && upper == other.upper; }
955 bool operator==(const QCPDataRange& other) const { return mBegin == other.mBegin && mEnd == other.mEnd; }
974 QCPDataRange adjusted(int changeBegin, int changeEnd) const { return QCPDataRange(mBegin+changeBegin, mEnd+changeEnd); }
998 friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataSelection& b);
999 friend inline const QCPDataSelection operator+(const QCPDataRange& a, const QCPDataSelection& b);
1000 friend inline const QCPDataSelection operator+(const QCPDataSelection& a, const QCPDataRange& b);
1002 friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataSelection& b);
1003 friend inline const QCPDataSelection operator-(const QCPDataRange& a, const QCPDataSelection& b);
1004 friend inline const QCPDataSelection operator-(const QCPDataSelection& a, const QCPDataRange& b);
1029 inline static bool lessThanDataRangeBegin(const QCPDataRange &a, const QCPDataRange &b) { return a.begin() < b.begin(); }
1035 Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
1046 Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
1057 Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
1068 Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
1215 QList<QCPLayoutElement*> elements(QCP::MarginSide side) const { return mChildren.value(side); }
1249 Q_PROPERTY(SizeConstraintRect sizeConstraintRect READ sizeConstraintRect WRITE setSizeConstraintRect)
1256 enum UpdatePhase { upPreparation ///< Phase used for any type of preparation that needs to be done before margin calculation and layout
1265 margins (e.g. in the case of a QCPAxisRect the axis labels), whereas the inner rect (\ref rect)
1270 enum SizeConstraintRect { scrInnerRect ///< Minimum/Maximum size constraints apply to inner rect
1271 , scrOuterRect ///< Minimum/Maximum size constraints apply to outer rect, thus include layout element margins
1288 QCPMarginGroup *marginGroup(QCP::MarginSide side) const { return mMarginGroups.value(side, nullptr); }
1310 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
1327 virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE { Q_UNUSED(painter) }
1371 QVector<int> getSectionSizes(QVector<int> maxSizes, QVector<int> minSizes, QVector<double> stretchFactors, int totalSize) const;
1387 Q_PROPERTY(QList<double> columnStretchFactors READ columnStretchFactors WRITE setColumnStretchFactors)
1403 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.
1404 ,foColumnsFirst ///< Columns are filled first, and a new element is wrapped to the next row if the column count would exceed \ref setWrap.
1479 enum InsetPlacement { ipFree ///< The element may be positioned/sized arbitrarily, see \ref setInsetRect
1480 ,ipBorderAligned ///< The element is aligned to one of the layout sides, see \ref setInsetAlignment
1538 and \ref setLength. Some decorations like \ref esDisc, \ref esSquare, \ref esDiamond and \ref esBar only
1541 \see QCPItemLine::setHead, QCPItemLine::setTail, QCPItemCurve::setHead, QCPItemCurve::setTail, QCPAxis::setLowerEnding, QCPAxis::setUpperEnding
1678 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
1695 double mRotation; // this is the rotation applied uniformly to all labels, not the heterogeneous rotation in amCircularRotated mode
1701 QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters
1707 virtual void drawLabelMaybeCached(QCPPainter *painter, const QFont &font, const QColor &color, const QPointF &pos, AnchorSide side, double rotation, const QString &text);
1708 virtual QByteArray generateLabelParameterHash() const; // TODO: get rid of this in favor of invalidation flag upon setters?
1713 LabelData getTickLabelData(const QFont &font, const QColor &color, double rotation, AnchorSide side, const QString &text) const;
1715 //void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const;
1717 QByteArray cacheKey(const QString &text, const QColor &color, double rotation, AnchorSide side) const;
1737 Defines the strategies that the axis ticker may follow when choosing the size of the tick step.
1743 tssReadability ///< A nicely readable tick step is prioritized over matching the requested number of ticks (see \ref setTickCount)
1744 ,tssMeetTickCount ///< Less readable tick steps are allowed which in turn facilitates getting closer to the requested tick count
1762 virtual void generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector<double> &ticks, QVector<double> *subTicks, QVector<QString> *tickLabels);
1773 virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision);
1815 void setTickOrigin(double origin); // hides base class method but calls baseclass implementation ("using" throws off IDEs and doxygen)
1836 virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE;
1837 virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE;
1855 enum TimeUnit { tuMilliseconds ///< Milliseconds, one thousandth of a second (%%z in \ref setTimeFormat)
1908 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.
1909 ,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.
1968 virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) Q_DECL_OVERRIDE;
1987 enum FractionStyle { fsFloatingPoint ///< Fractions are displayed as regular decimal floating point numbers, e.g. "0.25" or "0.125".
1988 ,fsAsciiFractions ///< Fractions are written as rationals using ASCII characters only, e.g. "1/4" or "1/8"
1989 ,fsUnicodeFractions ///< Fractions are written using sub- and superscript UTF-8 digits and the fraction symbol.
2060 virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE;
2155 Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectionChanged)
2156 Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectableChanged)
2157 Q_PROPERTY(QFont selectedTickLabelFont READ selectedTickLabelFont WRITE setSelectedTickLabelFont)
2159 Q_PROPERTY(QColor selectedTickLabelColor READ selectedTickLabelColor WRITE setSelectedTickLabelColor)
2173 enum AxisType { atLeft = 0x01 ///< <tt>0x01</tt> Axis is vertical and on the left side of the axis rect
2195 ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed axis coordinates (possibly also \ref setTicker to a \ref QCPAxisTickerLog instance).
2306 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
2310 int pixelOrientation() const { return rangeReversed() != (orientation()==Qt::Vertical) ? -1 : 1; }
2324 static Qt::Orientation orientation(AxisType type) { return type==atBottom || type==atTop ? Qt::Horizontal : Qt::Vertical; }
2392 virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
2452 int tickLengthIn, tickLengthOut, subTickLengthIn, subTickLengthOut; // directly accessed by QCPAxis setters/getters
2478 QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters
2484 virtual void placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize);
2485 virtual void drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const;
2488 virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const;
2527 enum ScatterShape { ssNone ///< no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines)
2528 ,ssDot ///< \enumimage{ssDot.png} a single pixel (use \ref ssDisc or \ref ssCircle if you want a round shape with a certain radius)
2532 ,ssDisc ///< \enumimage{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle)
2535 ,ssStar ///< \enumimage{ssStar.png} a star with eight arms, i.e. a combination of cross and plus
2537 ,ssTriangleInverted ///< \enumimage{ssTriangleInverted.png} an equilateral triangle, standing on corner
2542 ,ssPeace ///< \enumimage{ssPeace.png} a circle, with one vertical and two downward diagonal lines
2543 ,ssPixmap ///< a custom pixmap specified by \ref setPixmap, centered on the data point coordinates
2554 QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush=Qt::NoBrush, double size=6);
2610inline bool qcpLessThanSortKey(const DataType &a, const DataType &b) { return a.sortKey() < b.sortKey(); }
2613class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp included below)
2651 QCPRange valueRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange());
2653 void limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const;
2672////////////////////////////////////////////////////////////////////////////////////////////////////
2674////////////////////////////////////////////////////////////////////////////////////////////////////
2679 This class template provides a fast container for data storage of one-dimensional data. The data
2683 The data is stored in a sorted fashion, which allows very quick lookups by the sorted key as well
2684 as retrieval of ranges (see \ref findBegin, \ref findEnd, \ref keyRange) using binary search. The
2688 using the fact that existing data is always sorted. The user can further improve performance by
2689 specifying that added data is already itself sorted by key, if he can guarantee that this is the
2692 The data can be accessed with the provided const iterators (\ref constBegin, \ref constEnd). If
2693 it is necessary to alter existing data in-place, the non-const iterators can be used (\ref begin,
2694 \ref end). Changing data members that are not the sort key (for most data types called \a key) is
2697 Great care must be taken however if the sort key is modified through the non-const iterators. For
2699 manipulation. It is thus the responsibility of the user to leave the container in a sorted state
2714 \li <tt>double sortKey() const</tt>\n Returns the member variable of this data point that is the
2720 \li <tt>static bool sortKeyIsMainKey()</tt>\n Returns true if the sort key is equal to the main
2721 key (see method \c mainKey below). For most plottables this is the case. It is not the case for
2722 example for \ref QCPCurve, which uses \a t as sort key and \a key as main key. This is the reason
2725 \li <tt>double mainKey() const</tt>\n Returns the variable of this data point considered the main
2726 key. This is commonly the variable that is used as the coordinate of this data point on the key
2734 \li <tt>QCPRange valueRange() const</tt>\n Returns the range this data point spans in the value
2736 both lower and upper set to the main data point value. However if the data points can represent
2738 values at each \a key) this method should return the range those values span. This method is used
2769 You can manipulate the data points in-place through the non-const iterators, but great care must
2778 You can manipulate the data points in-place through the non-const iterators, but great care must
2786 the available elements in this container, returns \ref constEnd, i.e. an iterator past the last
2879 if (oldSize > 0 && !qcpLessThanSortKey<DataType>(*constBegin(), *(data.constEnd()-1))) // prepend if new data keys are all smaller than or equal to existing ones
2889 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
2916 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
2928 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
2942 if (isEmpty() || !qcpLessThanSortKey<DataType>(data, *(constEnd()-1))) // quickly handle appends if new data key is greater or equal to existing ones
2945 } else if (qcpLessThanSortKey<DataType>(data, *constBegin())) // quickly handle prepends using preallocated space
2953 QCPDataContainer<DataType>::iterator insertionPoint = std::lower_bound(begin(), end(), data, qcpLessThanSortKey<DataType>);
2967 QCPDataContainer<DataType>::iterator itEnd = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
2981 QCPDataContainer<DataType>::iterator it = std::upper_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
3001 QCPDataContainer<DataType>::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKeyFrom), qcpLessThanSortKey<DataType>);
3002 QCPDataContainer<DataType>::iterator itEnd = std::upper_bound(it, end(), DataType::fromSortKey(sortKeyTo), qcpLessThanSortKey<DataType>);
3020 QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
3048 When setting, adding or removing points using the QCPDataContainer interface (\ref set, \ref add,
3051 points by accessing and modifying it through the non-const iterators (\ref begin, \ref end), it
3052 is your responsibility to bring the container back into a sorted state before any other methods
3069 The parameters \a preAllocation and \a postAllocation control whether pre- and/or post allocation
3094 This can be used in conjunction with \ref findEnd to iterate over data points within a given key
3095 range, including or excluding the bounding data points that are just beyond the specified range.
3105typename QCPDataContainer<DataType>::const_iterator QCPDataContainer<DataType>::findBegin(double sortKey, bool expandedRange) const
3110 QCPDataContainer<DataType>::const_iterator it = std::lower_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
3111 if (expandedRange && it != constBegin()) // also covers it == constEnd case, and we know --constEnd is valid because mData isn't empty
3117 Returns an iterator to the element after the data point with a (sort-)key that is equal to, just
3118 above or just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey
3122 key range, including the bounding data points that are just below and above the specified range.
3132typename QCPDataContainer<DataType>::const_iterator QCPDataContainer<DataType>::findEnd(double sortKey, bool expandedRange) const
3137 QCPDataContainer<DataType>::const_iterator it = std::upper_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
3153 If the DataType reports that its main key is equal to the sort key (\a sortKeyIsMainKey), as is
3175 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
3269 you should not use the returned QCPRange (e.g. the data container is empty or all points have the
3284QCPRange QCPDataContainer<DataType>::valueRange(bool &foundRange, QCP::SignDomain signDomain, const QCPRange &inKeyRange)
3307 if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper))
3310 if ((current.lower < range.lower || !haveLower) && !qIsNaN(current.lower) && std::isfinite(current.lower))
3315 if ((current.upper > range.upper || !haveUpper) && !qIsNaN(current.upper) && std::isfinite(current.upper))
3325 if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper))
3328 if ((current.lower < range.lower || !haveLower) && current.lower < 0 && !qIsNaN(current.lower) && std::isfinite(current.lower))
3333 if ((current.upper > range.upper || !haveUpper) && current.upper < 0 && !qIsNaN(current.upper) && std::isfinite(current.upper))
3343 if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper))
3346 if ((current.lower < range.lower || !haveLower) && current.lower > 0 && !qIsNaN(current.lower) && std::isfinite(current.lower))
3368 This function doesn't require for \a dataRange to be within the bounds of this data container's
3372void QCPDataContainer<DataType>::limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const
3382 Increases the preallocation pool to have a size of at least \a minimumPreallocSize. Depending on
3386 if \a minimumPreallocSize is smaller than or equal to the current preallocation pool size, this
3407 This method decides, depending on the total allocation size and the size of the unused pre- and
3411 If \ref setAutoSqueeze is enabled, this method is called automatically each time data points are
3427 if (totalAlloc > 650000) // if allocation is larger, shrink earlier with respect to total used size
3429 shrinkPostAllocation = postAllocSize > usedSize*1.5; // QVector grow strategy is 2^n for static data. Watch out not to oscillate!
3431 } else if (totalAlloc > 1000) // below 10 MiB raw data be generous with preallocated memory, below 1k points don't even bother
3459 QCPScatterStyle::ScatterProperties usedScatterProperties() const { return mUsedScatterProperties; }
3464 void setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties=QCPScatterStyle::spPen);
3506 Q_PROPERTY(QCP::SelectionType selectable READ selectable WRITE setSelectable NOTIFY selectableChanged)
3507 Q_PROPERTY(QCPDataSelection selection READ selection WRITE setSelection NOTIFY selectionChanged)
3508 Q_PROPERTY(QCPSelectionDecorator* selectionDecorator READ selectionDecorator WRITE setSelectionDecorator)
3540 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
3542 virtual QCPRange getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth) const = 0;
3543 virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange()) const = 0;
3580 virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
3609 QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId=-1);
3631 void removeChildX(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted
3633 void removeChildY(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted
3653 enum PositionType { ptAbsolute ///< Static positioning in pixels, starting from the top left corner of the viewport/widget.
3654 ,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
3655 ///< 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
3657 ,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
3658 ///< 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
3659 ///< 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.
3660 ,ptPlotCoords ///< Dynamic positioning at a plot coordinate defined by two axes (see \ref setAxes).
3739 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE = 0;
3766 virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
3797 Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode)
3799 Q_PROPERTY(bool autoAddPlottableToLegend READ autoAddPlottableToLegend WRITE setAutoAddPlottableToLegend)
3802 Q_PROPERTY(Qt::KeyboardModifier multiSelectModifier READ multiSelectModifier WRITE setMultiSelectModifier)
3821 enum RefreshPriority { rpImmediateRefresh ///< Replots immediately and repaints the widget immediately by calling QWidget::repaint() after the replot
3822 ,rpQueuedRefresh ///< Replots immediately, but queues the widget repaint, by calling QWidget::update() after the replot. This way multiple redundant widget repaints can be avoided.
3823 ,rpRefreshHint ///< Whether to use immediate or queued refresh depends on whether the plotting hint \ref QCP::phImmediateRefresh is set, see \ref setPlottingHints.
3824 ,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.
3854 void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding);
3861 void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true);
3884 PlottableType *plottableAt(const QPointF &pos, bool onlySelectable=false, int *dataIndex=nullptr) const;
3885 QCPAbstractPlottable *plottableAt(const QPointF &pos, bool onlySelectable=false, int *dataIndex=nullptr) const;
3918 bool addLayer(const QString &name, QCPLayer *otherLayer=nullptr, LayerInsertMode insertMode=limAbove);
3934 bool savePdf(const QString &fileName, int width=0, int height=0, QCP::ExportPen exportPen=QCP::epAllowCosmetic, const QString &pdfCreator=QString(), const QString &pdfTitle=QString());
3935 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);
3936 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);
3937 bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0, int resolution=96, QCP::ResolutionUnit resolutionUnit=QCP::ruDotsPerInch);
3938 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);
3975 QList<QCPGraph*> mGraphs; // extra list of plottables also in mPlottables that are of type QCPGraph
4039 QCPLayerable *layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=nullptr) const;
4040 QList<QCPLayerable*> layerableListAt(const QPointF &pos, bool onlySelectable, QList<QVariant> *selectionDetails=nullptr) const;
4066 Plottables that only consist of single lines (like graphs) have a tolerance band around them, see
4067 \ref setSelectionTolerance. If multiple plottables come into consideration, the one closest to \a
4073 if \a dataIndex is non-null, it is set to the index of the plottable's data point that is closest
4081PlottableType *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable, int *dataIndex) const
4085 double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value
4090 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
4092 if (currentPlottable->clipRect().contains(pos.toPoint())) // only consider clicks where the plottable is actually visible
4095 double currentDistance = currentPlottable->selectTest(pos, false, dataIndex ? &details : nullptr);
4115 Returns the item at the pixel position \a pos. The item type (a QCPAbstractItem subclass) that shall be
4116 taken into consideration can be specified via the template parameter. Items that only consist of single
4118 setSelectionTolerance. If multiple items come into consideration, the one closest to \a pos is returned.
4120 If \a onlySelectable is true, only items that are selectable (QCPAbstractItem::setSelectable) are
4131 double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value
4136 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
4138 if (!currentItem->clipToAxisRect() || currentItem->clipRect().contains(pos.toPoint())) // only consider clicks inside axis cliprect of the item if actually clipped to it
4178class QCPAbstractPlottable1D : public QCPAbstractPlottable, public QCPPlottableInterface1D // no QCP_LIB_DECL, template class ends up in header (cpp included below)
4194 virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE;
4199 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
4207 void getDataSegments(QList<QCPDataRange> &selectedSegments, QList<QCPDataRange> &unselectedSegments) const;
4218////////////////////////////////////////////////////////////////////////////////////////////////////
4220////////////////////////////////////////////////////////////////////////////////////////////////////
4228 For example, it is implemented by the template class \ref QCPAbstractPlottable1D (the preferred
4233 If your plottable doesn't derive from \ref QCPAbstractPlottable1D but still wants to provide a 1d
4240 interface by calling \ref QCPAbstractPlottable::interface1D and testing it for a non-zero return
4252/*! \fn virtual QCPDataSelection QCPPlottableInterface1D::selectTestRect(const QRectF &rect, bool onlySelectable) const = 0;
4254 Returns a data selection containing all the data points of this plottable which are contained (or
4255 hit by) \a rect. This is used mainly in the selection rect interaction for data selection (\ref
4261 \note \a rect must be a normalized rect (positive or zero width and height). This is especially
4263 normalized. Use <tt>QRect::normalized()</tt> when passing a rect which might not be normalized.
4271 qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4280 qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4289 qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4298 qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4315 Returns whether the sort key (\ref dataSortKey) is identical to the main key (\ref dataMainKey).
4318 qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4322/*! \fn virtual int QCPPlottableInterface1D::findBegin(double sortKey, bool expandedRange) const = 0
4324 Returns the index of the data point with a (sort-)key that is equal to, just below, or just above
4325 \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be considered,
4328 This can be used in conjunction with \ref findEnd to iterate over data points within a given key
4329 range, including or excluding the bounding data points that are just beyond the specified range.
4339/*! \fn virtual int QCPPlottableInterface1D::findEnd(double sortKey, bool expandedRange) const = 0
4342 just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey will be
4346 key range, including the bounding data points that are just below and above the specified range.
4348 If \a expandedRange is true but there are no data points above \a sortKey, the index just above the
4359////////////////////////////////////////////////////////////////////////////////////////////////////
4361////////////////////////////////////////////////////////////////////////////////////////////////////
4366 This template class derives from \ref QCPAbstractPlottable and from the abstract interface \ref
4367 QCPPlottableInterface1D. It serves as a base class for all one-dimensional data (i.e. data with
4371 QCPGraphData or \ref QCPCurveData). The main purpose of this base class is to provide the member
4372 \a mDataContainer (a shared pointer to a \ref QCPDataContainer "QCPDataContainer<DataType>") and
4377 \ref getDataSegments. This is useful when subclasses implement their \ref draw method and need to
4384 again, to provide a more accurate hit test based on their specific data visualization geometry.
4404QCPAbstractPlottable1D<DataType>::QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis) :
4515 Implements a rect-selection algorithm assuming the data (accessed via the 1D data interface) is
4522QCPDataSelection QCPAbstractPlottable1D<DataType>::selectTestRect(const QRectF &rect, bool onlySelectable) const
4534 QCPRange keyRange(key1, key2); // QCPRange normalizes internally so we don't have to care about whether key1 < key2
4538 if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval:
4546 int currentSegmentBegin = -1; // -1 means we're currently not in a segment that's contained in rect
4553 } else if (!valueRange.contains(it->mainValue()) || !keyRange.contains(it->mainKey())) // segment just ended
4555 result.addDataRange(QCPDataRange(currentSegmentBegin, int(it-mDataContainer->constBegin())), false);
4561 result.addDataRange(QCPDataRange(currentSegmentBegin, int(end-mDataContainer->constBegin())), false);
4586 Implements a point-selection algorithm assuming the data (accessed via the 1D data interface) is
4590 If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data point
4596double QCPAbstractPlottable1D<DataType>::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const
4609 if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval:
4611 // determine which key range comes into question, taking selection tolerance around pos into account:
4613 pixelsToCoords(pos-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy);
4614 pixelsToCoords(pos+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy);
4628 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
4630 const double currentDistSqr = QCPVector2D(coordsToPixels(mainKey, mainValue)-pos).lengthSquared();