Kstars
qcustomplot.h
140class QCP { // when in moc-run, make it look like a class, so we get Q_GADGET, Q_ENUMS/Q_FLAGS features in namespace
162 \see QCustomPlot::savePng, QCustomPlot::saveJpg, QCustomPlot::saveBmp, QCustomPlot::saveRastered
167 };
174enum 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 };
188 };
201 };
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
220 ,aeScatters = 0x0080 ///< <tt>0x0080</tt> Scatter symbols of plottables (excluding scatter symbols of type ssPixmap)
223 ,aeOther = 0x8000 ///< <tt>0x8000</tt> Other elements that don't fit into any of the existing categories
226 };
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 };
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 };
268enum 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 };
293 ,stWhole ///< Selection behaves like \ref stMultipleDataRanges, but if there are any data points selected, the entire plottable is drawn as selected.
297 };
360extern 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
435inline const QCPVector2D operator*(double factor, const QCPVector2D &vec) { return QCPVector2D(vec.mX*factor, vec.mY*factor); }
436inline const QCPVector2D operator*(const QCPVector2D &vec, double factor) { return QCPVector2D(vec.mX*factor, vec.mY*factor); }
437inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor) { return QCPVector2D(vec.mX/divisor, vec.mY/divisor); }
438inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX+vec2.mX, vec1.mY+vec2.mY); }
439inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2) { return QCPVector2D(vec1.mX-vec2.mX, vec1.mY-vec2.mY); }
440inline const QCPVector2D operator-(const QCPVector2D &vec) { return QCPVector2D(-vec.mX, -vec.mY); }
463 Defines special modes the painter can operate in. They disable or enable certain subsets of features/fixes/workarounds,
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 };
599 explicit QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer<QOpenGLContext> glContext, QWeakPointer<QOpenGLPaintDevice> glPaintDevice);
705 QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=nullptr);
722 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const;
745 virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged);
758 void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const;
782 bool operator==(const QCPRange& other) const { return lower == other.lower && upper == other.upper; }
898 bool operator==(const QCPDataRange& other) const { return mBegin == other.mBegin && mEnd == other.mEnd; }
917 QCPDataRange adjusted(int changeBegin, int changeEnd) const { return QCPDataRange(mBegin+changeBegin, mEnd+changeEnd); }
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);
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);
972 inline static bool lessThanDataRangeBegin(const QCPDataRange &a, const QCPDataRange &b) { return a.begin() < b.begin(); }
978 Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
989 Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
1000 Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
1011 Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b.
1158 QList<QCPLayoutElement*> elements(QCP::MarginSide side) const { return mChildren.value(side); }
1192 Q_PROPERTY(SizeConstraintRect sizeConstraintRect READ sizeConstraintRect WRITE setSizeConstraintRect)
1199 enum UpdatePhase { upPreparation ///< Phase used for any type of preparation that needs to be done before margin calculation and layout
1202 };
1208 margins (e.g. in the case of a QCPAxisRect the axis labels), whereas the inner rect (\ref rect)
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 };
1231 QCPMarginGroup *marginGroup(QCP::MarginSide side) const { return mMarginGroups.value(side, nullptr); }
1253 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
1270 virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE { Q_UNUSED(painter) }
1314 QVector<int> getSectionSizes(QVector<int> maxSizes, QVector<int> minSizes, QVector<double> stretchFactors, int totalSize) const;
1330 Q_PROPERTY(QList<double> columnStretchFactors READ columnStretchFactors WRITE setColumnStretchFactors)
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 };
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 };
1481 and \ref setLength. Some decorations like \ref esDisc, \ref esSquare, \ref esDiamond and \ref esBar only
1484 \see QCPItemLine::setHead, QCPItemLine::setTail, QCPItemCurve::setHead, QCPItemCurve::setTail, QCPAxis::setLowerEnding, QCPAxis::setUpperEnding
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
1638 double mRotation; // this is the rotation applied uniformly to all labels, not the heterogeneous rotation in amCircularRotated mode
1644 QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters
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?
1656 LabelData getTickLabelData(const QFont &font, const QColor &color, double rotation, AnchorSide side, const QString &text) const;
1658 //void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) 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;
1680 Defines the strategies that the axis ticker may follow when choosing the size of the tick step.
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 };
1705 virtual void generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector<double> &ticks, QVector<double> *subTicks, QVector<QString> *tickLabels);
1716 virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision);
1719 virtual QVector<QString> createLabelVector(const QVector<double> &ticks, const QLocale &locale, QChar formatChar, int precision);
1758 void setTickOrigin(double origin); // hides base class method but calls baseclass implementation ("using" throws off IDEs and doxygen)
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;
1798 enum TimeUnit { tuMilliseconds ///< Milliseconds, one thousandth of a second (%%z in \ref setTimeFormat)
1803 };
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.
1854 };
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;
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 };
2003 virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) Q_DECL_OVERRIDE;
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)
2102 Q_PROPERTY(QColor selectedTickLabelColor READ selectedTickLabelColor WRITE setSelectedTickLabelColor)
2116 enum AxisType { atLeft = 0x01 ///< <tt>0x01</tt> Axis is vertical and on the left side of the axis rect
2120 };
2129 enum LabelSide { lsInside ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect
2131 };
2138 ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed axis coordinates (possibly also \ref setTicker to a \ref QCPAxisTickerLog instance).
2139 };
2149 };
2249 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
2253 int pixelOrientation() const { return rangeReversed() != (orientation()==Qt::Vertical) ? -1 : 1; }
2267 static Qt::Orientation orientation(AxisType type) { return type==atBottom || type==atTop ? Qt::Horizontal : Qt::Vertical; }
2335 virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
2395 int tickLengthIn, tickLengthOut, subTickLengthIn, subTickLengthOut; // directly accessed by QCPAxis setters/getters
2421 QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters
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;
2458 };
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)
2475 ,ssDisc ///< \enumimage{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle)
2478 ,ssStar ///< \enumimage{ssStar.png} a star with eight arms, i.e. a combination of cross and plus
2480 ,ssTriangleInverted ///< \enumimage{ssTriangleInverted.png} an equilateral triangle, standing on corner
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 };
2497 QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush=Qt::NoBrush, double size=6);
2553inline bool qcpLessThanSortKey(const DataType &a, const DataType &b) { return a.sortKey() < b.sortKey(); }
2556class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp included below)
2594 QCPRange valueRange(bool &foundRange, QCP::SignDomain signDomain=QCP::sdBoth, const QCPRange &inKeyRange=QCPRange());
2596 void limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const;
2615////////////////////////////////////////////////////////////////////////////////////////////////////
2617////////////////////////////////////////////////////////////////////////////////////////////////////
2622 This class template provides a fast container for data storage of one-dimensional data. The data
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
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
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
2640 Great care must be taken however if the sort key is modified through the non-const iterators. For
2642 manipulation. It is thus the responsibility of the user to leave the container in a sorted state
2657 \li <tt>double sortKey() const</tt>\n Returns the member variable of this data point that is the
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
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
2677 \li <tt>QCPRange valueRange() const</tt>\n Returns the range this data point spans in the value
2679 both lower and upper set to the main data point value. However if the data points can represent
2681 values at each \a key) this method should return the range those values span. This method is used
2712 You can manipulate the data points in-place through the non-const iterators, but great care must
2721 You can manipulate the data points in-place through the non-const iterators, but great care must
2729 the available elements in this container, returns \ref constEnd, i.e. an iterator past the last
2822 if (oldSize > 0 && !qcpLessThanSortKey<DataType>(*constBegin(), *(data.constEnd()-1))) // prepend if new data keys are all smaller than or equal to existing ones
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
2885 if (isEmpty() || !qcpLessThanSortKey<DataType>(data, *(constEnd()-1))) // quickly handle appends if new data key is greater or equal to existing ones
2888 } else if (qcpLessThanSortKey<DataType>(data, *constBegin())) // quickly handle prepends using preallocated space
2896 QCPDataContainer<DataType>::iterator insertionPoint = std::lower_bound(begin(), end(), data, qcpLessThanSortKey<DataType>);
2910 QCPDataContainer<DataType>::iterator itEnd = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
2924 QCPDataContainer<DataType>::iterator it = std::upper_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
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>);
2963 QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
2991 When setting, adding or removing points using the QCPDataContainer interface (\ref set, \ref add,
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
3012 The parameters \a preAllocation and \a postAllocation control whether pre- and/or post allocation
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.
3048typename QCPDataContainer<DataType>::const_iterator QCPDataContainer<DataType>::findBegin(double sortKey, bool expandedRange) const
3053 QCPDataContainer<DataType>::const_iterator it = std::lower_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
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
3065 key range, including the bounding data points that are just below and above the specified range.
3075typename QCPDataContainer<DataType>::const_iterator QCPDataContainer<DataType>::findEnd(double sortKey, bool expandedRange) const
3080 QCPDataContainer<DataType>::const_iterator it = std::upper_bound(constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>);
3096 If the DataType reports that its main key is equal to the sort key (\a sortKeyIsMainKey), as is
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
3212 you should not use the returned QCPRange (e.g. the data container is empty or all points have the
3225QCPRange QCPDataContainer<DataType>::valueRange(bool &foundRange, QCP::SignDomain signDomain, const QCPRange &inKeyRange)
3248 if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper))
3266 if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper))
3269 if ((current.lower < range.lower || !haveLower) && current.lower < 0 && !qIsNaN(current.lower))
3274 if ((current.upper > range.upper || !haveUpper) && current.upper < 0 && !qIsNaN(current.upper))
3284 if (restrictKeyRange && (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper))
3287 if ((current.lower < range.lower || !haveLower) && current.lower > 0 && !qIsNaN(current.lower))
3309 This function doesn't require for \a dataRange to be within the bounds of this data container's
3313void QCPDataContainer<DataType>::limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, const QCPDataRange &dataRange) const
3323 Increases the preallocation pool to have a size of at least \a minimumPreallocSize. Depending on
3327 if \a minimumPreallocSize is smaller than or equal to the current preallocation pool size, this
3348 This method decides, depending on the total allocation size and the size of the unused pre- and
3352 If \ref setAutoSqueeze is enabled, this method is called automatically each time data points are
3368 if (totalAlloc > 650000) // if allocation is larger, shrink earlier with respect to total used size
3370 shrinkPostAllocation = postAllocSize > usedSize*1.5; // QVector grow strategy is 2^n for static data. Watch out not to oscillate!
3372 } else if (totalAlloc > 1000) // below 10 MiB raw data be generous with preallocated memory, below 1k points don't even bother
3400 QCPScatterStyle::ScatterProperties usedScatterProperties() const { return mUsedScatterProperties; }
3405 void setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties=QCPScatterStyle::spPen);
3447 Q_PROPERTY(QCP::SelectionType selectable READ selectable WRITE setSelectable NOTIFY selectableChanged)
3448 Q_PROPERTY(QCPDataSelection selection READ selection WRITE setSelection NOTIFY selectionChanged)
3449 Q_PROPERTY(QCPSelectionDecorator* selectionDecorator READ selectionDecorator WRITE setSelectionDecorator)
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
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;
3521 virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
3550 QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId=-1);
3572 void removeChildX(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted
3574 void removeChildY(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted
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
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 };
3680 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE = 0;
3707 virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged) Q_DECL_OVERRIDE;
3738 Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode)
3740 Q_PROPERTY(bool autoAddPlottableToLegend READ autoAddPlottableToLegend WRITE setAutoAddPlottableToLegend)
3743 Q_PROPERTY(Qt::KeyboardModifier multiSelectModifier READ multiSelectModifier WRITE setMultiSelectModifier)
3754 };
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 };
3795 void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding);
3802 void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true);
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;
3859 bool addLayer(const QString &name, QCPLayer *otherLayer=nullptr, LayerInsertMode insertMode=limAbove);
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);
3916 QList<QCPGraph*> mGraphs; // extra list of plottables also in mPlottables that are of type QCPGraph
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;
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
4015 if \a dataIndex is non-null, it is set to the index of the plottable's data point that is closest
4023PlottableType *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable, int *dataIndex) const
4027 double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value
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
4034 if (currentPlottable->clipRect().contains(pos.toPoint())) // only consider clicks where the plottable is actually visible
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
4060 setSelectionTolerance. If multiple items come into consideration, the one closest to \a pos is returned.
4062 If \a onlySelectable is true, only items that are selectable (QCPAbstractItem::setSelectable) are
4073 double resultDistance = mSelectionTolerance; // only regard clicks with distances smaller than mSelectionTolerance as selections, so initialize with that value
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
4080 if (!currentItem->clipToAxisRect() || currentItem->clipRect().contains(pos.toPoint())) // only consider clicks inside axis cliprect of the item if actually clipped to it
4120class QCPAbstractPlottable1D : public QCPAbstractPlottable, public QCPPlottableInterface1D // no QCP_LIB_DECL, template class ends up in header (cpp included below)
4136 virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const Q_DECL_OVERRIDE;
4141 virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=nullptr) const Q_DECL_OVERRIDE;
4149 void getDataSegments(QList<QCPDataRange> &selectedSegments, QList<QCPDataRange> &unselectedSegments) const;
4160////////////////////////////////////////////////////////////////////////////////////////////////////
4162////////////////////////////////////////////////////////////////////////////////////////////////////
4170 For example, it is implemented by the template class \ref QCPAbstractPlottable1D (the preferred
4175 If your plottable doesn't derive from \ref QCPAbstractPlottable1D but still wants to provide a 1d
4182 interface by calling \ref QCPAbstractPlottable::interface1D and testing it for a non-zero return
4194/*! \fn virtual QCPDataSelection QCPPlottableInterface1D::selectTestRect(const QRectF &rect, bool onlySelectable) const = 0;
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
4203 \note \a rect must be a normalized rect (positive or zero width and height). This is especially
4205 normalized. Use <tt>QRect::normalized()</tt> when passing a rect which might not be normalized.
4213 qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4222 qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4231 qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4240 qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4257 Returns whether the sort key (\ref dataSortKey) is identical to the main key (\ref dataMainKey).
4260 qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming
4264/*! \fn virtual int QCPPlottableInterface1D::findBegin(double sortKey, bool expandedRange) const = 0
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,
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.
4281/*! \fn virtual int QCPPlottableInterface1D::findEnd(double sortKey, bool expandedRange) const = 0
4284 just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey will be
4288 key range, including the bounding data points that are just below and above the specified range.
4290 If \a expandedRange is true but there are no data points above \a sortKey, the index just above the
4301////////////////////////////////////////////////////////////////////////////////////////////////////
4303////////////////////////////////////////////////////////////////////////////////////////////////////
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
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
4319 \ref getDataSegments. This is useful when subclasses implement their \ref draw method and need to
4326 again, to provide a more accurate hit test based on their specific data visualization geometry.
4346QCPAbstractPlottable1D<DataType>::QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis) :
4438 const typename QCPDataContainer<DataType>::const_iterator it = mDataContainer->constBegin()+index;
4457 Implements a rect-selection algorithm assuming the data (accessed via the 1D data interface) is
4464QCPDataSelection QCPAbstractPlottable1D<DataType>::selectTestRect(const QRectF &rect, bool onlySelectable) const
4476 QCPRange keyRange(key1, key2); // QCPRange normalizes internally so we don't have to care about whether key1 < key2
4480 if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval:
4488 int currentSegmentBegin = -1; // -1 means we're currently not in a segment that's contained in rect
4495 } else if (!valueRange.contains(it->mainValue()) || !keyRange.contains(it->mainKey())) // segment just ended
4497 result.addDataRange(QCPDataRange(currentSegmentBegin, int(it-mDataContainer->constBegin())), false);
4503 result.addDataRange(QCPDataRange(currentSegmentBegin, int(end-mDataContainer->constBegin())), false);
4528 Implements a point-selection algorithm assuming the data (accessed via the 1D data interface) is
4532 If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data point
4538double QCPAbstractPlottable1D<DataType>::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const
4551 if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can reduce the searched key interval:
4553 // determine which key range comes into question, taking selection tolerance around pos into account:
4555 pixelsToCoords(pos-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy);
4556 pixelsToCoords(pos+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy);
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
4572 const double currentDistSqr = QCPVector2D(coordsToPixels(mainKey, mainValue)-pos).lengthSquared();
4600void QCPAbstractPlottable1D<DataType>::getDataSegments(QList<QCPDataRange> &selectedSegments, QList<QCPDataRange> &unselectedSegments) const
4604 if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with selected style if mSelection isn't empty
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
4625 Further it uses a faster line drawing technique based on \ref QCPPainter::drawLine rather than \c
4630void QCPAbstractPlottable1D<DataType>::drawPolyline(QCPPainter *painter, const QVector<QPointF> &lineData) const
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
4653 while (i < lineDataSize && (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()))) // make sure first point is not NaN
4658 if (!qIsNaN(lineData.at(i).y()) && !qIsNaN(lineData.at(i).x())) // NaNs create a gap in the line
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
4677 painter->drawPolyline(lineData.constData()+segmentStart, i-segmentStart); // i, because we don't want to include the current NaN point
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 };
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
4718 };
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)
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 };
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);
4780 QVector<QRgb> mColorBuffer; // have colors premultiplied with alpha (for usage with QImage::Format_ARGB32_Premultiplied)
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.
4812 ,bsUserStyle ///< Start custom bracket styles at this index when subclassing and reimplementing \ref drawBracket.
4813 };
4854 double getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const;