Kstars
qcustomplot.cpp
32////////////////////////////////////////////////////////////////////////////////////////////////////
34////////////////////////////////////////////////////////////////////////////////////////////////////
77 Returns the angle of the vector in radians. The angle is measured between the positive x line and
99 Returns whether this vector is null. A vector is null if \c qIsNull returns true for both x and y
185 Returns the squared shortest distance of this vector (interpreted as a point) to the finite line
190double QCPVector2D::distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const
209 Returns the squared shortest distance of this vector (interpreted as a point) to the finite line
225double QCPVector2D::distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const
277////////////////////////////////////////////////////////////////////////////////////////////////////
279////////////////////////////////////////////////////////////////////////////////////////////////////
284 This QPainter subclass is used to provide some extended functionality e.g. for tweaking position
288 \warning This class intentionally hides non-virtual functions of QPainter, e.g. setPen, save and
290 QPainter pointer, some of the workarounds and tweaks will be unavailable to the function (because
306 Creates a new QCPPainter instance on the specified paint \a device and sets default values. Just
337 Sets the pen (by color) of the painter and applies certain fixes to it, depending on the mode of
351 Sets the pen (by style) of the painter and applies certain fixes to it, depending on the mode of
382 antialiased and non-antialiased painting (Since Qt < 5.0 uses slightly different coordinate systems for
391 if (!mModes.testFlag(pmVectorized)) // antialiasing half-pixel shift only needed for rasterized outputs
411 Sets the QPainter::NonCosmeticDefaultPen in Qt versions before Qt5 after beginning painting on \a
412 device. This is necessary to get cosmetic pen consistency across Qt versions, because since Qt5,
494////////////////////////////////////////////////////////////////////////////////////////////////////
496////////////////////////////////////////////////////////////////////////////////////////////////////
508 clean up if necessary. Before rendering a frame, each paint buffer is usually filled with a color
543 Fills the entire buffer with the provided \a color. To have an empty transparent buffer, use the
546 This method must not be called if there is currently a painter (acquired with \ref startPainting)
570 paint buffer subclasses may use this method to perform any type of cleanup that is necessary. The
579 Subclasses must call their \ref reallocateBuffer implementation in their respective constructors.
595 The buffer is reallocated (by calling \ref reallocateBuffer), so any painters that were obtained
614 layer, i.e. an isolated repaint of only that layer (and its dedicated paint buffer) is requested,
615 QCustomPlot will decide depending on the invalidated flags of other paint buffers whether it also
619 were added or removed from this buffer, or if they were reordered. It is set to false as soon as
631 The ratio is automatically set to the device pixel ratio used by the parent QCustomPlot instance.
633 The buffer is reallocated (by calling \ref reallocateBuffer), so any painters that were obtained
652////////////////////////////////////////////////////////////////////////////////////////////////////
654////////////////////////////////////////////////////////////////////////////////////////////////////
724////////////////////////////////////////////////////////////////////////////////////////////////////
726////////////////////////////////////////////////////////////////////////////////////////////////////
735 The OpenGL paint buffers are used if \ref QCustomPlot::setOpenGl is set to true, and if they are
747QCPPaintBufferGlPbuffer::QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples) :
766 qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?";
819////////////////////////////////////////////////////////////////////////////////////////////////////
821////////////////////////////////////////////////////////////////////////////////////////////////////
824 \brief A paint buffer based on OpenGL frame buffers objects, using hardware accelerated rendering
830 The OpenGL paint buffers are used if \ref QCustomPlot::setOpenGl is set to true, and if they are
838 All frame buffer objects shall share one OpenGL context and paint device, which need to be set up
843QCPPaintBufferGlFbo::QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, QWeakPointer<QOpenGLContext> glContext, QWeakPointer<QOpenGLPaintDevice> glPaintDevice) :
875 qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?";
908 qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?";
925 qDebug() << Q_FUNC_INFO << "OpenGL frame buffer object doesn't exist, reallocateBuffer was not called?";
981////////////////////////////////////////////////////////////////////////////////////////////////////
983////////////////////////////////////////////////////////////////////////////////////////////////////
1002 "overlay" (in that order). On top is the "overlay" layer, which only contains the QCustomPlot's
1003 selection rect (\ref QCustomPlot::selectionRect). The next two layers "axes" and "legend" contain
1004 the default axes and legend, so they will be drawn above plottables. In the middle, there is the
1007 layer by default. Then comes the "grid" layer which contains the QCPGrid instances (which belong
1016 you want the layerable to be in, e.g. above "main", with \ref QCustomPlot::addLayer. Then set the
1019 setting. Alternatively you could have also ignored the current layer setting and just moved the
1022 It is also possible to move whole layers. For example, If you want the grid to be shown in front
1029 When a layer is deleted, the objects on it are not deleted with it, but fall on the layer below
1035 layer by calling \ref replot. In certain situations this can provide better replot performance,
1051 Returns the index this layer has in the QCustomPlot. The index is the integer number by which this layer can be
1081 // If child layerables are still on this layer, detach them, so they don't try to reach back to this
1082 // then invalid layer once they get deleted/moved themselves. This only happens when layers are deleted
1083 // directly, like in the QCustomPlot destructor. (The regular layer removal procedure for the user is to
1084 // call QCustomPlot::removeLayer, which moves all layerables off this layer before deleting it.)
1090 qDebug() << Q_FUNC_INFO << "The parent plot's mCurrentLayer will be a dangling pointer. Should have been set to a valid layer or nullptr beforehand.";
1094 Sets whether this layer is visible or not. If \a visible is set to false, all layerables on this
1098 QCPLayerable::setVisible), but the \ref QCPLayerable::realVisibility of each layerable takes the
1113 Layers which are set to \ref lmLogical (the default) are used only to define the rendering order
1120 example would be a layer which contains certain layerables (e.g. items) that need to be changed
1121 and thus replotted regularly, while all other layerables on other layers stay static. By default,
1160 Draws the contents of this layer into the paint buffer which is associated with this layer. The
1161 association is established by the parent QCustomPlot, which manages all paint buffers (see \ref
1186 the layerables on this specific layer, without the need to replot all other layers (as a call to
1189 QCustomPlot also makes sure to replot all layers instead of only this one, if the layer ordering
1193 If the layer mode is \ref lmLogical however, this method simply calls \ref QCustomPlot::replot on
1216 Adds the \a layerable to the list of this layer. If \a prepend is set to true, the layerable will
1242 This function does not change the \a mLayer member of \a layerable. (Use QCPLayerable::setLayer
1258////////////////////////////////////////////////////////////////////////////////////////////////////
1260////////////////////////////////////////////////////////////////////////////////////////////////////
1268 Every layerable is on a layer (QCPLayer) which allows controlling the rendering order by stacking
1279 visibility hierarchies in conjunction with the method \ref realVisibility. This way, layerables
1298 \ref draw is called on the layerable. If the layerable has multiple entities whose antialiasing
1300 most prominent entity. In this case however, the \ref draw function usually calls the specialized
1301 versions of this function before drawing each entity, effectively overriding the setting of the
1304 <b>First example:</b> QCPGraph has multiple entities that have an antialiasing setting: The graph
1306 QCPGraph::setAntialiasedFill and QCPGraph::setAntialiasedScatters. Consequently, there isn't only
1309 QCPGraph::applyScattersAntialiasingHint. So before drawing one of those entities, QCPGraph::draw
1313 setting which can be controlled with QCPItemLine::setAntialiased. (This function is inherited by
1314 all layerables. The specialized functions, as seen on QCPGraph, must be added explicitly to the
1317 care about setting any antialiasing states, because the default antialiasing hint is already set
1318 on the painter when the \ref draw function is called, and that's the state it wants to draw the
1338 This signal is emitted when the layer of this layerable changes, i.e. this layerable is moved to
1349 Since QCPLayerable is an abstract base class, it can't be instantiated directly. Use one of the
1352 If \a plot is provided, it automatically places itself on the layer named \a targetLayer. If \a
1356 It is possible to provide \c nullptr as \a plot. In that case, you should assign a parent plot at
1362 parentLayerable does not become the QObject-parent (for memory management) of this layerable, \a
1363 plot does. It is not uncommon to set the QObject-parent to something else in the constructors of
1366QCPLayerable::QCPLayerable(QCustomPlot *plot, QString targetLayer, QCPLayerable *parentLayerable) :
1393 Sets the visibility of this layerable object. If an object is not visible, it will not be drawn
1403 Sets the \a layer of this layerable object. The object will be placed on top of the other objects
1450 Returns whether this layerable is visible, taking the visibility of the layerable parent and the
1451 visibility of this layerable's layer into account. This is the method that is consulted to decide
1455 subclasses, like in the case of \ref QCPLayoutElement), this function returns true only if this
1456 layerable has its visibility set to true and the parent layerable's \ref realVisibility returns
1461 return mVisible && (!mLayer || mLayer->visible()) && (!mParentLayerable || mParentLayerable.data()->realVisibility());
1469 distance couldn't be determined, -1.0 is returned. Further, if \a onlySelectable is true and the
1474 these cases this function thus returns a constant value greater zero but still below the parent
1482 parent QCustomPlot when the mouseReleaseEvent occurs, and the finally selected object is notified
1489 objects (like QCPAxis). This way, a possibly complex calculation to decide which part was clicked
1494 In the case of 1D Plottables (\ref QCPAbstractPlottable1D, like \ref QCPGraph or \ref QCPBars) \a
1497 You may pass \c nullptr as \a details to indicate that you are not interested in those selection
1503double QCPLayerable::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const
1513 Sets the parent plot of this layerable. Use this function once to set the parent plot if you have
1514 passed \c nullptr in the constructor. It can not be used to move a layerable from one QCustomPlot
1524 The parent plot change will be propagated to subclasses via a call to \ref parentPlotInitialized
1545 Sets the parent layerable of this layerable to \a parentLayerable. Note that \a parentLayerable does not
1549 layerables with a fully visible parent tree will return true for \ref realVisibility, and thus be
1561 Moves this layerable object to \a layer. If \a prepend is true, this object will be prepended to
1594 localAntialiased value as well as the overrides \ref QCustomPlot::setAntialiasedElements and \ref
1595 QCustomPlot::setNotAntialiasedElements. Which override enum this function takes into account is
1598void QCPLayerable::applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const
1610 This function is called by \ref initializeParentPlot, to allow subclasses to react on the setting
1611 of a parent plot. This is the case when \c nullptr was passed as parent plot in the constructor,
1615 QCustomPlot at first. When they are then added to a layout inside the QCustomPlot, the top level
1617 propagate the parent plot to all the children of the hierarchy, the top level element then uses
1631 Returns the selection category this layerable shall belong to. The selection category is used in
1647 Returns the clipping rectangle of this layerable object. By default, this is the viewport of the
1665 user. Subclasses should react to it by setting their selection state appropriately. The default
1670 QCustomPlot::setMultiSelectModifier). if \a additive is true, the selection state must be toggled
1673 Every selectEvent is preceded by a call to \ref selectTest, which has returned positively (i.e.
1674 returned a value greater than 0 and less than the selection tolerance of the parent QCustomPlot).
1677 selectEvent. Usually \a details is used to transfer which part was clicked, if it is a layerable
1678 that has multiple individually selectable parts (like QCPAxis). This way selectEvent doesn't need
1681 \a selectionStateChanged is an output parameter. If the pointer is non-null, this function must
1682 set the value either to true or false, depending on whether the selection state of this layerable
1683 was actually changed. For layerables that only are selectable as a whole and not in parts, this
1684 is simple: if \a additive is true, \a selectionStateChanged must also be set to true, because the
1685 selection toggles. If \a additive is false, \a selectionStateChanged is only set to true, if the
1690void QCPLayerable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
1721 event->pos(). The parameter \a details contains layerable-specific details about the hit, which
1722 were generated in the previous call to \ref selectTest. For example, One-dimensional plottables
1723 like \ref QCPGraph or \ref QCPBars convey the clicked data point in the \a details parameter, as
1728 layerable doesn't reimplement the \ref mousePressEvent or explicitly calls \c event->ignore() in
1729 its reimplementation, the event will be propagated to the next layerable in the stacking order.
1732 will receive all following calls to \ref mouseMoveEvent or \ref mouseReleaseEvent for this mouse
1765 This event gets called when the user releases the mouse button, after this layerable has become
1792 event->pos(). The parameter \a details contains layerable-specific details about the hit, which
1793 were generated in the previous call to \ref selectTest. For example, One-dimensional plottables
1794 like \ref QCPGraph or \ref QCPBars convey the clicked data point in the \a details parameter, as
1798 Similarly to \ref mousePressEvent, once a layerable has accepted the \ref mouseDoubleClickEvent,
1800 and \ref mouseReleaseEvent for this mouse interaction (a "mouse interaction" in this context ends
1822 The \c event->angleDelta() indicates how far the mouse wheel was turned, which is usually +/- 120
1824 accumulate to one event, making the delta larger. On the other hand, if the wheel has very smooth
1841////////////////////////////////////////////////////////////////////////////////////////////////////
1843////////////////////////////////////////////////////////////////////////////////////////////////////
1867 Makes sure \a lower is numerically smaller than \a upper. If this is not the case, the values are
1904 values that will appear in the plot)! It is intended only as a bound to compare against, e.g. to
1913 Larger absolute values would cause errors due to the 11-bit exponent of double precision numbers,
1917 values that will appear in the plot)! It is intended only as a bound to compare against, e.g. to
1949 Expands this range such that \a otherRange is contained in the new range. It is assumed that both
1952 If this range contains NaN as lower or upper bound, it will be replaced by the respective bound
1993 If this range contains NaN as lower or upper bound, the returned range's bound will be taken from
2010 If this range contains NaN as lower or upper bound, the returned range's bound will be set to \a
2023 Returns this range, possibly modified to not exceed the bounds provided as \a lowerBound and \a
2062 \a rangeFac *\a upper, whichever is closer to zero. Same procedure is used if the negative interval
2070 // can't have range spanning negative and positive values in log plot, so change range to fix it
2089 // find out whether negative or positive interval is wider to decide which sign domain will be chosen
2163////////////////////////////////////////////////////////////////////////////////////////////////////
2165////////////////////////////////////////////////////////////////////////////////////////////////////
2170 QCPDataRange holds two integers describing the begin (\ref setBegin) and end (\ref setEnd) index
2171 of a contiguous set of data points. The \a end index corresponds to the data point just after the
2174 Data Ranges are not bound to a certain plottable, thus they can be freely exchanged, created and
2176 used, which holds and manages multiple instances of \ref QCPDataRange. In most situations, \ref
2181 contains. Further, addition and subtraction operators (defined in \ref QCPDataSelection) can be
2182 used to join/subtract data ranges and data selections (or mixtures), to retrieve a corresponding
2185 %QCustomPlot's \ref dataselection "data selection mechanism" is based on \ref QCPDataSelection and
2188 \note Do not confuse \ref QCPDataRange with \ref QCPRange. A \ref QCPRange describes an interval
2209 Sets the begin of this data range. The \a begin index points to the first data point that is part
2229 Returns whether this range is valid. A valid range has a begin index greater or equal to 0, and
2232 \note Invalid ranges should be avoided and are never the result of any of QCustomPlot's methods
2233 (unless they are themselves fed with invalid ranges). Do not pass invalid ranges to QCustomPlot's
2235 invalid begin/end values while manipulating the range. An invalid range is not necessarily empty
2278 This method is very similar to \ref intersection, with one distinction: If this range and the \a
2279 other range share no intersection, the returned data range will be empty with begin and end set
2280 to the respective boundary side of \a other, at which this range is residing. (\ref intersection
2286 if (result.isEmpty()) // no intersection, preserve respective bounding side of otherRange as both begin and end of return value
2307 This method is very similar to \ref bounded, with one distinction: If this range and the \a other
2308 range share no intersection, the returned data range will be empty with begin and end set to 0.
2309 (\ref bounded would return a range with begin and end set to one of the boundaries of \a other,
2346////////////////////////////////////////////////////////////////////////////////////////////////////
2348////////////////////////////////////////////////////////////////////////////////////////////////////
2353 QCPDataSelection manages multiple instances of QCPDataRange in order to represent any (possibly
2358 \ref clear. Read access is provided by \ref dataRange, \ref dataRanges, \ref dataRangeCount, etc.
2363 addDataRange, with the parameter \a simplify explicitly set to false. This is useful if many data
2368 Use \ref enforceType to bring the data selection into a state complying with the constraints for
2387 Returns the number of ranges that make up the data selection. The ranges can be accessed by \ref
2395 Returns all data ranges that make up the data selection. If the data selection is simplified (the
2396 usual state of the selection, see \ref simplify), the ranges are sorted by ascending data point
2431 Note that both data selections must be in simplified state (the usual state of the selection, see
2458 Adds the data range \a other to this data selection, and then simplifies this data selection (see
2493 break; // since data ranges are sorted after the simplify() call, no ranges which contain other will come after this
2495 if (thisEnd > other.begin()) // ranges which don't fulfill this are entirely before other and can be ignored
2571 performance if adding a very large amount of data ranges successively. In this case, make sure to
2592 Sorts all data ranges by range begin index in ascending order, and then joins directly adjacent
2593 or overlapping ranges. This can reduce the number of individual data ranges in the selection, and
2596 This method is automatically called when using the addition/subtraction operators. The only case
2597 when \ref simplify is left to the user, is when calling \ref addDataRange, with the parameter \a
2628 Makes sure this data selection conforms to the specified \a type selection type. Before the type
2631 Depending on \a type, enforcing means adding new data points that were previously not part of the
2632 selection, or removing data points from the selection. If the current selection already conforms
2649 // whole selection isn't defined by data range, so don't change anything (is handled in plottable methods)
2701 Returns a data selection containing the points which are both in this data selection and in the
2704 A common use case is to limit an unknown data selection to the valid range of a data container,
2705 using \ref QCPDataContainer::dataRange as \a other. One can then safely iterate over the returned
2718 Returns a data selection containing the points which are both in this data selection and in the
2735 For example, this method can be used to retrieve all unselected segments by setting \a outerRange
2736 to the full data range of the plottable, and calling this method on a data selection holding the
2751 result.addDataRange(QCPDataRange(mDataRanges.at(i-1).end(), mDataRanges.at(i).begin()), false);
2764////////////////////////////////////////////////////////////////////////////////////////////////////
2766////////////////////////////////////////////////////////////////////////////////////////////////////
2774 according rect shape is drawn. At the begin, during, and after completion of the interaction, it
2777 The QCustomPlot instance connects own slots to the current selection rect instance, in order to
2785 If you wish to provide custom behaviour, e.g. a different visual representation of the selection
2814 Note that \a rect may have a negative width or height, if the selection is being dragged to the
2823 The user may cancel the selection interaction by pressing the escape key. In this case, \a event
2826 Note that \a rect may have a negative width or height, if the selection is being dragged to the
2835 Note that \a rect may have a negative width or height, if the selection is being dragged to the
2889 Sets the brush that will be used to fill the selection rect. By default the selection rect is not
2914 This method is called by QCustomPlot to indicate that a selection rect interaction was initiated.
2927 This method is called by QCustomPlot to indicate that an ongoing selection rect interaction needs
2940 This method is called by QCustomPlot to indicate that an ongoing selection rect interaction has
2953 This method is called by QCustomPlot when a key has been pressed by the user while the selection
2954 rect interaction is active. The default implementation allows to \ref cancel the interaction by
2993////////////////////////////////////////////////////////////////////////////////////////////////////
2995////////////////////////////////////////////////////////////////////////////////////////////////////
2998 \brief A margin group allows synchronization of margin sides if working with multiple layout elements.
3000 QCPMarginGroup allows you to tie a margin side of two or more layout elements together, such that
3008 layout elements. For example, if one QCPAxisRect is below another one in a grid layout, it will
3009 provide a cleaner look to the user if the left and right margins of the two axis rects are of the
3010 same size. The left axis of the top axis rect will then be at the same horizontal position as the
3015 QCPLayoutElement::setMarginGroup method. To completely break apart the margin group, either call
3032 Returns a list of all layout elements that have their margin \a side associated with this margin
3057 Returns whether this margin group is empty. If this function returns true, no layout elements use
3073 Clears this margin group. The synchronization of the margin sides that use this margin group is
3091 Returns the synchronized common margin for \a side. This is the margin value that will be used by
3096 group, and choosing the largest returned value. (QCPLayoutElement::minimumMargins is taken into
3141////////////////////////////////////////////////////////////////////////////////////////////////////
3143////////////////////////////////////////////////////////////////////////////////////////////////////
3146 \brief The abstract base class for all objects that form \ref thelayoutsystem "the layout system".
3148 This is an abstract base class. As such, it can't be instantiated directly, rather use one of its subclasses.
3152 between outer and inner rect is called its margin. The margin can either be set to automatic or
3153 manual (\ref setAutoMargins) on a per-side basis. If a side is set to manual, that margin can be
3154 set explicitly with \ref setMargins and will stay fixed at that value. If it's set to automatic,
3157 Layout elements can be placed in layouts (base class QCPLayout) like QCPLayoutGrid. The top level
3165 something. For example, QCPAxisRect, QCPLegend and QCPTextElement are of this category. This does
3180 Returns the inner rect of this layout element. The inner rect is the outer rect (\ref outerRect, \ref
3184 area is used to display peripheral graphics while the main content is in the inner rect. This is
3195 Returns the outer rect of this layout element. The outer rect is the inner rect expanded by the
3208 QCPLayerable(parentPlot), // parenthood is changed as soon as layout element gets inserted into a layout (except for top level layout)
3225 if (qobject_cast<QCPLayout*>(mParentLayout)) // the qobject_cast is just a safeguard in case the layout forgets to call clear() in its dtor and this dtor is called by QObject dtor
3230 Sets the outer rect of this layout element. If the layout element is inside a layout, the layout
3236 The layout element will adapt its inner \ref rect by applying the margins inward to the outer rect.
3251 sides, this function is used to manually set the margin on those sides. Sides that are still set
3273 The minimum values are not enforced on margin sides that were set to be under manual control via
3288 automatically, a minimum margin value may be provided with \ref setMinimumMargins. If a side is
3291 Margin sides that are under automatic control may participate in a \ref QCPMarginGroup (see \ref
3302 Sets the minimum size of this layout element. A parent layout tries to respect the \a size here
3305 If the parent layout size is not sufficient to satisfy all minimum size constraints of its child
3307 propagates the layout's size constraints to the outside by setting its own minimum QWidget size
3336 Sets the maximum size of this layout element. A parent layout tries to respect the \a size here
3368 The outer rect (\ref outerRect) includes the margins (e.g. in the case of a QCPAxisRect the axis
3386 Margin groups allow synchronizing specified margins across layout elements, see the documentation
3425 Updates the layout element and sub-elements. This function is automatically called before every
3427 UpdatePhase. The phases are run through in the order of the enum values. For details about what
3433 The default implementation executes the automatic margin mechanism in the \ref upMargins phase.
3442 // set the margins of this layout element according to automatic margin calculation, either directly or via a margin group:
3444 const QList<QCP::MarginSide> allMarginSides = QList<QCP::MarginSide>() << QCP::msLeft << QCP::msRight << QCP::msTop << QCP::msBottom;
3450 QCP::setMarginValue(newMargins, side, mMarginGroups[side]->commonMargin(side)); // this side is part of a margin group, so get the margin value from that group
3452 QCP::setMarginValue(newMargins, side, calculateAutoMargin(side)); // this side is not part of a group, so calculate the value directly
3464 Returns the suggested minimum size this layout element (the \ref outerRect) may be compressed to,
3467 if a minimum size (\ref setMinimumSize) was not set manually, parent layouts use the returned size
3473 The default implementation simply returns the sum of the horizontal margins for the width and the
3483 Returns the suggested maximum size this layout element (the \ref outerRect) may be expanded to,
3492 The default implementation simply returns \c QWIDGETSIZE_MAX for both width and height, implying
3522 QCPLayoutElement subclasses may reimplement this method to provide more specific selection test
3525double QCPLayoutElement::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const
3561 Returns the margin size for this \a side. It is used if automatic margins is enabled for this \a
3588////////////////////////////////////////////////////////////////////////////////////////////////////
3590////////////////////////////////////////////////////////////////////////////////////////////////////
3595 This is an abstract base class for layout elements whose main purpose is to define the position
3601 QCPLayout introduces a common interface for accessing and manipulating the child elements. Those
3603 simplify, \ref removeAt, \ref remove and \ref clear. Individual subclasses may add more functions
3605 QCPLayoutGrid adds functions that take row and column indices to access cells of the layout grid
3630 QCPLayoutGrid), so this function may return \c nullptr in those cases. You may use this function
3642 Note that some layouts don't remove the respective cell right away but leave an empty cell after
3654 Note that some layouts don't remove the respective cell right away but leave an empty cell after
3729 Removes and deletes the element at the provided \a index. Returns true on success. If \a index is
3732 This function internally uses \ref takeAt to remove the element from the layout and then deletes
3733 the returned element. Note that some layouts don't remove the respective cell right away but leave an
3750 Removes and deletes the provided \a element. Returns true on success. If \a element is not in the
3753 This function internally uses \ref takeAt to remove the element from the layout and then deletes
3771 Removes and deletes all layout elements in this layout. Finally calls \ref simplify to make sure
3790 sizeConstraintsChanged. If the parent is a QWidget (i.e. is the \ref QCustomPlot::plotLayout of
3791 QCustomPlot), calls QWidget::updateGeometry, so if the QCustomPlot widget is inside a Qt QLayout,
3804 Subclasses reimplement this method to update the position and sizes of the child elements/cells
3805 via calling their \ref QCPLayoutElement::setOuterRect. The default implementation does nothing.
3807 The geometry used as a reference is the inner \ref rect of this layout. Child elements should stay
3821 Associates \a el with this layout. This is done by setting the \ref QCPLayoutElement::layout, the
3827 This method is used by subclass specific methods that add elements to the layout. Note that this
3828 method only changes properties in \a el. The removal from the old layout and the insertion into
3847 Disassociates \a el from this layout. This is done by setting the \ref QCPLayoutElement::layout
3851 This method is used by subclass specific methods that remove elements from the layout (e.g. \ref
3871 It calculates the sizes of one-dimensional sections with provided constraints on maximum section
3872 sizes, minimum section sizes, relative stretch factors and the final total size of all sections.
3880 imposed, set all vector values to zero. If the \a minSizes entries add up to a value greater than
3881 \a totalSize, sections will be scaled smaller than the proposed minimum sizes. (In other words,
3882 not exceeding the allowed total size is taken to be more important than not going below minimum
3886 shall be scaled equally, set all values equal. If the first section shall be double the size of
3887 each individual other section, set the first number of \a stretchFactors to double the value of
3896QVector<int> QCPLayout::getSectionSizes(QVector<int> maxSizes, QVector<int> minSizes, QVector<double> stretchFactors, int totalSize) const
3900 qDebug() << Q_FUNC_INFO << "Passed vector sizes aren't equal:" << maxSizes << minSizes << stretchFactors;
3907 // if provided total size is forced smaller than total minimum size, ignore minimum sizes (squeeze sections):
3928 while (!unfinishedSections.isEmpty() && outerIterations < sectionCount*2) // the iteration check ist just a failsafe in case something really strange happens
3932 while (!unfinishedSections.isEmpty() && innerIterations < sectionCount*2) // the iteration check ist just a failsafe in case something really strange happens
3947 // check if that maximum is actually within the bounds of the total size (i.e. can we stretch all remaining sections so far that the found section
3953 if (nextMax < nextMaxLimit) // next maximum is actually hit, move forward to that point and fix the size of that section
3960 unfinishedSections.removeOne(nextId); // exclude the section that is now at maximum from further changes
3969 qDebug() << Q_FUNC_INFO << "Exceeded maximum expected inner iteration count, layouting aborted. Input was:" << maxSizes << minSizes << stretchFactors << totalSize;
3989 if (!minimumLockedSections.contains(i)) // only put sections that haven't hit their minimum back into the pool
3992 freeSize -= sectionSizes.at(i); // remove size of minimum locked sections from available space in next round
3994 // reset all section sizes to zero that are in unfinished sections (all others have been set to their minimum):
4012 It returns the minimum size that should finally be used for the outer rect of the passed layout
4017 QCPLayoutElement::setSizeConstraintRect), as well as the minimum size hint, if no manual minimum
4023 QSize minOuter = el->minimumSize(); // depending on sizeConstraitRect this might be with respect to inner rect, so possibly add margins in next four lines (preserving unset minimum of 0)
4037 It returns the maximum size that should finally be used for the outer rect of the passed layout
4042 QCPLayoutElement::setSizeConstraintRect), as well as the maximum size hint, if no manual maximum
4048 QSize maxOuter = el->maximumSize(); // depending on sizeConstraitRect this might be with respect to inner rect, so possibly add margins in next four lines (preserving unset maximum of QWIDGETSIZE_MAX)
4049 if (maxOuter.width() < QWIDGETSIZE_MAX && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect)
4051 if (maxOuter.height() < QWIDGETSIZE_MAX && el->sizeConstraintRect() == QCPLayoutElement::scrInnerRect)
4059////////////////////////////////////////////////////////////////////////////////////////////////////
4061////////////////////////////////////////////////////////////////////////////////////////////////////
4066 Elements are laid out in a grid with configurable stretch factors (\ref setColumnStretchFactor,
4069 Elements can be added to cells via \ref addElement. The grid is expanded if the specified row or
4070 column doesn't exist yet. Whether a cell contains a valid layout element can be checked with \ref
4071 hasElement, that element can be retrieved with \ref element. If rows and columns that only have
4077 column, the grid layout will choose the position according to the current \ref setFillOrder and
4114 // clear all child layout elements. This is important because only the specific layouts know how
4122 Returns \c nullptr if either the row/column is invalid or if the cell is empty. In those cases, a
4123 qDebug message is printed. To check whether a cell exists and isn't empty, use \ref hasElement.
4147 Adds the \a element to cell with \a row and \a column. If \a element is already in a layout, it
4154 Use the overload of this method without explicit row/column index to place the element according
4216 Returns whether the cell at \a row and \a column exists and contains a valid element, i.e. isn't
4232 Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond
4256 Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond
4274 qDebug() << Q_FUNC_INFO << "Invalid stretch factor, must be positive:" << mColumnStretchFactors.at(i);
4285 Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond
4309 Stretch factors control the relative sizes of rows and columns. Cells will not be resized beyond
4357 addElement(QCPLayoutElement*) will start to fill the next row or column, respectively. It depends
4363 rearrange set to true (the actual fill order doesn't need to be changed for the rearranging to be
4381 The specified \a order defines whether rows or columns are filled first. Using \ref setWrap, you
4382 can control at which row/column count wrapping into the next column/row will occur. If you set it
4387 If you want to have all current elements arranged in the new order, set \a rearrange to true. The
4428 Expands the layout to have \a newRowCount rows and \a newColumnCount columns. So the last valid
4431 If the current column/row count is already larger or equal to \a newColumnCount/\a newRowCount,
4488 newIndex range from 0 (inserts a column at the left) to \a columnCount (appends a column at the
4516 indices increase left to right and then top to bottom. If it is \ref foColumnsFirst, the indices
4519 For the returned index to be valid, \a row and \a column must be valid indices themselves, i.e.
4547 indices increase left to right and then top to bottom. If it is \ref foColumnsFirst, the indices
4597 QVector<int> colWidths = getSectionSizes(maxColWidths, minColWidths, mColumnStretchFactors.toVector(), mRect.width()-totalColSpacing);
4598 QVector<int> rowHeights = getSectionSizes(maxRowHeights, minRowHeights, mRowStretchFactors.toVector(), mRect.height()-totalRowSpacing);
4799void QCPLayoutGrid::getMinimumRowColSizes(QVector<int> *minColWidths, QVector<int> *minRowHeights) const
4825 row. The maximum width of a column is the smallest maximum width of any element's outer rect in
4832void QCPLayoutGrid::getMaximumRowColSizes(QVector<int> *maxColWidths, QVector<int> *maxRowHeights) const
4853////////////////////////////////////////////////////////////////////////////////////////////////////
4855////////////////////////////////////////////////////////////////////////////////////////////////////
4864 addElement(QCPLayoutElement *element, const QRectF &rect). If the first method is used, the inset
4865 placement will default to \ref ipBorderAligned and the element will be aligned according to the
4866 \a alignment parameter. The second method defaults to \ref ipFree and allows placing elements at
4869 The alignment or rect can be set via \ref setInsetAlignment or \ref setInsetRect, respectively.
4893 // clear all child layout elements. This is important because only the specific layouts know how
4976 If the inset placement (\ref setInsetPlacement) is \ref ipFree, this function is used to set the
4979 \a rect is given in fractions of the whole inset layout rect. So an inset with rect (0, 0, 1, 1)
4980 will span the entire layout. An inset with rect (0.6, 0.1, 0.35, 0.35) will be in the top right
5023 else insetRect.moveLeft(int( rect().x()+rect().width()*0.5-finalMinSize.width()*0.5 )); // default to Qt::AlignHCenter
5026 else insetRect.moveTop(int( rect().y()+rect().height()*0.5-finalMinSize.height()*0.5 )); // default to Qt::AlignVCenter
5029 }
5030}
5086 sensitive. If the selectTest method of any of the child elements returns a positive number for \a
5088 tolerance. The inset layout is not selectable itself by default. So if \a onlySelectable is true,
5093double QCPLayoutInset::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const
5140 \a rect is given in fractions of the whole inset layout rect. So an inset with rect (0, 0, 1, 1)
5141 will span the entire layout. An inset with rect (0.6, 0.1, 0.35, 0.35) will be in the top right
5166////////////////////////////////////////////////////////////////////////////////////////////////////
5168////////////////////////////////////////////////////////////////////////////////////////////////////
5175 For every ending a line-like item has, an instance of this class exists. For example, QCPItemLine
5178 The styles themselves are defined via the enum QCPLineEnding::EndingStyle. Most decorations can
5180 the ending decoration (e.g. direction an arrow is pointing) is controlled by the line-like item.
5181 For example, when both endings of a QCPItemLine are set to be arrows, they will point to opposite
5204QCPLineEnding::QCPLineEnding(QCPLineEnding::EndingStyle style, double width, double length, bool inverted) :
5232 Sets the length of the ending decoration, if the style supports it. On arrows, for example, the
5243 Sets whether the ending decoration shall be inverted. For example, an arrow decoration will point
5246 Note that also the \a width direction is inverted. For symmetrical ending styles like arrows or
5260 This is relevant for clipping. Only omit painting of the decoration when the position where the
5293 both have the same \ref setLength value, because the spike arrow has an inward curved back, which
5326 Draws the line ending with the specified \a painter at the position \a pos. The direction of the
5329void QCPLineEnding::draw(QCPPainter *painter, const QCPVector2D &pos, const QCPVector2D &dir) const
5435 if (!qFuzzyIsNull(painter->pen().widthF()) || painter->modes().testFlag(QCPPainter::pmNonCosmetic))
5461////////////////////////////////////////////////////////////////////////////////////////////////////
5463////////////////////////////////////////////////////////////////////////////////////////////////////
5573void QCPLabelPainterPrivate::drawTickLabel(QCPPainter *painter, const QPointF &tickPos, const QString &text)
5578 // for circular axes, the anchor side is determined depending on the quadrant of tickPos with respect to mCircularReference
5582 } else if (mAnchorMode == amSkewedRotated) // in this mode every label is individually rotated to match circle tangent
5590 realSide = rotationCorrectedSide(realSide, realRotation); // rotation angles may change the true anchor side of the label
5591 drawLabelMaybeCached(painter, mFont, mColor, getAnchorPos(tickPos), realSide, realRotation, text);
5596 Returns the size ("margin" in QCPAxisRect context, so measured perpendicular to the axis backbone
5615 result += QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width();
5620 // calculate size of axis label (only height needed, because left/right labels are rotated by 90 degrees):
5625 bounds = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter | Qt::AlignVCenter, label);
5636 method is called automatically if any parameters have changed that invalidate the cached labels,
5648 return value of this method hasn't changed since the last redraw, the respective label parameters
5670 for the bottom axis, \a position would indicate the horizontal pixel position (not coordinate),
5673 In order to later draw the axis label in a place that doesn't overlap with the tick labels, the
5675 drawTickLabel calls during the process of drawing all tick labels of one axis. In every call, \a
5683void QCPLabelPainterPrivate::drawLabelMaybeCached(QCPPainter *painter, const QFont &font, const QColor &color, const QPointF &pos, AnchorSide side, double rotation, const QString &text)
5689 if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && !painter->modes().testFlag(QCPPainter::pmNoCaching)) // label caching enabled
5692 CachedLabel *cachedLabel = mLabelCache.take(QString::fromUtf8(key)); // attempt to take label from cache (don't use object() because we want ownership/prevent deletion during our operations, we re-insert it afterwards)
5698 // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels):
5704 labelClippedByBorder = labelAnchor.x()+cachedLabel->offset.x()+cachedLabel->pixmap.width()/mParentPlot->bufferDevicePixelRatio() > viewportRect.right() || labelAnchor.x()+cachedLabel->offset.x() < viewportRect.left();
5706 labelClippedByBorder = labelAnchor.y()+cachedLabel->offset.y()+cachedLabel->pixmap.height()/mParentPlot->bufferDevicePixelRatio() > viewportRect.bottom() || labelAnchor.y()+cachedLabel->offset.y() < viewportRect.top();
5712 finalSize = cachedLabel->pixmap.size()/mParentPlot->bufferDevicePixelRatio(); // TODO: collect this in a member rect list?
5718 // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels):
5724 labelClippedByBorder = finalPosition.x()+(labelData.rotatedTotalBounds.width()+labelData.rotatedTotalBounds.left()) > viewportRect.right() || finalPosition.x()+labelData.rotatedTotalBounds.left() < viewportRect.left();
5783 Draws the tick label specified in \a labelData with \a painter at the pixel positions \a x and \a
5788void QCPLabelPainterPrivate::drawText(QCPPainter *painter, const QPointF &pos, const LabelData &labelData) const
5806 painter->drawText(labelData.baseBounds.width()+1+labelData.expBounds.width(), 0, 0, 0, Qt::TextDontClip, labelData.suffixPart);
5808 painter->drawText(labelData.baseBounds.width()+1, 0, labelData.expBounds.width(), labelData.expBounds.height(), Qt::TextDontClip, labelData.expPart);
5811 painter->drawText(0, 0, labelData.totalBounds.width(), labelData.totalBounds.height(), Qt::TextDontClip | Qt::AlignHCenter, labelData.basePart);
5836 Transforms the passed \a text and \a font to a tickLabelData structure that can then be further
5837 processed by \ref getTickLabelDrawOffset and \ref drawTickLabel. It splits the text into base and
5840QCPLabelPainterPrivate::LabelData QCPLabelPainterPrivate::getTickLabelData(const QFont &font, const QColor &color, double rotation, AnchorSide side, const QString &text) const
5849 int ePos = -1; // first index of exponent part, text before that will be basePart, text until eLast will be expPart
5857 while (eLast+1 < text.size() && (text.at(eLast+1) == QLatin1Char('+') || text.at(eLast+1) == QLatin1Char('-') || text.at(eLast+1).isDigit()))
5859 if (eLast > ePos) // only if also to right of 'e' is a digit/+/- interpret it as beautifiable power
5866 if (result.baseFont.pointSizeF() > 0) // might return -1 if specified with setPixelSize, in that case we can't do correction in next line
5867 result.baseFont.setPointSizeF(result.baseFont.pointSizeF()+0.05); // QFontMetrics.boundingRect has a bug for exact point sizes that make the results oscillate due to internal rounding
5872 // split text into parts of number/symbol that will be drawn normally and part that will be drawn as exponent:
5875 // in log scaling, we want to turn "1*10^n" into "10^n", else add multiplication sign and decimal base:
5882 while (result.expPart.length() > 2 && result.expPart.at(1) == QLatin1Char('0')) // length > 2 so we leave one zero when numberFormatChar is 'e'
5893 result.baseBounds = baseFontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.basePart);
5894 result.expBounds = QFontMetrics(result.expFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.expPart);
5896 result.suffixBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.suffixPart);
5897 result.totalBounds = result.baseBounds.adjusted(0, 0, result.expBounds.width()+result.suffixBounds.width()+2, 0); // +2 consists of the 1 pixel spacing between base and exponent (see drawTickLabel) and an extra pixel to include AA
5901 result.totalBounds = baseFontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter, result.basePart);
5913 labelData.transform.rotate(labelData.rotation); // rotates effectively clockwise (due to flipped y axis of painter vs widget coordinate system)
5917 labelData.transform.translate(0, -labelData.totalBounds.height()+mLetterDescent+mLetterCapHeight); // shifts origin to true top of capital (or number) characters
5921 else if (labelData.side == asTop || labelData.side == asBottom) // anchor is centered horizontally
5924 if (labelData.side == asTopRight || labelData.side == asRight || labelData.side == asBottomRight) // anchor is at right
5926 if (labelData.side == asBottomLeft || labelData.side == asBottom || labelData.side == asBottomRight) // anchor is at bottom (no elseif!)
5932 Simulates the steps done by \ref placeTickLabel by calculating bounding boxes of the text label
5933 to be drawn, depending on number format etc. Since only the largest tick label is wanted for the
5938void QCPLabelPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const
5942 if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && mLabelCache.contains(text)) // label caching enabled and have cached label
5960QCPLabelPainterPrivate::CachedLabel *QCPLabelPainterPrivate::createCachedLabel(const LabelData &labelData) const
5967 result->pixmap = QPixmap(labelData.rotatedTotalBounds.size()*mParentPlot->bufferDevicePixelRatio());
5980 // offset is between label anchor and topleft of cache pixmap, so pixmap can be drawn at pos+offset to make the label anchor appear at pos.
5988QByteArray QCPLabelPainterPrivate::cacheKey(const QString &text, const QColor &color, double rotation, AnchorSide side) const
5996QCPLabelPainterPrivate::AnchorSide QCPLabelPainterPrivate::skewedAnchorSide(const QPointF &tickPos, double sideExpandHorz, double sideExpandVert) const
6022QCPLabelPainterPrivate::AnchorSide QCPLabelPainterPrivate::rotationCorrectedSide(AnchorSide side, double rotation) const
6028 if (!qFuzzyCompare(qAbs(rotation), 90)) // avoid graphical collision with anchor tangent (e.g. axis line) when rotating, so change anchor side appropriately:
6036 } else // for full rotation by +/-90 degrees, other sides are more appropriate for centering on anchor:
6054 mLetterCapHeight = fm.tightBoundingRect(QLatin1String("8")).height(); // this method is slow, that's why we query it only upon font change
6063////////////////////////////////////////////////////////////////////////////////////////////////////
6065////////////////////////////////////////////////////////////////////////////////////////////////////
6074 This base class generates normal tick coordinates and numeric labels for linear axes. It picks a
6087 <tr><td style="text-align:right; padding: 0 1em">QCPAxisTickerFixed</td><td>\image html axisticker-fixed.png</td></tr>
6088 <tr><td style="text-align:right; padding: 0 1em">QCPAxisTickerLog</td><td>\image html axisticker-log.png</td></tr>
6089 <tr><td style="text-align:right; padding: 0 1em">QCPAxisTickerPi</td><td>\image html axisticker-pi.png</td></tr>
6090 <tr><td style="text-align:right; padding: 0 1em">QCPAxisTickerText</td><td>\image html axisticker-text.png</td></tr>
6091 <tr><td style="text-align:right; padding: 0 1em">QCPAxisTickerDateTime</td><td>\image html axisticker-datetime.png</td></tr>
6092 <tr><td style="text-align:right; padding: 0 1em">QCPAxisTickerTime</td><td>\image html axisticker-time.png
6102 In the simplest case you might wish to just generate different tick steps than the other tickers,
6109 getTickLabel, but your reimplementations don't necessarily need to do so. For example in the case
6112 The sub tick count between major ticks can be controlled with \ref getSubTickCount. Full sub tick
6145 Sets how many ticks this ticker shall aim to generate across the axis range. Note that \a count
6146 is not guaranteed to be matched exactly, as generating readable tick intervals may conflict with
6161 Sets the mathematical coordinate (or "offset") of the zeroth tick. This tick coordinate is just a
6164 By default \a origin is zero, which for example yields ticks {-5, 0, 5, 10, 15,...} when the tick
6165 step is five. If \a origin is now set to 1 instead, the correspondingly generated ticks would be
6174 This is the method called by QCPAxis in order to actually generate tick coordinates (\a ticks),
6178 specified \a locale, \a formatChar and number \a precision, however this might be different (or
6182 The output parameters \a subTicks and \a tickLabels are optional (set them to \c nullptr if not
6183 needed) and are respectively filled with sub tick coordinates, and tick label strings belonging
6186void QCPAxisTicker::generate(const QCPRange &range, const QLocale &locale, QChar formatChar, int precision, QVector<double> &ticks, QVector<double> *subTicks, QVector<QString> *tickLabels)
6191 trimTicks(range, ticks, true); // trim ticks to visible range plus one outer tick on each side (incase a subclass createTickVector creates more)
6218 implementation, it should reimplement this method. See \ref cleanMantissa for a possible helper
6223 double exactStep = range.size()/double(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers
6273 case 5: result = 4; break; // 5.5 -> 1.1 substep (won't occur with default getTickStep from here on)
6288 This method returns the tick label string as it should be printed under the \a tick coordinate.
6289 If a textual number is returned, it should respect the provided \a locale, \a formatChar and \a
6292 If the returned value contains exponentials of the form "2e5" and beautifully typeset powers is
6293 enabled in the QCPAxis number format (\ref QCPAxis::setNumberFormat), the exponential part will
6297QString QCPAxisTicker::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision)
6308 reimplement this method. Depending on the purpose of the subclass it doesn't necessarily need to
6311QVector<double> QCPAxisTicker::createSubTickVector(int subTickCount, const QVector<double> &ticks)
6330 implementation generates ticks with a spacing of \a tickStep (mathematically starting at the tick
6337 If a QCPAxisTicker subclass needs maximal control over the generated ticks, it should reimplement
6346 qint64 firstStep = qint64(floor((range.lower-mTickOrigin)/tickStep)); // do not use qFloor here, or we'll lose 64 bit precision
6358 Returns a vector containing all tick label strings corresponding to the tick coordinates provided
6365QVector<QString> QCPAxisTicker::createLabelVector(const QVector<double> &ticks, const QLocale &locale, QChar formatChar, int precision)
6377 keepOneOutlier is true, it preserves one tick just outside the range on both sides, if present.
6381void QCPAxisTicker::trimTicks(const QCPRange &range, QVector<double> &ticks, bool keepOneOutlier) const
6427 QVector<double>::const_iterator it = std::lower_bound(candidates.constBegin(), candidates.constEnd(), target);
6438 Returns the decimal mantissa of \a input. Optionally, if \a magnitude is not set to zero, it also
6452 Returns a number that is close to \a input but has a clean, easier human readable mantissa. How
6483////////////////////////////////////////////////////////////////////////////////////////////////////
6485////////////////////////////////////////////////////////////////////////////////////////////////////
6491 This QCPAxisTicker subclass generates ticks that correspond to real calendar dates and times. The
6492 plot axis coordinate is interpreted as Unix Time, so seconds since Epoch (January 1, 1970, 00:00
6493 UTC). This is also used for example by QDateTime in the <tt>toTime_t()/setTime_t()</tt> methods
6494 with a precision of one second. Since Qt 4.7, millisecond accuracy can be obtained from QDateTime
6495 by using <tt>QDateTime::fromMSecsSinceEpoch()/1000.0</tt>. The static methods \ref dateTimeToKey
6499 The format of the date/time display in the tick labels is controlled with \ref setDateTimeFormat.
6505 ticks will be positioned on 1. January of every year. This is intuitive but, due to leap years,
6506 will result in slightly unequal tick intervals (visually unnoticeable). The same can be seen in
6510 If you would like to change the date/time that is used as a (mathematical) starting date for the
6512 QDateTime. If you pass 15. July, 9:45 to this method, the yearly ticks will end up on 15. July at
6518 \note If you rather wish to display relative times in terms of days, hours, minutes, seconds and
6536 Sets the format in which dates and times are displayed as tick labels. For details about the \a
6543 <tr><td>\c ddd</td><td>The abbreviated localized day name (e.g. 'Mon' to 'Sun'). Uses the system locale to localize the name, i.e. QLocale::system().</td></tr>
6544 <tr><td>\c dddd</td><td>The long localized day name (e.g. 'Monday' to 'Sunday'). Uses the system locale to localize the name, i.e. QLocale::system().</td></tr>
6547 <tr><td>\c MMM</td><td>The abbreviated localized month name (e.g. 'Jan' to 'Dec'). Uses the system locale to localize the name, i.e. QLocale::system().</td></tr>
6548 <tr><td>\c MMMM</td><td>The long localized month name (e.g. 'January' to 'December'). Uses the system locale to localize the name, i.e. QLocale::system().</td></tr>
6550 <tr><td>\c yyyy</td><td>The year as a four digit number. If the year is negative, a minus sign is prepended, making five characters.</td></tr>
6551 <tr><td>\c h</td><td>The hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display)</td></tr>
6552 <tr><td>\c hh</td><td>The hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display)</td></tr>
6553 <tr><td>\c H</td><td>The hour without a leading zero (0 to 23, even with AM/PM display)</td></tr>
6554 <tr><td>\c HH</td><td>The hour with a leading zero (00 to 23, even with AM/PM display)</td></tr>
6558 <tr><td>\c ss</td><td>The whole second, with a leading zero where applicable (00 to 59)</td></tr>
6559 <tr><td>\c z</td><td>The fractional part of the second, to go after a decimal point, without trailing zeroes (0 to 999). Thus "s.z" reports the seconds to full available (millisecond) precision without trailing zeroes.</td></tr>
6560 <tr><td>\c zzz</td><td>The fractional part of the second, to millisecond precision, including trailing zeroes where applicable (000 to 999).</td></tr>
6561 <tr><td>\c AP or \c A</td><td>Use AM/PM display. A/AP will be replaced by an upper-case version of either QLocale::amText() or QLocale::pmText().</td></tr>
6562 <tr><td>\c ap or \c a</td><td>Use am/pm display. a/ap will be replaced by a lower-case version of either QLocale::amText() or QLocale::pmText().</td></tr>
6566 Newlines can be inserted with \c "\n", literal strings (even when containing above expressions)
6567 by encapsulating them using single-quotes. A literal single quote can be generated by using two
6581 <tt>Qt::LocalTime</tt>. However, if the displayed tick labels shall be given in UTC, set \a spec
6584 Tick labels corresponding to other time zones can be achieved with \ref setTimeZone (which sets
6597 Sets the time zone that is used for creating the tick labels from corresponding dates/times. The
6610 Sets the tick origin (see \ref QCPAxisTicker::setTickOrigin) in seconds since Epoch (1. Jan 1970,
6615 example, If you pass 15. July, 9:45 to this method and the tick interval happens to be one tick
6627 example, If you pass 15. July, 9:45 to this method and the tick interval happens to be one tick
6637 Returns a sensible tick step with intervals appropriate for a date-time-display, such as weekly,
6641 createTickVector, but only as a guiding value requiring some correction for each individual tick
6642 interval. Otherwise this would lead to unintuitive date displays, e.g. jumping between first day
6650 double result = range.size()/double(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers
6652 mDateStrategy = dsNone; // leaving it at dsNone means tick coordinates will not be tuned in any special way in createTickVector
6653 if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds
6659 << 1 << 2.5 << 5 << 10 << 15 << 30 << 60 << 2.5*60 << 5*60 << 10*60 << 15*60 << 30*60 << 60*60 // second, minute, hour range
6677 Returns a sensible sub tick count with intervals appropriate for a date-time-display, such as weekly,
6712 Generates a date/time tick label for tick coordinate \a tick, based on the currently set format
6718QString QCPAxisTickerDateTime::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision)
6735 non-uniform tick intervals but intuitive tick labels, e.g. falling on the same day of each month.
6746 QDateTime uniformDateTime = keyToDateTime(mTickOrigin); // the time of this datetime will be set for all other ticks, if possible
6756 QDateTime uniformDateTime = keyToDateTime(mTickOrigin); // this day (in month) and time will be set for all other ticks, if possible
6762 int thisUniformDay = uniformDateTime.date().day() <= tickDateTime.date().daysInMonth() ? uniformDateTime.date().day() : tickDateTime.date().daysInMonth(); // don't exceed month (e.g. try to set day 31 in February)
6763 if (thisUniformDay-tickDateTime.date().day() < -15) // with leap years involved, date month may jump backwards or forwards, and needs to be corrected before setting day
6765 else if (thisUniformDay-tickDateTime.date().day() > 15) // with leap years involved, date month may jump backwards or forwards, and needs to be corrected before setting day
6779 The accuracy achieved by this method is one millisecond, irrespective of the used Qt version (it
6799 The accuracy achieved by this method is one millisecond, irrespective of the used Qt version (it
6815 A convenience method which turns a QDate object into a double value that corresponds to seconds
6840////////////////////////////////////////////////////////////////////////////////////////////////////
6842////////////////////////////////////////////////////////////////////////////////////////////////////
6850 The format of the time display in the tick labels is controlled with \ref setTimeFormat and \ref
6851 setFieldWidth. The time coordinate is in the unit of seconds with respect to the time coordinate
6852 zero. Unlike with QCPAxisTickerDateTime, the ticks don't correspond to a specific calendar date
6856 largest available unit in the format specified with \ref setTimeFormat, any time spans above will
6858 coordinate value 7815 (being 2 hours, 10 minutes and 15 seconds) is created, the resulting tick
6859 label will show "130:15" (130 minutes, 15 seconds). If the format string is "%h:%m:%s", the hour
6860 unit will be used and the label will thus be "02:10:15". Negative times with respect to the axis
6866 Here is an example of a time axis providing time information in days, hours and minutes. Due to
6875 \note If you rather wish to display calendar dates and times, have a look at QCPAxisTickerDateTime
6958 Returns the tick step appropriate for time displays, depending on the provided \a range and the
6959 smallest available time unit in the current format (\ref setTimeFormat). For example if the unit
6960 of seconds isn't available in the format, this method will not generate steps (like 2.5 minutes)
6967 double result = range.size()/double(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers
6969 if (result < 1) // ideal tick step is below 1 second -> use normal clean mantissa algorithm in units of seconds
7037 Returns the tick label corresponding to the provided \a tick and the configured format and field
7042QString QCPAxisTickerTime::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision)
7049 double values[tuDays+1]; // contains the msec/sec/min/... value with its respective modulo (e.g. minute 0..59)
7050 double restValues[tuDays+1]; // contains the msec/sec/min/... value as if it's the largest available unit and thus consumes the remaining time
7072 Replaces all occurrences of the format pattern belonging to \a unit in \a text with the specified
7075void QCPAxisTickerTime::replaceUnit(QString &text, QCPAxisTickerTime::TimeUnit unit, int value) const
7089////////////////////////////////////////////////////////////////////////////////////////////////////
7091////////////////////////////////////////////////////////////////////////////////////////////////////
7097 This QCPAxisTicker subclass generates ticks with a fixed tick step set with \ref setTickStep. It
7104 Another case is when a certain number has a special meaning and axis ticks should only appear at
7125 The axis ticker will only use this tick step when generating axis ticks. This might cause a very
7127 setScaleStrategy it is possible to relax the fixed step and also allow multiples or powers of \a
7128 step. This will enable the ticker to reduce the number of ticks to a reasonable amount (see \ref
7156 This method either returns the specified tick step exactly, or, if the scale strategy is not \ref
7171 double exactStep = range.size()/double(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers
7179 double exactStep = range.size()/double(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers
7191////////////////////////////////////////////////////////////////////////////////////////////////////
7193////////////////////////////////////////////////////////////////////////////////////////////////////
7200 coordinates and associated strings. They can be passed as a whole with \ref setTicks or one at a
7201 time with \ref addTick. Alternatively you can directly access the internal storage via \ref ticks
7206 If you are updating the ticks of this ticker regularly and in a dynamic fasion (e.g. dependent on
7221 You can access the map directly in order to add, remove or manipulate ticks, as an alternative to
7241 An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks
7253 Sets the ticks that shall appear on the axis. The entries of \a positions correspond to the axis
7259void QCPAxisTickerText::setTicks(const QVector<double> &positions, const QVector<QString> &labels)
7266 Sets the number of sub ticks that shall appear between ticks. For QCPAxisTickerText, there is no
7267 automatic sub tick count calculation. So if sub ticks are needed, they must be configured with this
7281 An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks
7292 Adds a single tick to the axis at the given axis coordinate \a position, with the provided tick \a
7304 Adds the provided \a ticks to the ones already existing. The map key of \a ticks corresponds to
7307 An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks
7323 Adds the provided ticks to the ones already existing. The entries of \a positions correspond to
7324 the axis coordinates, and the entries of \a labels are the respective strings that will appear as
7327 An alternative to manipulate ticks is to directly access the internal storage with the \ref ticks
7332void QCPAxisTickerText::addTicks(const QVector<double> &positions, const QVector<QString> &labels)
7365 Returns the tick label which corresponds to the key \a tick in the internal tick storage. Since
7370QString QCPAxisTickerText::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision)
7380 available, one tick above and below the range is provided in addition, to allow possible sub tick
7410////////////////////////////////////////////////////////////////////////////////////////////////////
7412////////////////////////////////////////////////////////////////////////////////////////////////////
7414 \brief Specialized axis ticker to display ticks in units of an arbitrary constant, for example pi
7418 This QCPAxisTicker subclass generates ticks that are expressed with respect to a given symbolic
7422 Ticks may be generated at fractions of the symbolic constant. How these fractions appear in the
7444 Sets how the symbol part (which is always a suffix to the number) shall appear in the axis tick
7447 If a space shall appear between the number and the symbol, make sure the space is contained in \a
7490 Returns the tick step, using the constant's value (\ref setPiValue) as base unit. In consequence
7498 mPiTickStep = range.size()/mPiValue/double(mTickCount+1e-10); // mTickCount ticks on average, the small addition is to prevent jitter on exact integers
7519 formatting of the fraction is done according to the specified \ref setFractionStyle. The appended
7524QString QCPAxisTickerPi::getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision)
7555 Takes the fraction given by \a numerator and \a denominator and modifies the values to make sure
7579 Takes the fraction given by \a numerator and \a denominator and returns a string representation.
7583 simplifies the passed fraction to an irreducible form using \ref simplifyFraction and factors out
7618 .arg(integerPart > 0 ? QString::number(integerPart)+QLatin1String(" ") : QString(QLatin1String("")))
7697////////////////////////////////////////////////////////////////////////////////////////////////////
7699////////////////////////////////////////////////////////////////////////////////////////////////////
7712 powers, so a format string of <tt>"eb"</tt>. This will result in the following axis tick labels:
7719 Note that the nature of logarithmic ticks imply that there exists a smallest possible tick step,
7720 corresponding to one multiplication by the log base. If the user zooms in further than that, no
7721 new ticks would appear, leading to very sparse or even no axis ticks on the axis. To prevent this
7722 situation, this ticker falls back to regular tick generation if the axis range would be covered
7738 Sets the logarithm base used for tick coordinate generation. The ticks will be placed at integer
7752 Sets the number of sub ticks in a tick interval. Within each interval, the sub ticks are spaced
7756 Note that \a subTicks is the number of sub ticks (not sub intervals) in one tick interval. So in
7771 Returns the sub tick count specified in \ref setSubTickCount. For QCPAxisTickerLog, there is no
7784 Creates ticks with a spacing given by the logarithm base and an increasing integer power in the
7785 provided \a range. The step in which the power increases tick by tick is chosen in order to keep
7790 function falls back to the regular QCPAxisTicker::createTickVector, which then uses \a tickStep.
7800 if (baseTickCount < 1.6) // if too few log ticks would be visible in axis range, fall back to regular tick vector generation
7806 while (currentTick < range.upper && currentTick > 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case
7814 if (baseTickCount < 1.6) // if too few log ticks would be visible in axis range, fall back to regular tick vector generation
7820 while (currentTick < range.upper && currentTick < 0) // currentMag might be zero for ranges ~1e-300, just cancel in that case
7839////////////////////////////////////////////////////////////////////////////////////////////////////
7841////////////////////////////////////////////////////////////////////////////////////////////////////
7846 This class is tightly bound to QCPAxis. Every axis owns a grid instance and uses it to draw the
7851 layers (both QCPAxis and QCPGrid inherit from QCPLayerable). Thus it is possible to have the grid
7924 Zero lines are lines at value coordinate 0 which may be drawn with a different pen than other grid
7952 Draws grid lines and sub grid lines at the positions of (sub) ticks of the parent axis, spanning
7980 if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0)
7991 painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top()));
8003 painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top()));
8009 if (mZeroLinePen.style() != Qt::NoPen && mParentAxis->mRange.lower < 0 && mParentAxis->mRange.upper > 0)
8020 painter->drawLine(QLineF(mParentAxis->mAxisRect->left(), t, mParentAxis->mAxisRect->right(), t));
8055 painter->drawLine(QLineF(t, mParentAxis->mAxisRect->bottom(), t, mParentAxis->mAxisRect->top()));
8068////////////////////////////////////////////////////////////////////////////////////////////////////
8070////////////////////////////////////////////////////////////////////////////////////////////////////
8075 Usually doesn't need to be instantiated externally. Access %QCustomPlot's default four axes via
8085 <center>Overview of the spacings and paddings that define the geometry of an axis. The dashed gray line
8088 Each axis holds an instance of QCPAxisTicker which is used to generate the tick coordinates and
8089 tick labels. You can access the currently installed \ref ticker or set a new one (possibly one of
8106 Returns the \ref QCPGrid instance belonging to this axis. Access it to set details about the way the
8121 This method returns either 1 or -1. If it returns 1, then going in the positive direction along
8122 the orientation of the axis in pixels corresponds to going from lower to higher axis coordinates.
8123 On the other hand, if this method returns -1, going to smaller pixel values corresponds to going
8126 For example, this is useful to easily shift axis coordinates by a certain amount given in pixels,
8130 double newKey = keyAxis->pixelToCoord(keyAxis->coordToPixel(oldKey)+10*keyAxis->pixelOrientation());
8133 \a newKey will then contain a key that is ten pixels towards higher keys, starting from \a oldKey.
8140 \ref QCPAxisTicker with this method and modify basic properties such as the approximate tick count
8143 You can gain more control over the axis ticks by setting a different \ref QCPAxisTicker subclass, see
8146 Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis
8158 setRange slot of another axis to communicate the new range to the other axis, in order for it to
8161 You may also manipulate/correct the range with \ref setRange in a slot connected to this signal.
8162 This is useful if for example a maximum range span shall not be exceeded, or if the lower/upper
8163 range shouldn't go beyond certain values (see \ref QCPRange::bounded). For example, the following
8173 Additionally to the new range, this signal also provides the previous range held by the axis as
8184 This signal is emitted when the selection state of this axis has changed, either by user interaction
8198 Usually it isn't necessary to instantiate axes directly, because you can let QCustomPlot create
8199 them for you with \ref QCPAxisRect::addAxis. If you want to use own QCPAxis-subclasses however,
8222 mSelectedTickLabelFont(QFont(mTickLabelFont.family(), mTickLabelFont.pointSize(), QFont::Bold)),
8250 setLayer(mParentPlot->currentLayer()); // it's actually on that layer already, but we want it in front of the grid, so we place it on there again
8274 delete mGrid; // delete grid here instead of via parent ~QObject for better defined deletion order
8361 likely also want to use a logarithmic tick spacing and labeling, which can be achieved by setting
8410 Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface.
8413 However, even when \a selectable is set to a value not allowing the selection of a specific part,
8414 it is still possible to set the selection of this part manually, by calling \ref setSelectedParts
8429 Sets the selected state of the respective axis parts described by \ref SelectablePart. When a part
8433 QCustomPlot::setInteractions contains iSelectAxes. You only need to call this function when you
8436 This function can change the selection state of a part, independent of the \ref setSelectableParts setting.
8438 emits the \ref selectionChanged signal when \a selected is different from the previous selection state.
8440 \see SelectablePart, setSelectableParts, selectTest, setSelectedBasePen, setSelectedTickPen, setSelectedSubTickPen,
8441 setSelectedTickLabelFont, setSelectedLabelFont, setSelectedTickLabelColor, setSelectedLabelColor
8488 Qt::AlignLeft, Qt::AlignRight or Qt::AlignCenter. This will cause the left border, right border,
8547 Sets whether the axis range (direction) is displayed reversed. Normally, the values on horizontal
8548 axes increase left to right, on vertical axes bottom to top. When \a reversed is set to true, the
8551 Note that the range and data interface stays the same for reversed axes, e.g. the \a lower part
8552 of the \ref setRange interface will still reference the mathematically smaller number than the \a
8565 QCPAxisTicker subclass using this method. If you only wish to modify the currently installed axis
8568 Since the ticker is stored in the axis as a shared pointer, multiple axes may share the same axis
8585 Note that setting \a show to false does not imply that tick labels are invisible, too. To achieve
8614 Sets the distance between the axis base line (including any outward ticks) and the tick labels.
8651 Sets the rotation of the tick labels. If \a degrees is zero, the labels are drawn normally. Else,
8652 the tick labels are drawn rotated by \a degrees clockwise. The specified angle is bound to values
8655 If \a degrees is exactly -90, 0 or 90, the tick labels are centered on the tick coordinate. For
8656 other angles, the label is drawn with an offset such that it seems to point toward or away from
8671 The usual and default setting is \ref lsOutside. Very compact plots sometimes require tick labels
8682 Sets the number format for the numbers in tick labels. This \a formatCode is an extended version
8696 If the first char was 'e' or 'g', numbers are/might be displayed in the scientific format, e.g.
8699 [multiplication sign] 10 [superscript] 9". By default, the multiplication sign is a centered dot.
8700 If instead a cross should be shown (as is usual in the USA), the third char of \a formatCode can
8705 \li \c g normal format code behaviour. If number is small, fixed format is used, if number is large,
8707 \li \c gb If number is small, fixed format is used, if number is large, scientific format is used with
8709 \li \c ebc All numbers are in scientific format with beautifully typeset decimal power and a cross as
8711 \li \c fb illegal format code, since fixed format doesn't support (or need) beautifully typeset decimal
8713 \li \c hello illegal format code, since first char is not 'e', 'E', 'f', 'g' or 'G'. Current format
8732 qDebug() << Q_FUNC_INFO << "Invalid number format code (first char not in 'eEfgG'):" << formatCode;
8743 if (formatCode.at(1) == QLatin1Char('b') && (mNumberFormatChar == QLatin1Char('e') || mNumberFormatChar == QLatin1Char('g')))
8748 qDebug() << Q_FUNC_INFO << "Invalid number format code (second char not 'b' or first char neither 'e' nor 'g'):" << formatCode;
8772 Sets the precision of the tick label numbers. See QLocale::toString(double i, char f, int prec)
8773 for details. The effect of precisions are most notably for number Formats starting with 'e', see
8786 Sets the length of the ticks in pixels. \a inside is the length the ticks will reach inside the
8787 plot and \a outside is the length they will reach outside the plot. If \a outside is greater than
8846 Sets the length of the subticks in pixels. \a inside is the length the subticks will reach inside
8847 the plot and \a outside is the length they will reach outside the plot. If \a outside is greater
8848 than zero, the tick labels and axis label will increase their distance to the axis accordingly,
8860 Sets the length of the inward subticks in pixels. \a inside is the length the subticks will reach inside
8874 Sets the length of the outward subticks in pixels. \a outside is the length the subticks will reach
8944 Sets the text of the axis label that will be shown below/above or next to the axis, depending on
8973 When \ref QCPAxisRect::setAutoMargins is enabled, the padding is the additional outer most space,
8992 If an axis rect side has multiple axes and automatic margin calculation is enabled for that side,
9084 For horizontal axes, this method refers to the left ending, for vertical axes the bottom ending.
9111 If the scale type (\ref setScaleType) is \ref stLinear, \a diff is added to the lower and upper
9135 example, if \a factor is 2.0, then the axis range will double its size, and the point at the axis
9136 range center won't have changed its position in the QCustomPlot widget (i.e. coordinates around
9168 if ((mRange.upper < 0 && center < 0) || (mRange.upper > 0 && center > 0)) // make sure center has same sign as range
9183 Scales the range of this axis to have a certain scale \a ratio to \a otherAxis. The scaling will
9192 won't have the desired effect, since the widget dimensions aren't defined yet, and a resizeEvent
9247 if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable
9280 return qPow(mRange.upper/mRange.lower, (value-mAxisRect->left())/double(mAxisRect->width()))*mRange.lower;
9282 return qPow(mRange.upper/mRange.lower, (mAxisRect->left()-value)/double(mAxisRect->width()))*mRange.upper;
9295 return qPow(mRange.upper/mRange.lower, (mAxisRect->bottom()-value)/double(mAxisRect->height()))*mRange.lower;
9303 Transforms \a value, in coordinates of the axis, to pixel coordinates of the QCustomPlot widget.
9317 if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just draw it outside visible range
9319 else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale, just draw it outside visible range
9324 return qLn(value/mRange.lower)/qLn(mRange.upper/mRange.lower)*mAxisRect->width()+mAxisRect->left();
9326 return qLn(mRange.upper/value)/qLn(mRange.upper/mRange.lower)*mAxisRect->width()+mAxisRect->left();
9339 if (value >= 0.0 && mRange.upper < 0.0) // invalid value for logarithmic scale, just draw it outside visible range
9341 else if (value <= 0.0 && mRange.upper >= 0.0) // invalid value for logarithmic scale, just draw it outside visible range
9346 return mAxisRect->bottom()-qLn(value/mRange.lower)/qLn(mRange.upper/mRange.lower)*mAxisRect->height();
9355 Returns the part of the axis that is hit by \a pos (in pixels). The return value of this function
9356 is independent of the user-selectable parts defined with \ref setSelectableParts. Further, this
9489void QCPAxis::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
9513 This mouse event reimplementation provides the functionality to let the user drag individual axes
9516 For the axis to accept this event and perform the single axis drag, the parent \ref QCPAxisRect
9517 must be configured accordingly, i.e. it must allow range dragging in the orientation of this axis
9554 This mouse event reimplementation provides the functionality to let the user drag individual axes
9569 const double currentPixel = orientation() == Qt::Horizontal ? event->pos().x() : event->pos().y();
9588 This mouse event reimplementation provides the functionality to let the user drag individual axes
9612 This mouse event reimplementation provides the functionality to let the user zoom individual axes
9615 For the axis to accept this event and perform the single axis zoom, the parent \ref QCPAxisRect
9616 must be configured accordingly, i.e. it must allow range zooming in the orientation of this axis
9622 \note The zooming of possibly multiple axes at once by performing the wheel event anywhere in the
9676 Draws the axis with the specified \a painter, using the internal QCPAxisPainterPrivate instance.
9682 QVector<double> subTickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter
9683 QVector<double> tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter
9706 // transfer all properties of this axis to QCPAxisPainterPrivate which it needs to draw the axis.
9730 Prepares the internal tick vector, sub tick vector and tick label vector. This is done by calling
9742 mTicker->generate(mRange, mParentPlot->locale(), mNumberFormatChar, mNumberPrecision, mTickVector, mSubTicks ? &mSubTickVector : nullptr, mTickLabels ? &mTickVectorLabels : nullptr);
9748 Returns the pen that is used to draw the axis base line. Depending on the selection state, this
9819 QCPAxisRect::setAutoMargins is set to true on the parent axis rect. An axis with axis type \ref
9821 margin and so forth. For the calculation, this function goes through similar steps as \ref draw,
9832 if (!mVisible) // if not visible, directly return 0, don't cache 0 because we can't react to setVisible in QCPAxis
9838 // run through similar steps as QCPAxis::draw, and calculate margin needed to fit axis and its labels
9841 QVector<double> tickPositions; // the final coordToPixel transformed vector passed to QCPAxisPainter
9855 // transfer all properties of this axis to QCPAxisPainterPrivate which it needs to calculate the size.
9880////////////////////////////////////////////////////////////////////////////////////////////////////
9882////////////////////////////////////////////////////////////////////////////////////////////////////
9891 It is used by QCPAxis to do the low-level drawing of axis backbone, tick marks, tick labels and
9892 axis label. It also buffers the labels to reduce replot times. The parameters are configured by
9954 double xCor = 0, yCor = 0; // paint system correction, for pixel exact matches (affects baselines and ticks of top/right axes)
9970 baseLine = QLineF(baseLine.p2(), baseLine.p1()); // won't make a difference for line itself, but for line endings later
9977 int tickDir = (type == QCPAxis::atBottom || type == QCPAxis::atRight) ? -1 : 1; // direction of ticks ("inward" is right for left axis and left for right axis)
9981 painter->drawLine(QLineF(tickPos+xCor, origin.y()-tickLengthOut*tickDir+yCor, tickPos+xCor, origin.y()+tickLengthIn*tickDir+yCor));
9985 painter->drawLine(QLineF(origin.x()-tickLengthOut*tickDir+xCor, tickPos+yCor, origin.x()+tickLengthIn*tickDir+xCor, tickPos+yCor));
9998 painter->drawLine(QLineF(subTickPos+xCor, origin.y()-subTickLengthOut*tickDir+yCor, subTickPos+xCor, origin.y()+subTickLengthIn*tickDir+yCor));
10002 painter->drawLine(QLineF(origin.x()-subTickLengthOut*tickDir+xCor, subTickPos+yCor, origin.x()+subTickLengthIn*tickDir+xCor, subTickPos+yCor));
10009 painter->setAntialiasing(true); // always want endings to be antialiased, even if base and ticks themselves aren't
10013 lowerEnding.draw(painter, QCPVector2D(baseLine.p1())-baseLineVector.normalized()*lowerEnding.realLength()*(lowerEnding.inverted()?-1:1), -baseLineVector);
10015 upperEnding.draw(painter, QCPVector2D(baseLine.p2())+baseLineVector.normalized()*upperEnding.realLength()*(upperEnding.inverted()?-1:1), baseLineVector);
10025 QSize tickLabelsSize(0, 0); // size of largest tick label, for offset calculation of axis label
10037 placeTickLabel(painter, tickPositions.at(i), distanceToAxis, tickLabels.at(i), &tickLabelsSize);
10039 margin += (QCPAxis::orientation(type) == Qt::Horizontal) ? tickLabelsSize.height() : tickLabelsSize.width();
10057 painter->drawText(0, 0, axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label);
10065 painter->drawText(0, 0, axisRect.height(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label);
10069 painter->drawText(origin.x(), origin.y()-margin-labelBounds.height(), axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label);
10071 painter->drawText(origin.x(), origin.y()+margin, axisRect.width(), labelBounds.height(), Qt::TextDontClip | Qt::AlignCenter, label);
10086 selTickLabelSize = (QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width());
10090 selTickLabelSize = -(QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width());
10094 int selLabelOffset = qMax(tickLengthOut, subTickLengthOut)+(!tickLabels.isEmpty() && tickLabelSide == QCPAxis::lsOutside ? tickLabelPadding+selTickLabelSize : 0)+labelPadding;
10097 mAxisSelectionBox.setCoords(origin.x()-selAxisOutSize, axisRect.top(), origin.x()+selAxisInSize, axisRect.bottom());
10098 mTickLabelsSelectionBox.setCoords(origin.x()-selTickLabelOffset-selTickLabelSize, axisRect.top(), origin.x()-selTickLabelOffset, axisRect.bottom());
10099 mLabelSelectionBox.setCoords(origin.x()-selLabelOffset-selLabelSize, axisRect.top(), origin.x()-selLabelOffset, axisRect.bottom());
10102 mAxisSelectionBox.setCoords(origin.x()-selAxisInSize, axisRect.top(), origin.x()+selAxisOutSize, axisRect.bottom());
10103 mTickLabelsSelectionBox.setCoords(origin.x()+selTickLabelOffset+selTickLabelSize, axisRect.top(), origin.x()+selTickLabelOffset, axisRect.bottom());
10104 mLabelSelectionBox.setCoords(origin.x()+selLabelOffset+selLabelSize, axisRect.top(), origin.x()+selLabelOffset, axisRect.bottom());
10107 mAxisSelectionBox.setCoords(axisRect.left(), origin.y()-selAxisOutSize, axisRect.right(), origin.y()+selAxisInSize);
10108 mTickLabelsSelectionBox.setCoords(axisRect.left(), origin.y()-selTickLabelOffset-selTickLabelSize, axisRect.right(), origin.y()-selTickLabelOffset);
10109 mLabelSelectionBox.setCoords(axisRect.left(), origin.y()-selLabelOffset-selLabelSize, axisRect.right(), origin.y()-selLabelOffset);
10112 mAxisSelectionBox.setCoords(axisRect.left(), origin.y()-selAxisInSize, axisRect.right(), origin.y()+selAxisOutSize);
10113 mTickLabelsSelectionBox.setCoords(axisRect.left(), origin.y()+selTickLabelOffset+selTickLabelSize, axisRect.right(), origin.y()+selTickLabelOffset);
10114 mLabelSelectionBox.setCoords(axisRect.left(), origin.y()+selLabelOffset+selLabelSize, axisRect.right(), origin.y()+selLabelOffset);
10126 Returns the size ("margin" in QCPAxisRect context, so measured perpendicular to the axis backbone
10152 result += QCPAxis::orientation(type) == Qt::Horizontal ? tickLabelsSize.height() : tickLabelsSize.width();
10157 // calculate size of axis label (only height needed, because left/right labels are rotated by 90 degrees):
10162 bounds = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter | Qt::AlignVCenter, label);
10171 Clears the internal label cache. Upon the next \ref draw, all labels will be created new. This
10172 method is called automatically in \ref draw, if any parameters have changed that invalidate the
10182 Returns a hash that allows uniquely identifying whether the label parameters have changed such
10184 return value of this method hasn't changed since the last redraw, the respective label parameters
10195 result.append(tickLabelColor.name().toLatin1()+QByteArray::number(tickLabelColor.alpha(), 16));
10205 pixels. The pixel position in the axis direction is passed in the \a position parameter. Hence
10206 for the bottom axis, \a position would indicate the horizontal pixel position (not coordinate),
10209 In order to later draw the axis label in a place that doesn't overlap with the tick labels, the
10210 largest tick label size is needed. This is acquired by passing a \a tickLabelsSize to the \ref
10211 drawTickLabel calls during the process of drawing all tick labels of one axis. In every call, \a
10219void QCPAxisPainterPrivate::placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize)
10227 case QCPAxis::atLeft: labelAnchor = QPointF(axisRect.left()-distanceToAxis-offset, position); break;
10228 case QCPAxis::atRight: labelAnchor = QPointF(axisRect.right()+distanceToAxis+offset, position); break;
10229 case QCPAxis::atTop: labelAnchor = QPointF(position, axisRect.top()-distanceToAxis-offset); break;
10230 case QCPAxis::atBottom: labelAnchor = QPointF(position, axisRect.bottom()+distanceToAxis+offset); break;
10232 if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && !painter->modes().testFlag(QCPPainter::pmNoCaching)) // label caching enabled
10239 cachedLabel->offset = getTickLabelDrawOffset(labelData)+labelData.rotatedTotalBounds.topLeft();
10242 cachedLabel->pixmap = QPixmap(labelData.rotatedTotalBounds.size()*mParentPlot->bufferDevicePixelRatio());
10255 drawTickLabel(&cachePainter, -labelData.rotatedTotalBounds.topLeft().x(), -labelData.rotatedTotalBounds.topLeft().y(), labelData);
10257 // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels):
10262 labelClippedByBorder = labelAnchor.x()+cachedLabel->offset.x()+cachedLabel->pixmap.width()/mParentPlot->bufferDevicePixelRatio() > viewportRect.right() || labelAnchor.x()+cachedLabel->offset.x() < viewportRect.left();
10264 labelClippedByBorder = labelAnchor.y()+cachedLabel->offset.y()+cachedLabel->pixmap.height()/mParentPlot->bufferDevicePixelRatio() > viewportRect.bottom() || labelAnchor.y()+cachedLabel->offset.y() < viewportRect.top();
10271 mLabelCache.insert(text, cachedLabel); // return label to cache or insert for the first time if newly created
10276 // if label would be partly clipped by widget border on sides, don't draw it (only for outside tick labels):
10281 labelClippedByBorder = finalPosition.x()+(labelData.rotatedTotalBounds.width()+labelData.rotatedTotalBounds.left()) > viewportRect.right() || finalPosition.x()+labelData.rotatedTotalBounds.left() < viewportRect.left();
10303 Draws the tick label specified in \a labelData with \a painter at the pixel positions \a x and \a
10304 y. This function is used by \ref placeTickLabel to create new tick labels for the cache, or to
10308void QCPAxisPainterPrivate::drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const
10325 painter->drawText(labelData.baseBounds.width()+1+labelData.expBounds.width(), 0, 0, 0, Qt::TextDontClip, labelData.suffixPart);
10327 painter->drawText(labelData.baseBounds.width()+1, 0, labelData.expBounds.width(), labelData.expBounds.height(), Qt::TextDontClip, labelData.expPart);
10331 painter->drawText(0, 0, labelData.totalBounds.width(), labelData.totalBounds.height(), Qt::TextDontClip | Qt::AlignHCenter, labelData.basePart);
10343 Transforms the passed \a text and \a font to a tickLabelData structure that can then be further
10344 processed by \ref getTickLabelDrawOffset and \ref drawTickLabel. It splits the text into base and
10347QCPAxisPainterPrivate::TickLabelData QCPAxisPainterPrivate::getTickLabelData(const QFont &font, const QString &text) const
10353 int ePos = -1; // first index of exponent part, text before that will be basePart, text until eLast will be expPart
10361 while (eLast+1 < text.size() && (text.at(eLast+1) == QLatin1Char('+') || text.at(eLast+1) == QLatin1Char('-') || text.at(eLast+1).isDigit()))
10363 if (eLast > ePos) // only if also to right of 'e' is a digit/+/- interpret it as beautifiable power
10370 if (result.baseFont.pointSizeF() > 0) // might return -1 if specified with setPixelSize, in that case we can't do correction in next line
10371 result.baseFont.setPointSizeF(result.baseFont.pointSizeF()+0.05); // QFontMetrics.boundingRect has a bug for exact point sizes that make the results oscillate due to internal rounding
10374 // split text into parts of number/symbol that will be drawn normally and part that will be drawn as exponent:
10377 // in log scaling, we want to turn "1*10^n" into "10^n", else add multiplication sign and decimal base:
10381 result.basePart += (numberMultiplyCross ? QString(QChar(215)) : QString(QChar(183))) + QLatin1String("10");
10384 while (result.expPart.length() > 2 && result.expPart.at(1) == QLatin1Char('0')) // length > 2 so we leave one zero when numberFormatChar is 'e'
10395 result.baseBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.basePart);
10396 result.expBounds = QFontMetrics(result.expFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.expPart);
10398 result.suffixBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip, result.suffixPart);
10399 result.totalBounds = result.baseBounds.adjusted(0, 0, result.expBounds.width()+result.suffixBounds.width()+2, 0); // +2 consists of the 1 pixel spacing between base and exponent (see drawTickLabel) and an extra pixel to include AA
10403 result.totalBounds = QFontMetrics(result.baseFont).boundingRect(0, 0, 0, 0, Qt::TextDontClip | Qt::AlignHCenter, result.basePart);
10405 result.totalBounds.moveTopLeft(QPoint(0, 0)); // want bounding box aligned top left at origin, independent of how it was created, to make further processing simpler
10423 Calculates the offset at which the top left corner of the specified tick label shall be drawn.
10426 This function is thus responsible for e.g. centering tick labels under ticks and positioning them
10432 calculate label offset from base point at tick (non-trivial, for best visual appearance): short
10442 bool flip = qFuzzyCompare(qAbs(tickLabelRotation), 90.0); // perfect +/-90 degree flip. Indicates vertical label centering on vertical axes.
10446 if ((type == QCPAxis::atLeft && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atRight && tickLabelSide == QCPAxis::lsInside)) // Anchor at right side of tick label
10453 y = flip ? -labelData.totalBounds.width()/2.0 : -qSin(radians)*labelData.totalBounds.width()-qCos(radians)*labelData.totalBounds.height()/2.0;
10456 x = -qCos(-radians)*labelData.totalBounds.width()-qSin(-radians)*labelData.totalBounds.height();
10457 y = flip ? +labelData.totalBounds.width()/2.0 : +qSin(-radians)*labelData.totalBounds.width()-qCos(-radians)*labelData.totalBounds.height()/2.0;
10464 } else if ((type == QCPAxis::atRight && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atLeft && tickLabelSide == QCPAxis::lsInside)) // Anchor at left side of tick label
10471 y = flip ? -labelData.totalBounds.width()/2.0 : -qCos(radians)*labelData.totalBounds.height()/2.0;
10475 y = flip ? +labelData.totalBounds.width()/2.0 : -qCos(-radians)*labelData.totalBounds.height()/2.0;
10482 } else if ((type == QCPAxis::atTop && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atBottom && tickLabelSide == QCPAxis::lsInside)) // Anchor at bottom side of tick label
10488 x = -qCos(radians)*labelData.totalBounds.width()+qSin(radians)*labelData.totalBounds.height()/2.0;
10489 y = -qSin(radians)*labelData.totalBounds.width()-qCos(radians)*labelData.totalBounds.height();
10500 } else if ((type == QCPAxis::atBottom && tickLabelSide == QCPAxis::lsOutside) || (type == QCPAxis::atTop && tickLabelSide == QCPAxis::lsInside)) // Anchor at top side of tick label
10525 Simulates the steps done by \ref placeTickLabel by calculating bounding boxes of the text label
10526 to be drawn, depending on number format etc. Since only the largest tick label is wanted for the
10530void QCPAxisPainterPrivate::getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const
10534 if (mParentPlot->plottingHints().testFlag(QCP::phCacheLabels) && mLabelCache.contains(text)) // label caching enabled and have cached label
10556////////////////////////////////////////////////////////////////////////////////////////////////////
10558////////////////////////////////////////////////////////////////////////////////////////////////////
10563 This class holds information about shape, color and size of scatter points. In plottables like
10567 A scatter style consists of a shape (\ref setShape), a line color (\ref setPen) and possibly a
10568 fill (\ref setBrush), if the shape provides a fillable area. Further, the size of the shape can
10573 You can set all these configurations either by calling the respective functions on an instance:
10576 Or you can use one of the various constructors that take different parameter combinations, making
10583 QCPScatterStyle(ScatterShape shape, double size). If those constructors are used, a call to \ref
10585 plottable that uses the scatter style. Thus, if such a scatter style is passed to QCPGraph, the line
10591 Notice that it wasn't even necessary to explicitly call a QCPScatterStyle constructor. This works
10592 because QCPScatterStyle provides a constructor that can transform a \ref ScatterShape directly
10593 into a QCPScatterStyle instance (that's the \ref QCPScatterStyle(ScatterShape shape, double size)
10602 setCustomPath function or call the constructor that takes a painter path. The scatter shape will
10606 constructor that takes a QPixmap. The scatter shape will automatically be set to \ref ssPixmap.
10623 The pen is undefined if a constructor is called that does not carry \a pen as parameter. Those
10624 are \ref QCPScatterStyle() and \ref QCPScatterStyle(ScatterShape shape, double size). If the pen
10627 If a pen was defined for this scatter style instance, and you now wish to undefine the pen, call
10638 Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited
10651 Creates a new QCPScatterStyle instance with shape set to \a shape and size to \a size. No pen or
10654 Since the pen is undefined (\ref isPenDefined returns false), the scatter color will be inherited
10667 Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color,
10680 Creates a new QCPScatterStyle instance with shape set to \a shape, the pen color set to \a color,
10683QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size) :
10696 \warning In some cases it might be tempting to directly use a pen style like <tt>Qt::NoPen</tt> as \a pen
10701 \ref QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size)
10704 instead of just <tt>Qt::blue</tt>, to clearly point out to the compiler that this constructor is
10707QCPScatterStyle::QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size) :
10717 Creates a new QCPScatterStyle instance which will show the specified \a pixmap. The scatter shape
10731 Creates a new QCPScatterStyle instance with a custom shape that is defined via \a customPath. The
10734 The custom shape line will be drawn with \a pen and filled with \a brush. The size has a slightly
10739QCPScatterStyle::QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush, double size) :
10800 If the pen was previously undefined (see \ref isPenDefined), the pen is considered defined after
10813 Sets the brush that will be used to fill scatter points to \a brush. Note that not all scatter
10848 Sets this scatter style to have an undefined pen (see \ref isPenDefined for what an undefined pen
10859 Applies the pen and the brush of this scatter style to \a painter. If this scatter style has an
10876 This function does not modify the pen or the brush on the painter, as \ref applyTo is meant to be
11004 const QRectF clipRect = painter->clipRegion().boundingRect().adjusted(-widthHalf, -heightHalf, widthHalf, heightHalf);
11006 const QRectF clipRect = painter->clipBoundingRect().adjusted(-widthHalf, -heightHalf, widthHalf, heightHalf);
11029////////////////////////////////////////////////////////////////////////////////////////////////////
11031////////////////////////////////////////////////////////////////////////////////////////////////////
11036 Each \ref QCPAbstractPlottable instance has one \ref QCPSelectionDecorator (accessible via \ref
11037 QCPAbstractPlottable::selectionDecorator) and uses it when drawing selected segments of its data.
11039 The selection decorator controls both pen (\ref setPen) and brush (\ref setBrush), as well as the
11042 decorator allows specifying exactly which of those properties shall be used for the selected data
11046 QCPAbstractPlottable::setSelectionDecorator, allowing greater customizability of the appearance
11050 especially useful since plottables take ownership of the passed selection decorator, and thus the
11097void QCPSelectionDecorator::setScatterStyle(const QCPScatterStyle &scatterStyle, QCPScatterStyle::ScatterProperties usedProperties)
11104 Use this method to define which properties of the scatter style (set via \ref setScatterStyle)
11106 specified in \a properties will remain as specified in the plottable's original scatter style.
11110void QCPSelectionDecorator::setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties)
11136 Returns the scatter style that the parent plottable shall use for selected scatter points. The
11137 plottable's original (unselected) scatter style must be passed as \a unselectedStyle. Depending
11138 on the setting of \ref setUsedScatterProperties, the returned scatter style is a mixture of this
11143QCPScatterStyle QCPSelectionDecorator::getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const
11158 Copies all properties (e.g. color, fill, scatter style) of the \a other selection decorator to
11169 This method is called by all plottables' draw methods to allow custom selection decorations to be
11170 drawn. Use the passed \a painter to perform the drawing operations. \a selection carries the data
11173 The default base class implementation of \ref QCPSelectionDecorator has no special decoration, so
11184 This method is called as soon as a selection decorator is associated with a plottable, by a call
11185 to \ref QCPAbstractPlottable::setSelectionDecorator. This way the selection decorator can obtain a pointer to the plottable that uses it (e.g. to access
11188 If the selection decorator was already added to a different plottable before, this method aborts
11205////////////////////////////////////////////////////////////////////////////////////////////////////
11207////////////////////////////////////////////////////////////////////////////////////////////////////
11213 abstract, it can't be instantiated. Use one of the subclasses or create a subclass yourself to
11214 create new ways of displaying data (see "Creating own plottables" below). Plottables that display
11215 one-dimensional data (i.e. data points have a single key dimension and one or multiple values at
11245 For drawing your plot, you can use the \ref coordsToPixels functions to translate a point in plot
11247 orientation of the key and value axes into account for you (x and y are swapped when the key axis
11248 is vertical and the value axis horizontal). If you are worried about performance (i.e. you need
11257 <td>A pointer to the parent QCustomPlot instance. The parent plot is inferred from the axes that are passed in the constructor.</td>
11263 <td>The generic pen of the plottable. You should use this pen for the most prominent data representing lines in the plottable
11267 <td>The generic brush of the plottable. You should use this brush for the most prominent fillable structures in the plottable
11271 <td>The key and value axes this plottable is attached to. Call their QCPAxis::coordToPixel functions to translate coordinates
11272 to pixels in either the key or value dimension. Make sure to check whether the pointer is \c nullptr before using it. If one of
11276 <td>The currently set selection decorator which specifies how selected data of the plottable shall be drawn and decorated.
11277 When drawing your data, you must consult this decorator for the appropriate pen/brush before drawing unselected/selected data segments.
11278 Finally, you should call its \ref QCPSelectionDecorator::drawDecoration method at the end of your \ref draw implementation.</td>
11281 <td>In which composition, if at all, this plottable's data may be selected. Enforcing this setting on the data selection is done
11285 <td>Holds the current selection state of the plottable's data, i.e. the selected data ranges (\ref QCPDataRange).</td>
11294 Provides access to the selection decorator of this plottable. The selection decorator controls
11304 Returns true if there are any data points of the plottable currently selected. Use \ref selection
11310 Returns a \ref QCPDataSelection encompassing all the data points that are currently selected on
11319 QCPPlottableInterface1D, returns the \a this pointer with that type. Otherwise (e.g. in the case
11322 You can use this method to gain read access to data coordinates while holding a pointer to the
11329/*! \fn void QCPAbstractPlottable::drawLegendIcon(QCPPainter *painter, const QRect &rect) const = 0
11332 called by QCPLegend::draw (via QCPPlottableLegendItem::draw) to create a graphical representation
11339/*! \fn QCPRange QCPAbstractPlottable::getKeyRange(bool &foundRange, QCP::SignDomain inSignDomain) const = 0
11341 Returns the coordinate range that all data in this plottable span in the key axis dimension. For
11346 QCP::sdBoth (default). \a foundRange is an output parameter that indicates whether a range could
11347 be found or not. If this is false, you shouldn't use the returned range (e.g. no points in data).
11349 Note that \a foundRange is not the same as \ref QCPRange::validRange, since the range returned by
11357/*! \fn QCPRange QCPAbstractPlottable::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const = 0
11359 Returns the coordinate range that the data points in the specified key range (\a inKeyRange) span
11360 in the value axis dimension. For logarithmic plots, one can set \a inSignDomain to either \ref
11362 domain. E.g. when only negative range is wanted, set \a inSignDomain to \ref QCP::sdNegative and
11364 inSignDomain to \ref QCP::sdBoth (default). \a foundRange is an output parameter that indicates
11368 If \a inKeyRange has both lower and upper bound set to zero (is equal to <tt>QCPRange()</tt>),
11371 Note that \a foundRange is not the same as \ref QCPRange::validRange, since the range returned by
11385 interaction or by a direct call to \ref setSelection. The parameter \a selected indicates whether
11410 Constructs an abstract plottable which uses \a keyAxis as its key axis ("x") and \a valueAxis as
11411 its value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance
11412 and have perpendicular orientations. If either of these restrictions is violated, a corresponding
11415 Since QCPAbstractPlottable is an abstract class that defines the basic interface to plottables,
11509 The key axis of a plottable can be set to any axis of a QCustomPlot, as long as it is orthogonal
11510 to the plottable's value axis. This function performs no checks to make sure this is the case.
11526 orthogonal to the plottable's key axis. This function performs no checks to make sure this is the
11527 case. The typical mathematical choice is to use the x-axis (QCustomPlot::xAxis) as key axis and
11542 Sets which data ranges of this plottable are selected. Selected data ranges are drawn differently
11547 QCustomPlot::setInteractions contains iSelectPlottables. You only need to call this function when
11555 emits the \ref selectionChanged signal when \a selected is different from the previous selection state.
11599 QCustomPlot::setInteractions contains \ref QCP::iSelectPlottables), by dragging a selection rect
11624 taking the orientations of the axes associated with this plottable into account (e.g. whether key
11627 \a key and \a value are transformed to the coodinates in pixels and are written to \a x and \a y.
11631void QCPAbstractPlottable::coordsToPixels(double key, double value, double &x, double &y) const
11656 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPointF(); }
11665 Convenience function for transforming a x/y pixel pair on the QCustomPlot surface to plot coordinates,
11666 taking the orientations of the axes associated with this plottable into account (e.g. whether key
11673void QCPAbstractPlottable::pixelsToCoords(double x, double y, double &key, double &value) const
11694void QCPAbstractPlottable::pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const
11700 Rescales the key and value axes associated with this plottable to contain all displayed data, so
11701 the whole plottable is visible. If the scaling of an axis is logarithmic, rescaleAxes will make
11703 Instead it will stay in the current sign domain and ignore all parts of the plottable that lie
11706 \a onlyEnlarge makes sure the ranges are only expanded, never reduced. So it's possible to show
11707 multiple plottables in their entirety by multiple calls to rescaleAxes where the first call has
11738 if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable
11756 Rescales the value axis of the plottable so the whole plottable is visible. If \a inKeyRange is
11760 Returns true if the axis was actually scaled. This might not be the case if this plottable has an
11769 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
11776 QCPRange newRange = getValueRange(foundRange, signDomain, inKeyRange ? keyAxis->range() : QCPRange());
11781 if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this axis dimension), shift current range to at least center the plottable
11802 Creates a QCPPlottableLegendItem which is inserted into the legend. Returns true on success, i.e.
11807 corresponding subclass of \ref QCPPlottableLegendItem and add it to the legend manually instead
11902 A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter
11922 A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter
11938 A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter
11953void QCPAbstractPlottable::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
11963 if (mSelectable == QCP::stWhole) // in whole selection mode, we toggle to no selection even if currently unselected point was hit
11969 } else // in all other selection modes we toggle selections of homogeneously selected/unselected segments
12000////////////////////////////////////////////////////////////////////////////////////////////////////
12002////////////////////////////////////////////////////////////////////////////////////////////////////
12007 An item (QCPAbstractItem) may have one or more anchors. Unlike QCPItemPosition, an anchor doesn't
12008 control anything on its item, but provides a way to tie other items via their positions to the
12015 QCPItemRect. This way the start of the line will now always follow the respective anchor location
12021 To learn how to provide anchors in your own item subclasses, see the subclassing section of the
12032 This safe downcast functionality could also be achieved with a dynamic_cast. However, QCustomPlot avoids
12033 dynamic_cast to work with projects that don't have RTTI support enabled (e.g. -fno-rtti flag with
12044QCPItemAnchor::QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, int anchorId) :
12058 child->setParentAnchorX(nullptr); // this acts back on this anchor and child removes itself from mChildrenX
12063 child->setParentAnchorY(nullptr); // this acts back on this anchor and child removes itself from mChildrenY
12095 anchor as parent anchor for the respective coordinate. This is necessary to notify the children
12123 anchor as parent anchor for the respective coordinate. This is necessary to notify the children
12149////////////////////////////////////////////////////////////////////////////////////////////////////
12151////////////////////////////////////////////////////////////////////////////////////////////////////
12156 Every item has at least one public QCPItemPosition member pointer which provides ways to position the
12157 item on the QCustomPlot surface. Some items have multiple positions, for example QCPItemRect has two:
12161 defines how coordinates passed to \ref setCoords are to be interpreted, e.g. as absolute pixel
12162 coordinates, as plot coordinates of certain axes (\ref QCPItemPosition::setAxes), as fractions of
12164 possible to assign different types per X/Y coordinate of the position (see \ref setTypeX, \ref
12165 setTypeY). This way an item could be positioned for example at a fixed pixel distance from the
12168 A QCPItemPosition may have a parent QCPItemAnchor, see \ref setParentAnchor. This way you can tie
12169 multiple items together. If the QCPItemPosition has a parent, its coordinates (\ref setCoords)
12170 are considered to be absolute pixels in the reference frame of the parent anchor, where (0, 0)
12171 means directly ontop of the parent anchor. For example, You could attach the \a start position of
12173 always be centered under the text label, no matter where the text is moved to. For more advanced
12174 plots, it is possible to assign different parent anchors per X/Y coordinate of the position, see
12175 \ref setParentAnchorX, \ref setParentAnchorY. This way an item could follow another item in the X
12176 direction but stay at a fixed position in the Y direction. Or even follow item A in X, and item B
12179 Note that every QCPItemPosition inherits from QCPItemAnchor and thus can itself be used as parent
12182 To set the apparent pixel position on the QCustomPlot surface directly, use \ref setPixelPosition. This
12183 works no matter what type this QCPItemPosition is or what parent-child situation it is in, as \ref
12184 setPixelPosition transforms the coordinates appropriately, to make the position appear at the specified
12194 If different types were set for X and Y (\ref setTypeX, \ref setTypeY), this method returns the
12204 If different parent anchors were set for X and Y (\ref setParentAnchorX, \ref setParentAnchorY),
12214 Creates a new QCPItemPosition. You shouldn't create QCPItemPosition instances directly, even if
12218QCPItemPosition::QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name) :
12232 // Note: this is done in ~QCPItemAnchor again, but it's important QCPItemPosition does it itself, because only then
12233 // the setParentAnchor(0) call the correct QCPItemPosition::pixelPosition function instead of QCPItemAnchor::pixelPosition
12237 child->setParentAnchorX(nullptr); // this acts back on this anchor and child removes itself from mChildrenX
12242 child->setParentAnchorY(nullptr); // this acts back on this anchor and child removes itself from mChildrenY
12251/* can't make this a header inline function, because QPointer breaks with forward declared types, see QTBUG-29588 */
12263 \li The position is regarded as a point in plot coordinates. This corresponds to \ref ptPlotCoords
12264 and requires two axes that define the plot coordinate system. They can be specified with \ref setAxes.
12270 documentation of \ref PositionType for details. For \ref ptAxisRectRatio, note that you can specify
12273 Note that the position type \ref ptPlotCoords is only available (and sensible) when the position
12277 the coordinates as retrieved with coords() and set with \ref setCoords may change in the process.
12279 This method sets the type for both X and Y directions. It is also possible to set different types
12350 follow any position changes of the anchor. The local coordinate system of positions with a parent
12351 anchor always is absolute pixels, with (0, 0) being exactly on top of the parent anchor. (Hence
12354 if \a keepPixelPosition is true, the current pixel position of the QCPItemPosition is preserved
12355 during reparenting. If it's set to false, the coordinates are set to (0, 0), i.e. the position
12360 If the QCPItemPosition previously had no parent and the type is \ref ptPlotCoords, the type is
12376 For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor.
12385 qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast<quintptr>(parentAnchor);
12397 qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast<quintptr>(parentAnchor);
12408 qDebug() << Q_FUNC_INFO << "can't set parent to be an anchor which itself depends on this position" << reinterpret_cast<quintptr>(parentAnchor);
12441 For a detailed description of what a parent anchor is, see the documentation of \ref setParentAnchor.
12450 qDebug() << Q_FUNC_INFO << "can't set self as parent anchor" << reinterpret_cast<quintptr>(parentAnchor);
12462 qDebug() << Q_FUNC_INFO << "can't create recursive parent-child-relationship" << reinterpret_cast<quintptr>(parentAnchor);
12473 qDebug() << Q_FUNC_INFO << "can't set parent to be an anchor which itself depends on this position" << reinterpret_cast<quintptr>(parentAnchor);
12504 Sets the coordinates of this QCPItemPosition. What the coordinates mean, is defined by the type
12507 For example, if the type is \ref ptAbsolute, \a key and \a value mean the x and y pixel position
12509 QCustomPlot viewport. If the type is \ref ptPlotCoords, \a key and \a value mean a point in the
12515 value must also be provided in the different coordinate systems. Here, the X type refers to \a
12537 Returns the final absolute pixel position of the QCPItemPosition on the QCustomPlot surface. It
12538 includes all effects of type (\ref setType) and possible parent anchors (\ref setParentAnchor).
12575 qDebug() << Q_FUNC_INFO << "Item position type x is ptAxisRectRatio, but no axis rect was defined";
12639 coordinates set with \ref setCoords relate to. By default they are set to the initial xAxis and
12649 When \ref setType is \ref ptAxisRectRatio, this function may be used to specify the axis rect the
12650 coordinates set with \ref setCoords relate to. By default this is set to the main axis rect of
12700 qDebug() << Q_FUNC_INFO << "Item position type x is ptAxisRectRatio, but no axis rect was defined";
12761////////////////////////////////////////////////////////////////////////////////////////////////////
12763////////////////////////////////////////////////////////////////////////////////////////////////////
12769 (QCPAbstractPlottable) nor axes (QCPAxis). While plottables are always tied to two axes and thus
12770 plot coordinates, items can also be placed in absolute coordinates independent of any axes. Each
12771 specific item has at least one QCPItemPosition member which controls the positioning. Some items
12772 are defined by more than one coordinate and thus have two or more QCPItemPosition members (For
12775 This abstract base class defines a very basic interface like visibility and clipping. Since this
12781 <tr><td>QCPItemLine</td><td>A line defined by a start and an end point. May have different ending styles on each side (e.g. arrows).</td></tr>
12782 <tr><td>QCPItemStraightLine</td><td>A straight line defined by a start and a direction point. Unlike QCPItemLine, the straight line is infinitely long and has no endings.</td></tr>
12783 <tr><td>QCPItemCurve</td><td>A curve defined by start, end and two intermediate control points. May have different ending styles on each side (e.g. arrows).</td></tr>
12788 <tr><td>QCPItemBracket</td><td>A bracket which may be used to reference/highlight certain parts in the plot.</td></tr>
12789 <tr><td>QCPItemTracer</td><td>An item that can be attached to a QCPGraph and sticks to its data points, given a key coordinate.</td></tr>
12794 Items are by default clipped to the main axis rect (they are only visible inside the axis rect).
12799 \ref setClipAxisRect. This clipAxisRect property of an item is only used for clipping behaviour, and
12801 members (\ref QCPItemPosition::setAxes). However, it is common that the axis rect for clipping
12808 by default, the positions of the item are bound to the x- and y-Axis of the plot. So we can just
12811 If we don't want the line to be positioned in plot coordinates but a different coordinate system,
12812 e.g. absolute pixel positions on the QCustomPlot surface, we need to change the position type like this:
12819 For more advanced plots, it is even possible to set different types and parent anchors per X/Y
12821 QCPItemPosition::setParentAnchorX. For details, see the documentation of \ref QCPItemPosition.
12834 As mentioned, item positions are represented by QCPItemPosition members. Let's assume the new item shall
12835 have only one point as its position (as opposed to two like a rect or multiple like a polygon). You then add
12840 the const makes sure the pointer itself can't be modified from the user of your new item (the QCPItemPosition
12842 The initialization of this pointer is made easy with the \ref createPosition function. Just assign
12843 the return value of this function to each QCPItemPosition in the constructor of your item. \ref createPosition
12844 takes a string which is the name of the position, typically this is identical to the variable name.
12858 To give your item a visual representation, reimplement the \ref draw function and use the passed
12862 To optimize performance you should calculate a bounding rect first (don't forget to take the pen
12863 width into account), check whether it intersects the \ref clipRect, and only draw the item at all
12869 QCPVector2D::distanceSquaredToLine and \ref rectDistance. With these, the implementation of the
12875 Providing anchors (QCPItemAnchor) starts off like adding a position. First you create a public
12880 and create it in the constructor with the \ref createAnchor function, assigning it a name and an
12881 anchor id (an integer enumerating all anchors on the item, you may create an own enum for this).
12883 provide the position of every anchor with the reimplementation of the \ref anchorPixelPosition(int
12886 In essence the QCPItemAnchor is merely an intermediary that itself asks your item for the pixel
12901 Returns all anchors of the item in a list. Note that since a position (QCPItemPosition) is always
12924 This signal is emitted when the selection state of this item has changed, either by user interaction
12955/* can't make this a header inline function, because QPointer breaks with forward declared types, see QTBUG-29588 */
12991 However, even when \a selectable was set to false, it is possible to set the selection manually,
13015 emits the \ref selectionChanged signal when \a selected is different from the previous selection state.
13029 Returns the QCPItemPosition with the specified \a name. If this item doesn't have a position by
13073 Note that you can check for positions with this function, too. This is because every position is
13091 current setting of \ref setClipToAxisRect as well as the axis rect set with \ref setClipAxisRect.
13107 A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter
13125 A convenience function which returns the selectTest value for a specified \a rect and a specified
13132 For example, if your item consists of four rects, call this function four times, once for each
13133 rect, in your \ref selectTest reimplementation. Finally, return the minimum (non -1) of all four
13136double QCPAbstractItem::rectDistance(const QRectF &rect, const QPointF &pos, bool filledRect) const
13141 const QList<QLineF> lines = QList<QLineF>() << QLineF(rect.topLeft(), rect.topRight()) << QLineF(rect.bottomLeft(), rect.bottomRight())
13164 Returns the pixel position of the anchor with Id \a anchorId. This function must be reimplemented in
13167 For example, if the item has two anchors with id 0 and 1, this function takes one of these anchor
13180 Creates a QCPItemPosition, registers it with this item and returns a pointer to it. The specified
13181 \a name must be a unique string that is usually identical to the variable name of the position
13209 Creates a QCPItemAnchor, registers it with this item and returns a pointer to it. The specified
13213 The \a anchorId must be a number identifying the created anchor. It is recommended to create an
13214 enum (e.g. "AnchorIndex") for this on each item that uses anchors. This id is used by the anchor
13215 to identify itself when it calls QCPAbstractItem::anchorPixelPosition. That function then returns
13221 create each anchor member. Don't create QCPItemAnchors with \b new yourself, because then they
13236void QCPAbstractItem::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
13272////////////////////////////////////////////////////////////////////////////////////////////////////
13274////////////////////////////////////////////////////////////////////////////////////////////////////
13289 Allows access to the currently used QCPSelectionRect instance (or subclass thereof), that is used
13297 Returns the top level layout of this QCustomPlot instance. It is a \ref QCPLayoutGrid, initially containing just
13314 connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref
13323 connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeDrag or \ref
13326 \warning It is discouraged to change the drag-axes with \ref QCPAxisRect::setRangeDragAxes here,
13327 because the dragging starting point was saved the moment the mouse was pressed. Thus it only has
13328 a meaning for the range drag axes that were set at that moment. If you want to change the drag
13337 slot connected to this signal can still influence the behaviour e.g. with \ref setInteractions or
13346 connected to this signal can still influence the behaviour e.g. with \ref QCPAxisRect::setRangeZoom, \ref
13350/*! \fn void QCustomPlot::plottableClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event)
13354 \a event is the mouse event that caused the click and \a plottable is the plottable that received
13361/*! \fn void QCustomPlot::plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event)
13365 \a event is the mouse event that caused the click and \a plottable is the plottable that received
13392/*! \fn void QCustomPlot::axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event)
13396 \a event is the mouse event that caused the click, \a axis is the axis that received the click and
13402/*! \fn void QCustomPlot::axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event)
13406 \a event is the mouse event that caused the click, \a axis is the axis that received the click and
13412/*! \fn void QCustomPlot::legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event)
13417 click and \a item is the legend item that received the click. If only the legend and no item is
13418 clicked, \a item is \c nullptr. This happens for a click inside the legend padding or the space
13424/*! \fn void QCustomPlot::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event)
13429 click and \a item is the legend item that received the click. If only the legend and no item is
13430 clicked, \a item is \c nullptr. This happens for a click inside the legend padding or the space
13439 clicking. It is not emitted when the selection state of an object has changed programmatically by
13440 a direct call to <tt>setSelected()</tt>/<tt>setSelection()</tt> on an object or by calling \ref
13443 In addition to this signal, selectable objects also provide individual signals, for example \ref
13444 QCPAxis::selectionChanged or \ref QCPAbstractPlottable::selectionChanged. Note that those signals
13454 This signal is emitted immediately before a replot takes place (caused by a call to the slot \ref
13457 It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them
13465 This signal is emitted immediately after the layout step has been completed, which occurs right
13466 before drawing the plot. This is typically during a call to \ref replot, and in such cases this
13471 The layout step queries all layouts and layout elements in the plot for their proposed size and
13473 signal, you have the opportunity to update certain things in your plot that depend crucially on
13477 affect the layouting (e.g. axis range order of magnitudes, tick label sizes, etc.) will not issue
13486 This signal is emitted immediately after a replot has taken place (caused by a call to the slot \ref
13489 It is safe to mutually connect the replot slot with this signal on two QCustomPlots to make them
13503 yAxis2) and the \ref legend. They make it very easy working with plots that only have a single
13511 axis is added in the place of the main axis rect, QCustomPlot resets the convenience pointers to
13512 the according new axes. Similarly the \ref legend convenience pointer will be reset if a legend
13521 yAxis2) and the \ref legend. They make it very easy working with plots that only have a single
13529 axis is added in the place of the main axis rect, QCustomPlot resets the convenience pointers to
13530 the according new axes. Similarly the \ref legend convenience pointer will be reset if a legend
13541 yAxis2) and the \ref legend. They make it very easy working with plots that only have a single
13549 axis is added in the place of the main axis rect, QCustomPlot resets the convenience pointers to
13550 the according new axes. Similarly the \ref legend convenience pointer will be reset if a legend
13556 A pointer to the secondary y Axis (right) of the main axis rect of the plot. Secondary axes are
13561 yAxis2) and the \ref legend. They make it very easy working with plots that only have a single
13569 axis is added in the place of the main axis rect, QCustomPlot resets the convenience pointers to
13570 the according new axes. Similarly the \ref legend convenience pointer will be reset if a legend
13576 A pointer to the default legend of the main axis rect. The legend is invisible by default. Use
13580 yAxis2) and the \ref legend. They make it very easy working with plots that only have a single
13584 QCPAxisRect::insetLayout "inset layout", and must then also be accessed via the inset layout. If
13585 the default legend is removed due to manipulation of the layout system (e.g. by removing the main
13589 axis is added in the place of the main axis rect, QCustomPlot resets the convenience pointers to
13590 the according new axes. Similarly the \ref legend convenience pointer will be reset if a legend
13709 qDeleteAll(mLayers); // don't use removeLayer, because it would prevent the last layer to be removed
13714 Sets which elements are forcibly drawn antialiased as an \a or combination of QCP::AntialiasedElement.
13716 This overrides the antialiasing settings for whole element groups, normally controlled with the
13718 \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on
13721 For example, if \a antialiasedElements contains \ref QCP::aePlottables, all plottables will be
13722 drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set
13725 if an element in \a antialiasedElements is already set in \ref setNotAntialiasedElements, it is
13746void QCustomPlot::setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled)
13762 This overrides the antialiasing settings for whole element groups, normally controlled with the
13764 \ref setAntialiasedElements nor in \ref setNotAntialiasedElements, the antialiasing setting on
13767 For example, if \a notAntialiasedElements contains \ref QCP::aePlottables, no plottables will be
13768 drawn antialiased, no matter what the specific QCPAbstractPlottable::setAntialiased value was set
13771 if an element in \a notAntialiasedElements is already set in \ref setAntialiasedElements, it is
13776void QCustomPlot::setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements)
13792void QCustomPlot::setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled)
13805 If set to true, adding a plottable (e.g. a graph) to the QCustomPlot automatically also adds the
13816 Sets the possible interactions of this QCustomPlot as an or-combination of \ref QCP::Interaction
13819 <b>Axis range manipulation</b> is controlled via \ref QCP::iRangeDrag and \ref QCP::iRangeZoom. When the
13820 respective interaction is enabled, the user may drag axes ranges and zoom with the mouse wheel.
13821 For details how to control which axes the user may drag/zoom and in what orientations, see \ref
13822 QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeDragAxes,
13830 special page about the \ref dataselection "data selection mechanism". To retrieve a list of all
13834 <b>Item selection</b> is controlled by \ref QCP::iSelectItems. If \ref QCP::iSelectItems is set, the user
13835 may select items (QCPItemLine, QCPItemText,...) by clicking on them or in their vicinity. To find
13836 out whether a specific item is selected, call QCPAbstractItem::selected(). To retrieve a list of
13839 <b>Axis selection</b> is controlled with \ref QCP::iSelectAxes. If \ref QCP::iSelectAxes is set, the user
13840 may select parts of the axes by clicking on them. What parts exactly (e.g. Axis base line, tick
13843 selectedAxes. Which parts of an axis are selected, can be retrieved with QCPAxis::selectedParts().
13845 <b>Legend selection</b> is controlled with \ref QCP::iSelectLegend. If this is set, the user may
13848 legend or any of its child items are selected, check the value of QCPLegend::selectedParts. To
13852 QCPTextElement, or your own layerable subclasses) is controlled with \ref QCP::iSelectOther. If set, the
13853 user may select those objects by clicking on them. To find out which are currently selected, you
13856 If the selection state has changed by user interaction, the \ref selectionChangedByUser signal is
13857 emitted. Each selectable object additionally emits an individual selectionChanged signal whenever
13864 corresponding signals, when an object is clicked or double clicked. see \ref plottableClick and
13890 Sets the tolerance that is used to decide whether a click selects an object (e.g. a plottable) or
13894 potential selection when the minimum distance between the click position and the graph line is
13895 smaller than \a pixels. Objects that are defined by an area (e.g. QCPBars) only react to clicks
13896 directly inside the area and ignore this selection tolerance. In other words, it only has meaning
13910 performance during dragging. Thus it creates a more responsive user experience. As soon as the
13922 Sets the plotting hints for this QCustomPlot instance as an \a or combination of QCP::PlottingHint.
13952 objects (or data points) by clicking on them one after the other while holding down \a modifier.
13968 QCPAxisRect::setRangeDrag. If \a mode is not \ref QCP::srmNone, the current selection rect (\ref
13971 If you wish to provide your user both with axis range dragging and data selection/range zooming,
13973 reaction to the \ref mousePress or \ref mouseMove signals. For example you could check whether
13976 If a selection rect interaction is currently active, and \a mode is set to \ref QCP::srmNone, the
13977 interaction is canceled (\ref QCPSelectionRect::cancel). Switching between any of the other modes
13988 mSelectionRect->cancel(); // when switching to none, we immediately want to abort a potentially active selection rect
13992 disconnect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*)));
13994 disconnect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*)));
13998 connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*)));
14000 connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*)));
14008 QCP::srmNone and the user performs a click-and-drag interaction. QCustomPlot takes ownership of
14026 connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectSelection(QRect,QMouseEvent*)));
14028 connect(mSelectionRect, SIGNAL(accepted(QRect,QMouseEvent*)), this, SLOT(processRectZoom(QRect,QMouseEvent*)));
14033 \warning This is still an experimental feature and its performance depends on the system that it
14041 continue plotting with hardware acceleration. The parameter \a multisampling controls how many
14043 multisampling is set too high for the current graphics hardware, the maximum allowed value will
14051 If switching to OpenGL was successful, this method disables label caching (\ref setPlottingHint
14052 "setPlottingHint(QCP::phCacheLabels, false)") and turns on QCustomPlot's antialiasing override
14053 for all elements (\ref setAntialiasedElements "setAntialiasedElements(QCP::aeAll)"), leading to a
14055 OpenGL paint device. As stated before, in OpenGL rendering the actual antialiasing of the plot is
14056 controlled with \a multisampling. If \a enabled is set to false, the antialiasing/label caching
14057 settings are restored to what they were before OpenGL was enabled, if they weren't altered in the
14060 \note OpenGL support is only enabled if QCustomPlot is compiled with the macro \c QCUSTOMPLOT_USE_OPENGL
14061 defined. This define must be set before including the QCustomPlot header both during compilation
14062 of the QCustomPlot library as well as when compiling your application. It is best to just include
14064 \note If you are using a Qt version before 5.0, you must also add the module "opengl" to your \c
14065 QT variable in the qmake project files. For Qt versions 5.0 and higher, QCustomPlot switches to a
14077 // backup antialiasing override and labelcaching setting so we can restore upon disabling OpenGL
14080 // set antialiasing override to antialias all (aligns gl pixel grid properly), and disable label caching (would use software rasterizer for pixmap caches):
14085 qDebug() << Q_FUNC_INFO << "Failed to enable OpenGL, continuing plotting without hardware acceleration.";
14090 // restore antialiasing override and labelcaching to what it was before enabling OpenGL, if nobody changed it in the meantime:
14110 The viewport is the area in which the plot is drawn. All mechanisms, e.g. margin calculation take
14114 Don't confuse the viewport with the axis rect (QCustomPlot::axisRect). An axis rect is typically
14115 an area enclosed by four axes, where the graphs/plottables are drawn in. The viewport is larger
14116 and contains also the axes themselves, their tick numbers, their labels, or even additional axis
14133 QWidget::devicePixelRatio which is configured by Qt to fit the display device (e.g. 1 for normal
14136 Device pixel ratios are supported by Qt only for Qt versions since 5.4. If this method is called
14137 when QCustomPlot is being used with older Qt versions, outputs an according qDebug message and
14157 Sets \a pm as the viewport background pixmap (see \ref setViewport). The pixmap is always drawn
14160 For cases where the provided pixmap doesn't have the same size as the viewport, scaling can be
14161 enabled with \ref setBackgroundScaled and the scaling mode (whether and how the aspect ratio is
14162 preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call,
14180 Before drawing everything else, the background is filled with \a brush. If a background pixmap
14181 was set with \ref setBackground(const QPixmap &pm), this brush will be used to fill the viewport
14182 before the background pixmap is drawn. This can be useful for background pixmaps with translucent
14211 Sets whether the viewport background pixmap shall be scaled to fit the viewport. If \a scaled is
14212 set to true, control whether and how the aspect ratio of the original pixmap is preserved with
14239 There is an overloaded version of this function with no parameter which returns the last added
14258 Returns the last plottable that was added to the plot. If there are no plottables in the plot,
14341 Returns a list of the selected plottables. If no plottables are currently selected, the list is empty.
14343 There is a convenience function if you're only interested in selected graphs, see \ref selectedGraphs.
14367QCPAbstractPlottable *QCustomPlot::plottableAt(const QPointF &pos, bool onlySelectable, int *dataIndex) const
14383 There is an overloaded version of this function with no parameter which returns the last created
14402 Returns the last graph, that was created with \ref addGraph. If there are no graphs in the plot,
14417 Creates a new graph inside the plot. If \a keyAxis and \a valueAxis are left unspecified (0), the
14434 qDebug() << Q_FUNC_INFO << "can't use default QCustomPlot xAxis or yAxis, because at least one is invalid (has been deleted)";
14450 legend item is also removed from the default legend (QCustomPlot::legend). If any other graphs in
14451 the plot have a channel fill set towards the removed graph, the channel fill property of those
14476 Removes all graphs from the plot and deletes them. Corresponding legend items are also removed
14502 Returns a list of the selected graphs. If no graphs are currently selected, the list is empty.
14504 If you are not only interested in selected graphs but other plottables like QCPCurve, QCPBars,
14507 \see setInteractions, selectedPlottables, QCPAbstractPlottable::setSelectable, QCPAbstractPlottable::setSelection
14523 There is an overloaded version of this function with no parameter which returns the last added
14658 Returns the layer with the specified \a name. If there is no layer with the specified name, \c
14705 Returns true on success, i.e. if there is a layer with the specified \a name in the QCustomPlot.
14735 qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast<quintptr>(layer);
14754 Adds a new layer to this QCustomPlot instance. The new layer will have the name \a name, which
14755 must be unique. Depending on \a insertMode, it is positioned either below or above \a otherLayer.
14766bool QCustomPlot::addLayer(const QString &name, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode)
14791 All layerables (e.g. plottables and items) on the removed layer will be moved to the layer below
14792 \a layer. If \a layer is the bottom layer, the layerables are moved to the layer above. In both
14806 qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast<quintptr>(layer);
14815 // append all children of this layer to layer below (if this is lowest layer, prepend to layer above)
14841 Moves the specified \a layer either above or below \a otherLayer. Whether it's placed above or
14849bool QCustomPlot::moveLayer(QCPLayer *layer, QCPLayer *otherLayer, QCustomPlot::LayerInsertMode insertMode)
14853 qDebug() << Q_FUNC_INFO << "layer not a layer of this QCustomPlot:" << reinterpret_cast<quintptr>(layer);
14905 example, use \ref QCPLayoutGrid::element of the top level grid layout, and \c qobject_cast the
14961 Only visible elements are used. If \ref QCPLayoutElement::setVisible on the element itself or on
14987 Returns the layout element of type \ref QCPAxisRect at pixel position \a pos. This method ignores
14991 Only visible axis rects are used. If \ref QCPLayoutElement::setVisible on the axis rect itself or
15042 Returns the legends that currently have selected parts, i.e. whose selection state is not \ref
15079 selectionChangedByUser signal. The individual selectionChanged signals are emitted though, if the
15095 refreshed with the new buffer contents. This is the method that must be called to make changes to
15098 The parameter \a refreshPriority can be used to fine-tune the timing of the replot. For example
15100 functions change some aspects of the plot and each wants to make sure the change gets replotted),
15102 actual replotting is deferred to the next event loop iteration. Multiple successive calls of \ref
15106 Under a few circumstances, QCustomPlot causes a replot by itself. Those are resize events of the
15114 If a layer is in mode \ref QCPLayer::lmBuffered (\ref QCPLayer::setMode), it is also possible to
15154 if ((refreshPriority == rpRefreshHint && mPlottingHints.testFlag(QCP::phImmediateRefresh)) || refreshPriority==rpImmediateRefresh)
15165 mReplotTimeAverage = mReplotTimeAverage*0.9 + mReplotTime*0.1; // exponential moving average with a time constant of 10 last replots
15187 if \a onlyVisiblePlottables is set to true, only the plottables that have their visibility set to true
15203 Saves a PDF with the vectorized plot to the file \a fileName. The axis ratio as well as the scale
15205 output will look like the normal on-screen output of a QCustomPlot widget with the corresponding
15206 pixel width and height. If either \a width or \a height is zero, the exported image will have the
15209 Setting \a exportPen to \ref QCP::epNoCosmetic allows to disable the use of cosmetic pens when
15210 drawing to the PDF file. Cosmetic pens are pens with numerical width 0, which are always drawn as
15211 a one pixel wide line, no matter what zoom factor is set in the PDF-Viewer. For more information
15215 selected objects to be painted in their selected look, deselect everything with \ref deselectAll
15221 \li If you plan on editing the exported PDF file with a vector graphics editor like Inkscape, it
15223 (which might be quite many, because cosmetic pens are the default for e.g. axes and tick marks).
15231 \a pdfCreator and \a pdfTitle may be used to set the according metadata fields in the resulting
15239bool QCustomPlot::savePdf(const QString &fileName, int width, int height, QCP::ExportPen exportPen, const QString &pdfCreator, const QString &pdfTitle)
15249 qDebug() << Q_FUNC_INFO << "Qt was built without printer support (QT_NO_PRINTER). PDF not created.";
15278 pageLayout.setPageSize(QPageSize(viewport().size(), QPageSize::Point, QString(), QPageSize::ExactMatch));
15303 Saves a PNG image file to \a fileName on disc. The output plot will have the dimensions \a width
15305 current width and height of the QCustomPlot widget is used instead. Line widths and texts etc.
15306 are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale
15309 For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an
15310 image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths,
15311 texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full
15314 If you use a high scaling factor, it is recommended to enable antialiasing for all elements by
15315 temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows
15318 image compression can be controlled with the \a quality parameter which must be between 0 and 100
15321 The \a resolution will be written to the image file header and has no direct consequence for the
15322 quality or the pixel size. However, if opening the image with a tool which respects the metadata,
15323 it will be able to scale the image to match either a given size in real units of length (inch,
15324 centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is
15328 Returns true on success. If this function fails, most likely the PNG format isn't supported by
15331 The objects of the plot will appear in the current selection state. If you don't want any selected
15332 objects to be painted in their selected look, deselect everything with \ref deselectAll before calling
15335 If you want the PNG to have a transparent background, call \ref setBackground(const QBrush &brush)
15338 \warning If calling this function inside the constructor of the parent of the QCustomPlot widget
15347bool QCustomPlot::savePng(const QString &fileName, int width, int height, double scale, int quality, int resolution, QCP::ResolutionUnit resolutionUnit)
15349 return saveRastered(fileName, width, height, scale, "PNG", quality, resolution, resolutionUnit);
15353 Saves a JPEG image file to \a fileName on disc. The output plot will have the dimensions \a width
15355 current width and height of the QCustomPlot widget is used instead. Line widths and texts etc.
15356 are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale
15359 For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an
15360 image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths,
15361 texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full
15364 If you use a high scaling factor, it is recommended to enable antialiasing for all elements by
15365 temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows
15368 image compression can be controlled with the \a quality parameter which must be between 0 and 100
15371 The \a resolution will be written to the image file header and has no direct consequence for the
15372 quality or the pixel size. However, if opening the image with a tool which respects the metadata,
15373 it will be able to scale the image to match either a given size in real units of length (inch,
15374 centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is
15378 Returns true on success. If this function fails, most likely the JPEG format isn't supported by
15381 The objects of the plot will appear in the current selection state. If you don't want any selected
15382 objects to be painted in their selected look, deselect everything with \ref deselectAll before calling
15385 \warning If calling this function inside the constructor of the parent of the QCustomPlot widget
15394bool QCustomPlot::saveJpg(const QString &fileName, int width, int height, double scale, int quality, int resolution, QCP::ResolutionUnit resolutionUnit)
15396 return saveRastered(fileName, width, height, scale, "JPG", quality, resolution, resolutionUnit);
15400 Saves a BMP image file to \a fileName on disc. The output plot will have the dimensions \a width
15402 current width and height of the QCustomPlot widget is used instead. Line widths and texts etc.
15403 are not scaled up when larger widths/heights are used. If you want that effect, use the \a scale
15406 For example, if you set both \a width and \a height to 100 and \a scale to 2, you will end up with an
15407 image file of size 200*200 in which all graphical elements are scaled up by factor 2 (line widths,
15408 texts, etc.). This scaling is not done by stretching a 100*100 image, the result will have full
15411 If you use a high scaling factor, it is recommended to enable antialiasing for all elements by
15412 temporarily setting \ref QCustomPlot::setAntialiasedElements to \ref QCP::aeAll as this allows
15415 The \a resolution will be written to the image file header and has no direct consequence for the
15416 quality or the pixel size. However, if opening the image with a tool which respects the metadata,
15417 it will be able to scale the image to match either a given size in real units of length (inch,
15418 centimeters, etc.), or the target display DPI. You can specify in which units \a resolution is
15422 Returns true on success. If this function fails, most likely the BMP format isn't supported by
15425 The objects of the plot will appear in the current selection state. If you don't want any selected
15426 objects to be painted in their selected look, deselect everything with \ref deselectAll before calling
15429 \warning If calling this function inside the constructor of the parent of the QCustomPlot widget
15438bool QCustomPlot::saveBmp(const QString &fileName, int width, int height, double scale, int resolution, QCP::ResolutionUnit resolutionUnit)
15446 (\ref plotLayout). To prevent QCustomPlot from being collapsed to size/width zero, set a minimum
15447 size (setMinimumSize) either on the whole QCustomPlot or on any layout elements inside the plot.
15448 This is especially important, when placed in a QLayout where other components try to take in as
15468 Event handler for when the QCustomPlot widget needs repainting. This does not cause a \ref replot, but
15475 // detect if the device pixel ratio has changed (e.g. moving window between different DPI screens), and adapt buffers if necessary:
15494 painter.setRenderHint(QPainter::HighQualityAntialiasing); // to make Antialiasing look good if using the OpenGL graphicssystem
15506 Event handler for a resize of the QCustomPlot widget. The viewport (which becomes the outer rect
15514 replot(rpQueuedRefresh); // queued refresh is important here, to prevent painting issues in some contexts (e.g. MDI subwindow)
15532 // determine layerable under the cursor (this event is called instead of the second press event in a double-click):
15537 event->accept(); // default impl of QCPLayerable's mouse events ignore the event, in that case propagate to next candidate in list
15562 else if (QCPAbstractLegendItem *li = qobject_cast<QCPAbstractLegendItem*>(candidates.first()))
15574 selection rect. Otherwise determines the layerable under the cursor and forwards the event to it.
15587 if (mSelectionRectMode != QCP::srmZoom || qobject_cast<QCPAxisRect*>(axisRectAt(mMousePressPos))) // in zoom mode only activate selection rect if on an axis rect
15591 // no selection rect interaction, prepare for click signal emission and forward event to layerable under the cursor:
15596 mMouseSignalLayerable = candidates.first(); // candidate for signal emission is always topmost hit layerable (signal emitted in release event)
15602 event->accept(); // default impl of QCPLayerable's mouse events call ignore() on the event, in that case propagate to next candidate in list
15620 If the selection rect (\ref setSelectionRect) is currently active, the event is forwarded to it
15623 Otherwise, if a layout element has mouse capture focus (a mousePressEvent happened on top of the
15633 mMouseHasMoved = true; // moved too far from mouse press position, don't handle as click on mouse release
15648 mousePressEvent, it is considered a click which causes the selection mechanism (if activated via
15649 \ref setInteractions) to possibly change selection states accordingly. Further, specialized mouse
15661 if (!mMouseHasMoved) // mouse hasn't moved (much) between press and release, so handle as click
15663 if (mSelectionRect && mSelectionRect->isActive()) // a simple click shouldn't successfully finish a selection rect, so cancel it here
15681 else if (QCPAbstractLegendItem *li = qobject_cast<QCPAbstractLegendItem*>(mMouseSignalLayerable))
15686 if (mSelectionRect && mSelectionRect->isActive()) // Note: if a click was detected above, the selection rect is canceled there
15724 event->accept(); // default impl of QCPLayerable's mouse events ignore the event, in that case propagate to next candidate in list
15734 This function draws the entire plot, including background pixmap, with the specified \a painter.
15738 Note that it does not fill the background with the background brush (as the user may specify with
15767 Performs the layout update steps defined by \ref QCPLayoutElement::UpdatePhase, by calling \ref
15770 Here, the layout elements calculate their positions and margins, and prepare for the following
15788 depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside
15790 mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when
15792 dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was
15813 mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mViewport.size(), mBackgroundScaledMode, Qt::SmoothTransformation);
15814 painter->drawPixmap(mViewport.topLeft(), mScaledBackgroundPixmap, QRect(0, 0, mViewport.width(), mViewport.height()) & mScaledBackgroundPixmap.rect());
15817 painter->drawPixmap(mViewport.topLeft(), mBackgroundPixmap, QRect(0, 0, mViewport.width(), mViewport.height()));
15827 associates the paint buffers with the layers, so they draw themselves into the right buffer when
15834 After this method, the paint buffers are empty (filled with \c Qt::transparent) and invalidated
15837 This method is called in every \ref replot call, prior to actually drawing the layers (into their
15859 if (layerIndex < mLayers.size()-1 && mLayers.at(layerIndex+1)->mode() == QCPLayer::lmLogical) // not last layer, and next one is logical, so prepare another buffer for next layerables
15892 return new QCPPaintBufferGlFbo(viewport().size(), mBufferDevicePixelRatio, mGlContext, mGlPaintDevice);
15894 return new QCPPaintBufferGlPbuffer(viewport().size(), mBufferDevicePixelRatio, mOpenGlMultisamples);
15907 If any buffer is invalidated, a partial replot (\ref QCPLayer::replot) is not allowed and always
15908 causes a full replot (\ref QCustomPlot::replot) of all layers. This is the case when for example
15926 When \ref setOpenGl is set to true, this method is used to initialize OpenGL (create a context,
15931 If this method is successful, all paint buffers should be deleted and then reallocated by calling
16025 This method is used by the QCPLegend destructor to report legend removal to the QCustomPlot so
16036 This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref
16039 First, it determines which axis rect was the origin of the selection rect judging by the starting
16040 point of the selection. Then it goes through the plottables (\ref QCPAbstractPlottable1D to be
16041 precise) associated with that axis rect and finds the data points that are in \a rect. It does
16046 parameter as <tt>QVariant(\ref QCPDataSelection)</tt>. All plottables that weren't touched by \a
16054 typedef QMultiMap<int, SelectionCandidate> SelectionCandidates; // map key is number of selected data points, so we have selections sorted by size
16077 // only leave plottable with most selected points in map, since we will only select a single plottable:
16095 if ((potentialSelections.isEmpty() || potentialSelections.constBegin()->first != layerable) && mInteractions.testFlag(layerable->selectionCategory()))
16113 it.value().first->selectEvent(event, additive, QVariant::fromValue(it.value().second), &selChanged);
16130 This slot is connected to the selection rect's \ref QCPSelectionRect::accepted signal when \ref
16133 It determines which axis rect was the origin of the selection rect judging by the starting point
16134 of the selection, and then zooms the axes defined via \ref QCPAxisRect::setRangeZoomAxes to the
16144 QList<QCPAxis*> affectedAxes = QList<QCPAxis*>() << axisRect->rangeZoomAxes(Qt::Horizontal) << axisRect->rangeZoomAxes(Qt::Vertical);
16156 QCPLayerable::selectEvent. All other layerables receive a QCPLayerable::deselectEvent (unless the
16159 In this method the hit layerable is determined a second time using \ref layerableAt (after the
16162 clicked layerable determined here. For example, if a non-selectable layerable is in front of a
16163 selectable layerable at the click position, the front layerable will receive mouse events but the
16173 bool additive = mInteractions.testFlag(QCP::iMultiSelect) && event->modifiers().testFlag(mMultiSelectModifier);
16206 Registers the specified plottable with this QCustomPlot and, if \ref setAutoAddPlottableToLegend
16210 Returns true on success, i.e. when \a plottable isn't already in this plot and the parent plot of
16219 qDebug() << Q_FUNC_INFO << "plottable already added to this QCustomPlot:" << reinterpret_cast<quintptr>(plottable);
16224 qDebug() << Q_FUNC_INFO << "plottable not created with this QCustomPlot as parent:" << reinterpret_cast<quintptr>(plottable);
16232 if (!plottable->layer()) // usually the layer is already set in the constructor of the plottable (via QCPLayerable constructor)
16239 In order to maintain the simplified graph interface of QCustomPlot, this method is called by the
16240 QCPGraph constructor to register itself with this QCustomPlot's internal graph list. Returns true
16243 This graph specific registration happens in addition to the call to \ref registerPlottable by the
16268 Returns true on success, i.e. when \a item wasn't already in the plot and the parent plot of \a
16277 qDebug() << Q_FUNC_INFO << "item already added to this QCustomPlot:" << reinterpret_cast<quintptr>(item);
16282 qDebug() << Q_FUNC_INFO << "item not created with this QCustomPlot as parent:" << reinterpret_cast<quintptr>(item);
16287 if (!item->layer()) // usually the layer is already set in the constructor of the item (via QCPLayerable constructor)
16294 Assigns all layers their index (QCPLayer::mIndex) in the mLayers list. This method is thus called
16295 after every operation that changes the layer indices, like layer removal, layer creation, layer
16307 only those layerables that are selectable will be considered. (Layerable subclasses communicate
16312 QCPLayerable::selectEvent (like in \ref mouseReleaseEvent). \a selectionDetails usually contains
16314 QCPAxis::SelectablePart). If the layerable is a plottable, \a selectionDetails contains a \ref
16319QCPLayerable *QCustomPlot::layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails) const
16322 QList<QCPLayerable*> candidates = layerableListAt(pos, onlySelectable, selectionDetails ? &details : nullptr);
16333 Returns the layerables at pixel position \a pos. If \a onlySelectable is set to true, only those
16337 The returned list is sorted by the layerable/drawing order such that the layerable that appears
16343 QCPLayerable::selectEvent (like in \ref mouseReleaseEvent). \a selectionDetails usually contains
16345 QCPAxis::SelectablePart). If the layerable is a plottable, \a selectionDetails contains a \ref
16350QList<QCPLayerable*> QCustomPlot::layerableListAt(const QPointF &pos, bool onlySelectable, QList<QVariant> *selectionDetails) const
16374 Saves the plot to a rastered image file \a fileName in the image format \a format. The plot is
16375 sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and scale 2.0 lead
16376 to a full resolution file with width 200.) If the \a format supports compression, \a quality may
16379 Returns true on success. If this function fails, most likely the given \a format isn't supported
16382 The \a resolution will be written to the image file header (if the file format supports this) and
16383 has no direct consequence for the quality or the pixel size. However, if opening the image with a
16384 tool which respects the metadata, it will be able to scale the image to match either a given size
16385 in real units of length (inch, centimeters, etc.), or the target display DPI. You can specify in
16386 which units \a resolution is given, by setting \a resolutionUnit. The \a resolution is converted
16391bool QCustomPlot::saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality, int resolution, QCP::ResolutionUnit resolutionUnit)
16402 buffer.setDotsPerMeterX(dotsPerMeter); // this is saved together with some image formats, e.g. PNG, and is relevant when opening image in other tools
16403 buffer.setDotsPerMeterY(dotsPerMeter); // this is saved together with some image formats, e.g. PNG, and is relevant when opening image in other tools
16413 The plot is sized to \a width and \a height in pixels and scaled with \a scale. (width 100 and
16420 // this method is somewhat similar to toPainter. Change something here, and a change in toPainter might be necessary, too.
16435 result.fill(mBackgroundBrush.style() == Qt::SolidPattern ? mBackgroundBrush.color() : Qt::transparent); // if using non-solid pattern, make transparent now and draw brush pattern later
16445 if (scale > 1.0) // for scale < 1 we always want cosmetic pens where possible, because else lines might disappear for very small scales
16449 if (mBackgroundBrush.style() != Qt::SolidPattern && mBackgroundBrush.style() != Qt::NoBrush) // solid fills were done a few lines above with QPixmap::fill
16465 The plot is sized to \a width and \a height in pixels. If the \a painter's scale is not 1.0, the resulting plot will
16468 \note If you are restricted to using a QPainter (instead of QCPPainter), create a temporary QPicture and open a QCPPainter
16469 on it. Then call \ref toPainter with this QCPPainter. After ending the paint operation on the picture, draw it with
16476 // this method is somewhat similar to toPixmap. Change something here, and a change in toPixmap might be necessary, too.
16493 if (mBackgroundBrush.style() != Qt::NoBrush) // unlike in toPixmap, we can't do QPixmap::fill for Qt::SolidPattern brush style, so we also draw solid fills with fillRect here
16507////////////////////////////////////////////////////////////////////////////////////////////////////
16509////////////////////////////////////////////////////////////////////////////////////////////////////
16514 This class describes a color gradient which can be used to encode data with color. For example,
16516 take an instance of this class. Colors are set with \ref setColorStopAt(double position, const QColor &color)
16518 color will be interpolated linearly either in RGB or HSV space, see \ref setColorInterpolation.
16523 Apart from red, green and blue components, the gradient also interpolates the alpha values of the
16524 configured color stops. This allows to display some portions of the data range as transparent in
16531 The constructor \ref QCPColorGradient(GradientPreset preset) allows directly converting a \ref
16532 GradientPreset to a QCPColorGradient. This means that you can directly pass \ref GradientPreset
16536 The total number of levels used in the gradient can be set with \ref setLevelCount. Whether the
16537 color gradient shall be applied periodically (wrapping around) to data values that lie outside
16542 Constructs a new, empty QCPColorGradient with no predefined color stops. You can add own color
16559 Constructs a new QCPColorGradient initialized with the colors and color interpolation according
16588 Sets the number of discretization levels of the color gradient to \a n. The default is 350 which
16609 colors are the values of the passed QMap \a colorStops. In between these color stops, the color
16613 clearColorStops (or creating a new, empty QCPColorGradient) and then adding them one by one with
16625 Sets the \a color the gradient will have at the specified \a position (from 0 to 1). In between
16637 Sets whether the colors in between the configured color stops (see \ref setColorStopAt) shall be
16640 For example, a sweep in RGB space from red to green will have a muddy brown intermediate color,
16643void QCPColorGradient::setColorInterpolation(QCPColorGradient::ColorInterpolation interpolation)
16675 QCPColorMap::setDataRange) are colored by periodically repeating the color gradient or whether
16681 suitable for a periodic gradient mapping, since they produce smooth color transitions throughout
16684 In practice, using periodic color gradients makes sense when the data corresponds to a periodic
16685 dimension, such as an angle or a phase. If this is not the case, the color encoding might become
16695 This method is used to quickly convert a \a data array to colors. The colors will be output in
16696 the array \a scanLine. Both \a data and \a scanLine must have the length \a n when passed to this
16697 function. The data range that shall be used for mapping the data value to the gradient is passed
16701 if \a data actually contains 2D-data linearized via <tt>[row*columnCount + column]</tt>, you can
16702 set \a dataIndexFactor to <tt>columnCount</tt> to convert a column instead of a row of the data
16703 array, in \a scanLine. \a scanLine will remain a regular (1D) array. This works because \a data
16708 The QRgb values that are placed in \a scanLine have their r, g, and b components premultiplied
16711void QCPColorGradient::colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor, bool logarithmic)
16713 // If you change something here, make sure to also adapt color() and the other colorize() overload
16728 const double posToIndexFactor = !logarithmic ? (mLevelCount-1)/range.size() : (mLevelCount-1)/qLn(range.upper/range.lower);
16761 Additionally to the other overload of \ref colorize, this method takes the array \a alpha, which
16767void QCPColorGradient::colorize(const double *data, const unsigned char *alpha, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor, bool logarithmic)
16769 // If you change something here, make sure to also adapt color() and the other colorize() overload
16789 const double posToIndexFactor = !logarithmic ? (mLevelCount-1)/range.size() : (mLevelCount-1)/qLn(range.upper/range.lower);
16795 qint64 index = qint64((!logarithmic ? value-range.lower : qLn(value/range.lower)) * posToIndexFactor);
16859 const double posToIndexFactor = !logarithmic ? (mLevelCount-1)/range.size() : (mLevelCount-1)/qLn(range.upper/range.lower);
16874 Clears the current color stops and loads the specified \a preset. A preset consists of predefined
17005 for (QMap<double, QColor>::const_iterator it=mColorStops.constBegin(); it!=mColorStops.constEnd(); ++it)
17012 Returns true if the color gradient uses transparency, i.e. if any of the configured color stops
17017 for (QMap<double, QColor>::const_iterator it=mColorStops.constBegin(); it!=mColorStops.constEnd(); ++it)
17027 Updates the internal color buffer which will be used by \ref colorize and \ref color, to quickly
17028 convert positions to colors. This is where the interpolation between color stops is calculated.
17041 QMap<double, QColor>::const_iterator it = const_cast<const QMap<double, QColor>*>(&mColorStops)->lowerBound(position); // force using the const lowerBound method
17042 if (it == mColorStops.constEnd()) // position is on or after last stop, use color of last stop
17047 const double alphaPremultiplier = col.alpha()/255.0; // since we use QImage::Format_ARGB32_Premultiplied
17054 } else if (it == mColorStops.constBegin()) // position is on or before first stop, use color of first stop
17059 const double alphaPremultiplier = col.alpha()/255.0; // since we use QImage::Format_ARGB32_Premultiplied
17078 const double alphaPremultiplier = alpha/255.0; // since we use QImage::Format_ARGB32_Premultiplied
17079 mColorBuffer[i] = qRgba(int( ((1-t)*low.value().red() + t*high.value().red())*alphaPremultiplier ),
17111 mColorBuffer[i] = qRgba(int(qRed(rgb)*alpha), int(qGreen(rgb)*alpha), int(qBlue(rgb)*alpha), int(255*alpha));
17141////////////////////////////////////////////////////////////////////////////////////////////////////
17143////////////////////////////////////////////////////////////////////////////////////////////////////
17148 Additionally to the regular highlighting of selected segments via color, fill and scatter style,
17149 this \ref QCPSelectionDecorator subclass draws markers at the begin and end of each selected data
17152 The shape of the markers can be controlled with \ref setBracketStyle, \ref setBracketWidth and
17157 QCPSelectionDecoratorBracket and reimplement \ref drawBracket. The rest will be managed by the
17190 Sets the brush that will be used to draw the brackets at the beginning and end of each selected
17199 Sets the width of the drawn bracket. The width dimension is always parallel to the key axis of
17209 Sets the height of the drawn bracket. The height dimension is always perpendicular to the key axis
17229 Sets whether the brackets will be rotated such that they align with the slope of the data at the
17241 Controls over how many data points the slope shall be averaged, when brackets shall be aligned
17244 From the position of the bracket, \a pointCount points towards the selected data range will be
17245 taken into account. The smallest value of \a pointCount is 1, which is effectively equivalent to
17257 indicates whether the bracket shall point to the left or the right (i.e. is a closing or opening
17274 painter->drawLine(QLineF(mBracketWidth*direction, -mBracketHeight*0.5, 0, -mBracketHeight*0.5));
17275 painter->drawLine(QLineF(mBracketWidth*direction, mBracketHeight*0.5, 0, mBracketHeight*0.5));
17281 painter->drawArc(QRectF(-mBracketWidth*0.5, -mBracketHeight*0.5, mBracketWidth, mBracketHeight), -90*16, -180*16*direction);
17286 painter->drawEllipse(QRectF(-mBracketWidth*0.5, -mBracketHeight*0.5, mBracketWidth, mBracketHeight));
17311void QCPSelectionDecoratorBracket::drawDecoration(QCPPainter *painter, QCPDataSelection selection)
17356 The parameter \a direction must be set to either -1 or 1, representing whether it is an opening
17357 or closing bracket. Since for slope calculation multiple data points are required, this defines
17361 \a interface1d is the interface to the plottable's data which is used to query data coordinates.
17363double QCPSelectionDecoratorBracket::getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, int direction) const
17407 Returns the pixel coordinates of the data point at \a dataIndex, using \a interface1d to access
17410QPointF QCPSelectionDecoratorBracket::getPixelCoordinates(const QCPPlottableInterface1D *interface1d, int dataIndex) const
17414 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return {0, 0}; }
17417 return {keyAxis->coordToPixel(interface1d->dataMainKey(dataIndex)), valueAxis->coordToPixel(interface1d->dataMainValue(dataIndex))};
17419 return {valueAxis->coordToPixel(interface1d->dataMainValue(dataIndex)), keyAxis->coordToPixel(interface1d->dataMainKey(dataIndex))};
17428////////////////////////////////////////////////////////////////////////////////////////////////////
17430////////////////////////////////////////////////////////////////////////////////////////////////////
17443 accessed via \ref axis by providing the respective axis type (\ref QCPAxis::AxisType) and index.
17445 invisible initially (QCPAxis::setVisible). To add more axes to a side, use \ref addAxis or \ref
17454 insetLayout and can be used to have other layout elements (or even other layouts with multiple
17458 behaviour can be controlled with \ref setRangeDrag and \ref setRangeDragAxes. If the mouse wheel
17459 is scrolled while the cursor is on the axis rect, certain axes are scaled. This is controllable
17460 via \ref setRangeZoom, \ref setRangeZoomAxes and \ref setRangeZoomFactor. These interactions are
17523 Returns the top left corner of this axis rect in pixels. Margins are not taken into account here,
17535 Returns the bottom left corner of this axis rect in pixels. Margins are not taken into account
17541 Returns the bottom right corner of this axis rect in pixels. Margins are not taken into account
17547 Returns the center of this axis rect in pixels. Margins are not taken into account here, so the
17641 \a types may be a single \ref QCPAxis::AxisType or an <tt>or</tt>-combination, to get the axes of
17677 Adds a new axis to the axis rect side specified with \a type, and returns it. If \a axis is 0, a
17678 new QCPAxis instance is created internally. QCustomPlot owns the returned axis, so if you want to
17681 You may inject QCPAxis instances (or subclasses of QCPAxis) by setting \a axis to an axis that was
17682 previously created outside QCustomPlot. It is important to note that QCustomPlot takes ownership
17684 with this axis rect as parent and with the same axis type as specified in \a type. If this is not
17685 the case, a debug output is generated, the axis is not added, and the method returns \c nullptr.
17687 This method can not be used to move \a axis between axis rects. The same \a axis instance must
17690 If an axis rect side already contains one or more axes, the lower and upper endings of the new
17706 qDebug() << Q_FUNC_INFO << "passed axis has different axis type than specified in type parameter";
17744 Adds a new axis with \ref addAxis to each axis rect side specified in \a types. This may be an
17774 // don't access axis->axisType() to provide safety when axis is an invalid pointer, rather go through all axis containers:
17781 if (it.value().first() == axis && it.value().size() > 1) // if removing first axis, transfer axis offset to the new first axis (which at this point is the second axis, if it exists)
17784 if (qobject_cast<QCustomPlot*>(parentPlot())) // make sure this isn't called from QObject dtor when QCustomPlot is already destructed (happens when the axis rect is not in any layout and thus QObject-child of QCustomPlot)
17834 Convenience function to create an axis on each side that doesn't have any axes yet and set their
17847 Tick label visibility (\ref QCPAxis::setTickLabels) of the right and top axes are set to false.
17849 If \a connectRanges is true, the \ref QCPAxis::rangeChanged "rangeChanged" signals of the bottom
17910 A plottable is considered associated with an axis rect if its key or value axis (or both) is in
17950 An item is considered associated with an axis rect if any of its positions has key or value axis
17987 Calls the base class implementation to update the margins (see \ref QCPLayoutElement::update),
18044 axis rect. Since axis rects place themselves on the "background" layer by default, the axis rect
18047 For cases where the provided pixmap doesn't have the same size as the axis rect, scaling can be
18048 enabled with \ref setBackgroundScaled and the scaling mode (i.e. whether and how the aspect ratio
18049 is preserved) can be set with \ref setBackgroundScaledMode. To set all these options in one call,
18065 Sets \a brush as the background brush. The axis rect background will be filled with this brush.
18066 Since axis rects place themselves on the "background" layer by default, the axis rect backgrounds
18069 The brush will be drawn before (under) any background pixmap, which may be specified with \ref
18097 Sets whether the axis background pixmap shall be scaled to fit the axis rect or not. If \a scaled
18112 If scaling of the axis background pixmap is enabled (\ref setBackgroundScaled), use this function to
18113 define whether and how the aspect ratio of the original pixmap passed to \ref setBackground is preserved.
18122 Returns the range drag axis of the \a orientation provided. If multiple axes were set, returns
18136 Returns the range zoom axis of the \a orientation provided. If multiple axes were set, returns
18222 In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions
18235 QCPAxis *vertical). By default, the horizontal axis is the bottom axis (xAxis) and the vertical
18242 In addition to setting \a orientations to a non-zero value, make sure \ref QCustomPlot::setInteractions
18254 Sets the axes whose range will be dragged when \ref setRangeDrag enables mouse range dragging on
18258 Use the overload taking a list of axes, if multiple axes (more than one per orientation) shall
18275 This method allows to set up multiple axes to react to horizontal and vertical dragging. The drag
18279 In the unusual case that you wish to e.g. drag a vertically oriented axis with a horizontal drag
18310 qDebug() << Q_FUNC_INFO << "invalid axis passed in horizontal list:" << reinterpret_cast<quintptr>(ax);
18324 Sets the axes whose range will be zoomed when \ref setRangeZoom enables mouse wheel zooming on
18325 the QCustomPlot widget. Pass \c nullptr if no axis shall be zoomed in the respective orientation.
18327 The two axes can be zoomed with different strengths, when different factors are passed to \ref
18330 Use the overload taking a list of axes, if multiple axes (more than one per orientation) shall
18347 This method allows to set up multiple axes to react to horizontal and vertical range zooming. The
18351 In the unusual case that you wish to e.g. zoom a vertically oriented axis with a horizontal zoom
18382 qDebug() << Q_FUNC_INFO << "invalid axis passed in horizontal list:" << reinterpret_cast<quintptr>(ax);
18396 Sets how strong one rotation step of the mouse wheel zooms, when range zoom was activated with
18397 \ref setRangeZoom. The two parameters \a horizontalFactor and \a verticalFactor provide a way to
18398 let the horizontal axis zoom at different rates than the vertical axis. Which axis is horizontal
18401 When the zoom factor is greater than one, scrolling the mouse wheel backwards (towards the user)
18402 will zoom in (make the currently visible range smaller). For zoom factors smaller than one, the
18426 If a brush was given via \ref setBackground(const QBrush &brush), this function first draws an
18429 Then, if a pixmap was provided via \ref setBackground, this function buffers the scaled version
18430 depending on \ref setBackgroundScaled and \ref setBackgroundScaledMode and then draws it inside
18432 mScaledBackgroundPixmap to prevent expensive rescaling at every redraw. It is only updated, when
18434 dependent on the \ref setBackgroundScaledMode), or when a differend axis background pixmap was
18454 mScaledBackgroundPixmap = mBackgroundPixmap.scaled(mRect.size(), mBackgroundScaledMode, Qt::SmoothTransformation);
18455 painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mScaledBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height()) & mScaledBackgroundPixmap.rect());
18458 painter->drawPixmap(mRect.topLeft()+QPoint(0, -1), mBackgroundPixmap, QRect(0, 0, mRect.width(), mRect.height()));
18465 This function makes sure multiple axes on the side specified with \a type don't collide, but are
18468 It does this by setting an appropriate offset (\ref QCPAxis::setOffset) on all axes except the
18479 bool isFirstVisible = !axesList.first()->visible(); // if the first axis is visible, the second axis (which is where the loop starts) isn't the first visible axis, so initialize with false
18483 if (axesList.at(i)->visible()) // only add inner tick length to offset if this axis is visible and it's not the first visible one (might happen if true first axis is invisible)
18513 axes of this axis rect. This is only done if the respective convenience pointer is currently zero
18516 This automation makes it simpler to replace the main axis rect with a newly created one, without
18536 Event handler for when a mouse button is pressed on the axis rect. If the left mouse button is
18537 pressed, the range dragging interaction is initialized (the actual range manipulation happens in
18540 The mDragging flag is set to true and some anchor points are set that are needed to determine the
18572 Event handler for when the mouse is moved on the axis rect. If range dragging was activated in a
18651 Event handler for mouse wheel events. If rangeZoom is Qt::Horizontal, Qt::Vertical or both, the
18652 ranges of the axes defined as rangeZoomHorzAxis and rangeZoomVertAxis are scaled. The center of
18653 the scaling operation is the current cursor position inside the axis rect. The scaling factor is
18654 dependent on the mouse wheel delta (which direction the wheel was rotated) to provide a natural
18657 Note, that event->angleDelta() is usually +/-120 for single rotation steps. However, if the mouse
18658 wheel is turned rapidly, many steps may bunch up to one event, so the delta may then be multiples
18659 of 120. This is taken into account here, by calculating \a wheelSteps and using it as exponent of
18712////////////////////////////////////////////////////////////////////////////////////////////////////
18714////////////////////////////////////////////////////////////////////////////////////////////////////
18719 It defines a very basic interface for entries in a QCPLegend. For representing plottables in the
18722 Only derive directly from this class when you need absolute freedom (e.g. a custom legend entry
18735 <td>The generic font of the item. You should use this font for all or at least the most prominent text of the item.</td>
18744 This signal is emitted when the selection state of this legend item has changed, either by user
18751 Constructs a QCPAbstractLegendItem and associates it with the QCPLegend \a parent. This does not
18752 cause the item to be added to \a parent, so \ref QCPLegend::addItem must be called separately.
18789 When this legend item is selected, \a font is used to draw generic text, instead of the normal
18800 When this legend item is selected, \a color is used to draw generic text, instead of the normal
18827 It is possible to set the selection state of this item by calling this function directly, even if
18842double QCPAbstractLegendItem::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const
18846 if (onlySelectable && (!mSelectable || !mParentLegend->selectableParts().testFlag(QCPLegend::spItems)))
18868void QCPAbstractLegendItem::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
18893////////////////////////////////////////////////////////////////////////////////////////////////////
18895////////////////////////////////////////////////////////////////////////////////////////////////////
18900 This is the standard legend item for plottables. It displays an icon of the plottable next to the
18902 QCPAbstractPlottable::drawLegendIcon), and tries to give an intuitive symbol for the plottable.
18903 For example, the QCPGraph draws a centered horizontal line and/or a single scatter point in the
18907 plottable() function and settable with the constructor). You may change the font of the plottable
18908 name with \ref setFont. Icon padding and border pen is taken from the parent QCPLegend, see \ref
18911 The function \ref QCPAbstractPlottable::addToLegend/\ref QCPAbstractPlottable::removeFromLegend
18915 QCPLayoutElement. While it could be added to a legend (or any other layout) via the normal layout
18916 interface, QCPLegend has specialized functions for handling legend items conveniently, see the
18925 A more convenient way of adding/removing a plottable to/from the legend is via the functions \ref
18928QCPPlottableLegendItem::QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable) :
18947 Returns the text color that shall be used to draw text, taking into account the selection state
18957 Returns the font that shall be used to draw text, taking into account the selection state of this
18967 Draws the item with \a painter. The size and position of the drawn legend item is defined by the
18977 QRect textRect = painter->fontMetrics().boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->name());
18979 int textHeight = qMax(textRect.height(), iconSize.height()); // if text has smaller height than icon, center text vertically in icon height, else align tops
18980 painter->drawText(mRect.x()+iconSize.width()+mParentLegend->iconTextPadding(), mRect.y(), textRect.width(), textHeight, Qt::TextDontClip, mPlottable->name());
18992 painter->setClipRect(mOuterRect.adjusted(-halfPen, -halfPen, halfPen, halfPen)); // extend default clip rect so thicker pens (especially during selection) are not clipped
18999 Calculates and returns the size of this item. This includes the icon, the text and the padding in
19011 textRect = fontMetrics.boundingRect(0, 0, 0, iconSize.height(), Qt::TextDontClip, mPlottable->name());
19020////////////////////////////////////////////////////////////////////////////////////////////////////
19022////////////////////////////////////////////////////////////////////////////////////////////////////
19027 A legend is a small box somewhere in the plot which lists plottables with their name and icon.
19029 A legend is populated with legend items by calling \ref QCPAbstractPlottable::addToLegend on the
19034 QCPAbstractPlottable::removeFromLegend. However, QCPLegend also offers an interface to add and
19040 "QCPLayoutElements" which are placed in the grid layout of the legend. \ref QCPLegend only adds
19042 mentioned above. In principle, any other layout elements may also be added to a legend via the
19043 normal \ref QCPLayoutGrid interface. See the special page about \link thelayoutsystem The Layout
19044 System\endlink for examples on how to add other elements to the legend and move it outside the axis
19047 Use the methods \ref setFillOrder and \ref setWrap inherited from \ref QCPLayoutGrid to control
19048 in which order (column first or row first) the legend is filled up when calling \ref addItem, and
19049 at which column or row wrapping occurs. The default fill order for legends is \ref foRowsFirst.
19051 By default, every QCustomPlot has one legend (\ref QCustomPlot::legend) which is placed in the
19052 inset layout of the main axis rect (\ref QCPAxisRect::insetLayout). To move the legend to another
19054 outside of the axis rect, place it anywhere else with the \ref QCPLayout/\ref QCPLayoutElement
19105 if (qobject_cast<QCustomPlot*>(mParentPlot)) // make sure this isn't called from QObject dtor when QCustomPlot is already destructed (happens when the legend is not in any layout and thus QObject-child of QCustomPlot)
19145 Sets the default font of legend text. Legend items that draw text (e.g. the name of a graph) will
19165 will use this color by default. However, a different colors can be specified on a per-item-basis
19221 Sets whether the user can (de-)select the parts in \a selectable by clicking on the QCustomPlot surface.
19224 However, even when \a selectable is set to a value not allowing the selection of a specific part,
19225 it is still possible to set the selection of this part manually, by calling \ref setSelectedParts
19240 Sets the selected state of the respective legend parts described by \ref SelectablePart. When a part
19241 is selected, it uses a different pen/font and brush. If some legend items are selected and \a selected
19244 The entire selection mechanism is handled automatically when \ref QCustomPlot::setInteractions
19245 contains iSelectLegend. You only need to call this function when you wish to change the selection
19248 This function can change the selection state of a part even when \ref setSelectableParts was set to a
19251 emits the \ref selectionChanged signal when \a selected is different from the previous selection state.
19253 Note that it doesn't make sense to set the selected state \ref spItems here when it wasn't set
19254 before, because there's no way to specify which exact items to newly select. Do this by calling
19257 \see SelectablePart, setSelectableParts, selectTest, setSelectedBorderPen, setSelectedIconBorderPen, setSelectedBrush,
19263 mSelectedParts = this->selectedParts(); // update mSelectedParts in case item selection changed
19267 if (!mSelectedParts.testFlag(spItems) && newSelected.testFlag(spItems)) // attempt to set spItems flag (can't do that)
19269 qDebug() << Q_FUNC_INFO << "spItems flag can not be set, it can only be unset with this function";
19286 When the legend box is selected, this pen is used to draw the border instead of the normal pen
19307 When the legend box is selected, this brush is used to draw the legend background instead of the normal brush
19352 Returns the item with index \a i. If non-legend items were added to the legend, and the element
19365 Returns the QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*).
19370QCPPlottableLegendItem *QCPLegend::itemWithPlottable(const QCPAbstractPlottable *plottable) const
19414 Returns whether the legend contains a QCPPlottableLegendItem which is associated with \a plottable (e.g. a \ref QCPGraph*).
19425 Adds \a item to the legend, if it's not present already. The element is arranged according to the
19428 Returns true on sucess, i.e. if the item wasn't in the list already and has been successfuly added.
19492 removeAt(i); // don't use removeItem() because it would unnecessarily reorder the whole legend for each item
19494 setFillOrder(fillOrder(), true); // get rid of empty cells by reordering once after all items are removed
19519 A convenience function to easily set the QPainter::Antialiased hint on the provided \a painter
19539 Returns the pen used to paint the border of the legend, taking into account the selection state
19549 Returns the brush used to paint the background of the legend, taking into account the selection
19586void QCPLegend::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
19593 setSelectedParts(additive ? mSelectedParts^spLegendBox : mSelectedParts|spLegendBox); // no need to unset spItems in !additive case, because they will be deselected by QCustomPlot (they're normal QCPLayerables with own deselectEvent)
19636////////////////////////////////////////////////////////////////////////////////////////////////////
19638////////////////////////////////////////////////////////////////////////////////////////////////////
19643 The text may be specified with \ref setText, the formatting can be controlled with \ref setFont,
19678 Creates a new QCPTextElement instance and sets default values. The initial text is empty (\ref
19685 mFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below
19687 mSelectedFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below
19710 mFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below
19712 mSelectedFont(QFont(QLatin1String("sans serif"), 12)), // will be taken from parentPlot if available, see below
19731QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, double pointSize) :
19735 mFont(QFont(QLatin1String("sans serif"), int(pointSize))), // will be taken from parentPlot if available, see below
19737 mSelectedFont(QFont(QLatin1String("sans serif"), int(pointSize))), // will be taken from parentPlot if available, see below
19759QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QString &fontFamily, double pointSize) :
19780QCPTextElement::QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QFont &font) :
19795 Sets the text that will be displayed to \a text. Multiple lines can be created by insertion of "\n".
19805 Sets options for text alignment and wrapping behaviour. \a flags is a bitwise OR-combination of
19850 Sets the \a font of the text that will be used if the text element is selected (\ref setSelected).
19860 Sets the \a color of the text that will be used if the text element is selected (\ref setSelected).
19872 Note that even when \a selectable is set to <tt>false</tt>, the selection state may be changed
19885 Sets the selection state of this text element to \a selected. If the selection has changed, \ref
19935void QCPTextElement::selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged)
19962 within the bounding box of the text element's text. Note that this bounding box is updated in the
19970double QCPTextElement::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const
19995 Emits the \ref clicked signal if the cursor hasn't moved by more than a few pixels since the \ref
20043////////////////////////////////////////////////////////////////////////////////////////////////////
20045////////////////////////////////////////////////////////////////////////////////////////////////////
20050 This layout element can be placed on the plot to correlate a color gradient with data values. It
20060 setDataRange, \ref setDataScaleType). Multiple color maps may be associated with a single color
20064 \ref axis. See the documentation of QCPAxis for details about configuring axes. For example, if
20070 In this case we have placed it to the right of the default axis rect, so it wasn't necessary to
20071 call \ref setType, since \ref QCPAxis::atRight is already the default. The text next to the color
20074 For optimum appearance (like in the image above), it may be desirable to line up the axis rect and
20080 margin makes sure it keeps some distance to the top/bottom widget border. So if you change to a
20081 horizontal color scale by setting \ref setType to \ref QCPAxis::atBottom or \ref QCPAxis::atTop, you
20082 might want to also change the minimum margins accordingly, e.g. <tt>setMinimumMargins(QMargins(6, 0, 6, 0))</tt>.
20089 Returns the internal \ref QCPAxis instance of this color scale. You can access it to alter the
20093 QCPAxis::setLabel). As they each are connected, it does not matter whether you use the method on
20097 will change, too, to either the left, right, bottom or top axis, depending on which type was set.
20131 mType(QCPAxis::atTop), // set to atTop such that setType(QCPAxis::atRight) below doesn't skip work because it thinks it's already atRight
20137 setMinimumMargins(QMargins(0, 6, 0, 6)); // for default right color scale types, keep some room at bottom and top (important if no margin group is used)
20170 mAxisRect.data()->rangeDragAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType);
20184 mAxisRect.data()->rangeZoomAxis(QCPAxis::orientation(mType))->orientation() == QCPAxis::orientation(mType);
20191 be a different one. The new axis will adopt the following properties from the previous axis: The
20215 disconnect(mColorAxis.data(), SIGNAL(rangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange)));
20216 disconnect(mColorAxis.data(), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType)));
20218 const QList<QCPAxis::AxisType> allAxisTypes = QList<QCPAxis::AxisType>() << QCPAxis::atLeft << QCPAxis::atRight << QCPAxis::atBottom << QCPAxis::atTop;
20229 mColorAxis.data()->setRange(rangeTransfer); // range transfer necessary if axis changes from vertical to horizontal or vice versa (axes with same orientation are synchronized via signals)
20233 connect(mColorAxis.data(), SIGNAL(rangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange)));
20234 connect(mColorAxis.data(), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType)));
20240 Sets the range spanned by the color gradient and that is shown by the axis in the color scale.
20242 It is equivalent to calling QCPColorMap::setDataRange on any of the connected color maps. It is
20260 Sets the scale type of the color scale, i.e. whether values are associated with colors linearly
20263 It is equivalent to calling QCPColorMap::setDataScaleType on any of the connected color maps. It is
20267 Note that this method controls the coordinate transformation. For logarithmic scales, you will
20268 likely also want to use a logarithmic tick spacing and labeling, which can be achieved by setting
20310 Sets the axis label of the color scale. This is equivalent to calling \ref QCPAxis::setLabel on
20325 Sets the width (or height, for horizontal color scales) the bar where the gradient is displayed
20361 Sets whether the user can zoom the data range (\ref setDataRange) by scrolling the mouse wheel.
20403 Changes the data range such that all color maps associated with this color scale are fully mapped
20450 if (!QCPRange::validRange(newRange)) // likely due to range being zero (plottable has only constant data in this dimension), shift current range to at least center the data
20485 setMaximumSize(QWIDGETSIZE_MAX, mBarWidth+mAxisRect.data()->margins().top()+mAxisRect.data()->margins().bottom());
20486 setMinimumSize(0, mBarWidth+mAxisRect.data()->margins().top()+mAxisRect.data()->margins().bottom());
20489 setMaximumSize(mBarWidth+mAxisRect.data()->margins().left()+mAxisRect.data()->margins().right(), QWIDGETSIZE_MAX);
20490 setMinimumSize(mBarWidth+mAxisRect.data()->margins().left()+mAxisRect.data()->margins().right(), 0);
20553////////////////////////////////////////////////////////////////////////////////////////////////////
20555////////////////////////////////////////////////////////////////////////////////////////////////////
20578 const QList<QCPAxis::AxisType> allAxisTypes = QList<QCPAxis::AxisType>() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight;
20584 connect(axis(type), SIGNAL(selectionChanged(QCPAxis::SelectableParts)), this, SLOT(axisSelectionChanged(QCPAxis::SelectableParts)));
20585 connect(axis(type), SIGNAL(selectableChanged(QCPAxis::SelectableParts)), this, SLOT(axisSelectableChanged(QCPAxis::SelectableParts)));
20588 connect(axis(QCPAxis::atLeft), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atRight), SLOT(setRange(QCPRange)));
20589 connect(axis(QCPAxis::atRight), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atLeft), SLOT(setRange(QCPRange)));
20590 connect(axis(QCPAxis::atBottom), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atTop), SLOT(setRange(QCPRange)));
20591 connect(axis(QCPAxis::atTop), SIGNAL(rangeChanged(QCPRange)), axis(QCPAxis::atBottom), SLOT(setRange(QCPRange)));
20592 connect(axis(QCPAxis::atLeft), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atRight), SLOT(setScaleType(QCPAxis::ScaleType)));
20593 connect(axis(QCPAxis::atRight), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atLeft), SLOT(setScaleType(QCPAxis::ScaleType)));
20594 connect(axis(QCPAxis::atBottom), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atTop), SLOT(setScaleType(QCPAxis::ScaleType)));
20595 connect(axis(QCPAxis::atTop), SIGNAL(scaleTypeChanged(QCPAxis::ScaleType)), axis(QCPAxis::atBottom), SLOT(setScaleType(QCPAxis::ScaleType)));
20598 // the axes must be set after axis rect, such that they appear above color gradient drawn by axis rect:
20606 Updates the color gradient image if necessary, by calling \ref updateGradientImage, then draws
20620 mirrorHorz = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atBottom || mParentColorScale->type() == QCPAxis::atTop);
20621 mirrorVert = mParentColorScale->mColorAxis.data()->rangeReversed() && (mParentColorScale->type() == QCPAxis::atLeft || mParentColorScale->type() == QCPAxis::atRight);
20644 if (mParentColorScale->mType == QCPAxis::atBottom || mParentColorScale->mType == QCPAxis::atTop)
20673 This slot is connected to the selectionChanged signals of the four axes in the constructor. It
20676void QCPColorScaleAxisRectPrivate::axisSelectionChanged(QCPAxis::SelectableParts selectedParts)
20679 const QList<QCPAxis::AxisType> allAxisTypes = QList<QCPAxis::AxisType>() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight;
20698 This slot is connected to the selectableChanged signals of the four axes in the constructor. It
20701void QCPColorScaleAxisRectPrivate::axisSelectableChanged(QCPAxis::SelectableParts selectableParts)
20704 const QList<QCPAxis::AxisType> allAxisTypes = QList<QCPAxis::AxisType>() << QCPAxis::atBottom << QCPAxis::atTop << QCPAxis::atLeft << QCPAxis::atRight;
20726////////////////////////////////////////////////////////////////////////////////////////////////////
20728////////////////////////////////////////////////////////////////////////////////////////////////////
20734 \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey)
20737 The container for storing multiple data points is \ref QCPGraphDataContainer. It is a typedef for
20750 For a general explanation of what this method is good for in the context of the data container,
20758 For a general explanation of what this method is good for in the context of the data container,
20764 Since the member \a key is both the data point key coordinate and the data ordering parameter,
20767 For a general explanation of what this method is good for in the context of the data container,
20775 For a general explanation of what this method is good for in the context of the data container,
20783 For a general explanation of what this method is good for in the context of the data container,
20791 For a general explanation of what this method is good for in the context of the data container,
20816////////////////////////////////////////////////////////////////////////////////////////////////////
20818////////////////////////////////////////////////////////////////////////////////////////////////////
20828 To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can
20829 also access and modify the data via the \ref data method, which returns a pointer to the internal
20832 Graphs are used to display single-valued data. Single-valued means that there should only be one
20833 data point per unique key coordinate. In other words, the graph can't have \a loops. If you do
20837 (<tt>qQNaN()</tt> or <tt>std::numeric_limits<double>::quiet_NaN()</tt>) in between the two data points that shall be
20842 The appearance of the graph is mainly determined by the line style, scatter style, brush and pen
20848 the key axis of the graph, and fills between two graphs, called channel fills. To enable a fill,
20862 Returns a shared pointer to the internal data storage of type \ref QCPGraphDataContainer. You may
20863 use it to directly manipulate the data, which may be more convenient and faster than using the
20871 axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have
20875 The created QCPGraph is automatically registered with the QCustomPlot instance inferred from \a
20876 keyAxis. This QCustomPlot instance takes ownership of the QCPGraph, so do not delete it manually
20879 To directly create a graph inside a plot, you can also use the simpler QCustomPlot::addGraph function.
20908 Modifying the data in the container will then affect all graphs that share the container. Sharing
20912 If you do not wish to share containers, but create a copy from an existing container, rather use
20929 If you can guarantee that the passed data points are sorted by \a keys in ascending order, you
20934void QCPGraph::setData(const QVector<double> &keys, const QVector<double> &values, bool alreadySorted)
20941 Sets how the single data points are connected in the plot. For scatter-only plots, set \a ls to
20952 Sets the visual appearance of single data points in the plot. If set to \ref QCPScatterStyle::ssNone, no scatter points
20966 This can be used to make the data appear sparser while for example still having a smooth line,
20979 Sets the target graph for filling the area between this graph and \a targetGraph with the current
21009 sampling technique can drastically improve the replot performance for graphs with a larger number
21012 By default, adaptive sampling is enabled. Even if enabled, QCustomPlot decides whether adaptive
21013 sampling shall actually be used on a per-graph basis. So leaving adaptive sampling enabled has no
21016 \image html adaptive-sampling-line.png "A line plot of 500,000 points without and with adaptive sampling"
21018 As can be seen, line plots experience no visual degradation from adaptive sampling. Outliers are
21022 \image html adaptive-sampling-scatter.png "A scatter plot of 100,000 points without and with adaptive sampling"
21024 Care must be taken when using high-density scatter plots in combination with adaptive sampling.
21025 The adaptive sampling algorithm treats scatter plots more carefully than line plots which still
21026 gives a significant reduction of replot times, but not quite as much as for line plots. This is
21027 because scatter plots inherently need more data points to be preserved in order to still resemble
21029 identical, as banding occurs for the outer data points. This is in fact intentional, such that
21035 enabled to false before issuing a command like \ref QCustomPlot::savePng, and setting \a enabled
21049 If you can guarantee that the passed data points are sorted by \a keys in ascending order, you
21052 Alternatively, you can also access and modify the data directly via the \ref data method, which
21055void QCPGraph::addData(const QVector<double> &keys, const QVector<double> &values, bool alreadySorted)
21058 qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size();
21078 Alternatively, you can also access and modify the data directly via the \ref data method, which
21089 If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data
21101 if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect))
21122QCPRange QCPGraph::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const
21130 if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
21134 QVector<QPointF> lines, scatters; // line and (if necessary) scatter pixel coordinates will be stored here while iterating over segments
21144 QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getLines takes care)
21202 painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush);
21209 painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens
21216 if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height()))
21219 scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
21232 This method retrieves an optimized set of data points via \ref getOptimizedLineData, and branches
21233 out to the line style specific functions such as \ref dataToLines, \ref dataToStepLeftLines, etc.
21236 \a lines will be filled with points in pixel coordinates, that can be drawn with the according
21237 draw functions like \ref drawLinePlot and \ref drawImpulsePlot. The points returned in \a lines
21242 \a dataRange specifies the beginning and ending data indices that will be taken into account for
21243 conversion. In this function, the specified range may exceed the total data bounds without harm:
21245 function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref
21265 if (mKeyAxis->rangeReversed() != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending in lineData (significantly simplifies following processing)
21281 This method retrieves an optimized set of data points via \ref getOptimizedScatterData and then
21282 converts them to pixel coordinates. The resulting points are returned in \a scatters, and can be
21285 \a dataRange specifies the beginning and ending data indices that will be taken into account for
21286 conversion. In this function, the specified range may exceed the total data bounds without harm:
21288 function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref
21296 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; scatters->clear(); return; }
21309 if (mKeyAxis->rangeReversed() != (mKeyAxis->orientation() == Qt::Vertical)) // make sure key pixels are sorted ascending in data (significantly simplifies following processing)
21344 \see dataToStepLeftLines, dataToStepRightLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot
21382 \see dataToLines, dataToStepRightLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot
21430 \see dataToLines, dataToStepLeftLines, dataToStepCenterLines, dataToImpulseLines, getLines, drawLinePlot
21478 \see dataToLines, dataToStepLeftLines, dataToStepRightLines, dataToImpulseLines, getLines, drawLinePlot
21538 \see dataToLines, dataToStepLeftLines, dataToStepRightLines, dataToStepCenterLines, getLines, drawImpulsePlot
21594 Depending on whether a normal fill or a channel fill (\ref setChannelFillGraph) is needed, \ref
21597 In order to handle NaN Data points correctly (the fill needs to be split into disjoint areas),
21598 this method first determines a list of non-NaN segments with \ref getNonNanSegments, on which to
21599 operate. In the channel fill case, \ref getOverlappingSegments is used to consolidate the non-NaN
21626 QVector<QCPDataRange> otherSegments = getNonNanSegments(&otherLines, mChannelFillGraph->keyAxis()->orientation());
21627 QVector<QPair<QCPDataRange, QCPDataRange> > segmentPairs = getOverlappingSegments(segments, lines, otherSegments, &otherLines);
21629 painter->drawPolygon(getChannelFillPolygon(lines, segmentPairs.at(i).first, &otherLines, segmentPairs.at(i).second));
21641void QCPGraph::drawScatterPlot(QCPPainter *painter, const QVector<QPointF> &scatters, const QCPScatterStyle &style) const
21667 pixel coordinates. The \a lines necessary for impulses are generated by \ref dataToImpulseLines
21688 Returns via \a lineData the data points that need to be visualized for this graph when plotting
21698void QCPGraph::getOptimizedLineData(QVector<QCPGraphData> *lineData, const QCPGraphDataContainer::const_iterator &begin, const QCPGraphDataContainer::const_iterator &end) const
21703 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
21710 double keyPixelSpan = qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key));
21715 if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average
21721 int reversedFactor = keyAxis->pixelOrientation(); // is used to calculate keyEpsilon pixel into the correct direction
21722 int reversedRound = reversedFactor==-1 ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey
21723 double currentIntervalStartKey = keyAxis->pixelToCoord(int(keyAxis->coordToPixel(begin->key)+reversedRound));
21725 double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates
21726 bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes)
21728 ++it; // advance iterator to second data point because adaptive sampling works in 1 point retrospect
21731 if (it->key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this cluster if necessary
21740 if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster
21742 if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point is further away, so first point of this cluster must be at a real data point
21743 lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint->value));
21746 if (it->key > currentIntervalStartKey+keyEpsilon*2) // new pixel started further away from previous cluster, so make sure the last point of the cluster is at a real data point
21749 lineData->append(QCPGraphData(currentIntervalFirstPoint->key, currentIntervalFirstPoint->value));
21754 currentIntervalStartKey = keyAxis->pixelToCoord(int(keyAxis->coordToPixel(it->key)+reversedRound));
21756 keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor));
21762 if (intervalDataCount >= 2) // last pixel had multiple data points, consolidate them to a cluster
21764 if (lastIntervalEndKey < currentIntervalStartKey-keyEpsilon) // last point wasn't a cluster, so first point of this cluster must be at a real data point
21765 lineData->append(QCPGraphData(currentIntervalStartKey+keyEpsilon*0.2, currentIntervalFirstPoint->value));
21769 lineData->append(QCPGraphData(currentIntervalFirstPoint->key, currentIntervalFirstPoint->value));
21781 plotting scatter points, taking into consideration the currently visible axis ranges and, if \ref
21790void QCPGraph::getOptimizedScatterData(QVector<QCPGraphData> *scatterData, QCPGraphDataContainer::const_iterator begin, QCPGraphDataContainer::const_iterator end) const
21795 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
21801 while (doScatterSkip && begin != end && beginIndex % scatterModulo != 0) // advance begin iterator to first non-skipped scatter
21811 int keyPixelSpan = int(qAbs(keyAxis->coordToPixel(begin->key)-keyAxis->coordToPixel((end-1)->key)));
21815 if (mAdaptiveSampling && dataCount >= maxCount) // use adaptive sampling only if there are at least two points per pixel on average
21826 int reversedFactor = keyAxis->pixelOrientation(); // is used to calculate keyEpsilon pixel into the correct direction
21827 int reversedRound = reversedFactor==-1 ? 1 : 0; // is used to switch between floor (normal) and ceil (reversed) rounding of currentIntervalStartKey
21828 double currentIntervalStartKey = keyAxis->pixelToCoord(int(keyAxis->coordToPixel(begin->key)+reversedRound));
21829 double keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor)); // interval of one pixel on screen when mapped to plot key coordinates
21830 bool keyEpsilonVariable = keyAxis->scaleType() == QCPAxis::stLogarithmic; // indicates whether keyEpsilon needs to be updated after every interval (for log axes)
21832 // advance iterator to second (non-skipped) data point because adaptive sampling works in 1 point retrospect:
21849 if (it->key < currentIntervalStartKey+keyEpsilon) // data point is still within same pixel, so skip it and expand value span of this pixel if necessary
21865 // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot):
21866 double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue));
21867 int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average
21872 if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt->value > valueMinRange && intervalIt->value < valueMaxRange)
21878 intervalIt += scatterModulo; // since we know indices of "currentIntervalStart", "intervalIt" and "it" are multiples of scatterModulo, we can't accidentally jump over "it" here
21880 } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange)
21885 currentIntervalStartKey = keyAxis->pixelToCoord(int(keyAxis->coordToPixel(it->key)+reversedRound));
21887 keyEpsilon = qAbs(currentIntervalStartKey-keyAxis->pixelToCoord(keyAxis->coordToPixel(currentIntervalStartKey)+1.0*reversedFactor));
21908 // determine value pixel span and add as many points in interval to maintain certain vertical data density (this is specific to scatter plot):
21909 double valuePixelSpan = qAbs(valueAxis->coordToPixel(minValue)-valueAxis->coordToPixel(maxValue));
21910 int dataModulo = qMax(1, qRound(intervalDataCount/(valuePixelSpan/4.0))); // approximately every 4 value pixels one data point on average
21916 if ((c % dataModulo == 0 || intervalIt == minValueIt || intervalIt == maxValueIt) && intervalIt->value > valueMinRange && intervalIt->value < valueMaxRange)
21921 else // here we can't guarantee that adding scatterModulo doesn't exceed "it" (because "it" is equal to "end" here, and "end" isn't scatterModulo-aligned), so check via index comparison:
21933 } else if (currentIntervalStart->value > valueMinRange && currentIntervalStart->value < valueMaxRange)
21963 This method outputs the currently visible data range via \a begin and \a end. The returned range
21971void QCPGraph::getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, QCPGraphDataContainer::const_iterator &end, const QCPDataRange &rangeRestriction) const
21981 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
21995 \a keyOrientation defines whether the \a x or \a y member of the passed QPointF is used to check
22001QVector<QCPDataRange> QCPGraph::getNonNanSegments(const QVector<QPointF> *lineData, Qt::Orientation keyOrientation) const
22043 This method takes two segment lists (e.g. created by \ref getNonNanSegments) \a thisSegments and
22049 This method is useful in the case of a channel fill between two graphs, when only those non-NaN
22050 segments which actually overlap in their key coordinate shall be considered for drawing a channel
22059QVector<QPair<QCPDataRange, QCPDataRange> > QCPGraph::getOverlappingSegments(QVector<QCPDataRange> thisSegments, const QVector<QPointF> *thisData, QVector<QCPDataRange> otherSegments, const QVector<QPointF> *otherData) const
22062 if (thisData->isEmpty() || otherData->isEmpty() || thisSegments.isEmpty() || otherSegments.isEmpty())
22070 if (thisSegments.at(thisIndex).size() < 2) // segments with fewer than two points won't have a fill anyhow
22075 if (otherSegments.at(otherIndex).size() < 2) // segments with fewer than two points won't have a fill anyhow
22097 result.append(QPair<QCPDataRange, QCPDataRange>(thisSegments.at(thisIndex), otherSegments.at(otherIndex)));
22099 if (bPrecedence <= 0) // otherSegment doesn't reach as far as thisSegment, so continue with next otherSegment, keeping current thisSegment
22113 The output parameter \a bPrecedence indicates whether the \a b segment reaches farther than the
22115 coordinates (i.e. bUpper > aUpper). If it returns -1, segment \a a reaches the farthest. Only if
22118 It is assumed that the lower bounds always have smaller or equal values than the upper bounds.
22122bool QCPGraph::segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, int &bPrecedence) const
22146 Returns the point which closes the fill polygon on the zero-value-line parallel to the key axis.
22147 The logarithmic axis scale case is a bit special, since the zero-value-line in pixel coordinates
22148 is in positive or negative infinity. So this case is handled separately by just closing the fill
22151 \a matchingDataPoint will provide the key (in pixels) of the returned point. Depending on whether
22152 the key axis of this graph is horizontal or vertical, \a matchingDataPoint will provide the x or
22159 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return {}; }
22180 (valueAxis->range().upper > 0 && valueAxis->rangeReversed())) // if range is negative, zero is on opposite side of key axis
22202 Pass the graph's data points (in pixel coordinates) as \a lineData, and specify the \a segment
22203 which shall be used for the fill. The collection of \a lineData points described by \a segment
22206 The returned fill polygon will be closed at the key axis (the zero-value line) for linear value
22207 axes. For logarithmic value axes the polygon will reach just beyond the corresponding axis rect
22214const QPolygonF QCPGraph::getFillPolygon(const QVector<QPointF> *lineData, QCPDataRange segment) const
22221 std::copy(lineData->constBegin()+segment.begin(), lineData->constBegin()+segment.end(), result.begin()+1);
22229 Returns the polygon needed for drawing (partial) channel fills between this graph and the graph
22232 The data points of this graph are passed as pixel coordinates via \a thisData, the data of the
22237 The passed \a thisSegment and \a otherSegment should correspond to the segment pairs returned by
22238 \ref getOverlappingSegments, to make sure only segments that actually have key coordinate overlap
22245const QPolygonF QCPGraph::getChannelFillPolygon(const QVector<QPointF> *thisData, QCPDataRange thisSegment, const QVector<QPointF> *otherData, QCPDataRange otherSegment) const
22252 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return QPolygonF(); }
22253 if (!mChannelFillGraph.data()->mKeyAxis) { qDebug() << Q_FUNC_INFO << "channel fill target key axis invalid"; return QPolygonF(); }
22256 return QPolygonF(); // don't have same axis orientation, can't fill that (Note: if keyAxis fits, valueAxis will fit too, because it's always orthogonal to keyAxis)
22261 std::copy(thisData->constBegin()+thisSegment.begin(), thisData->constBegin()+thisSegment.end(), thisSegmentData.begin());
22262 std::copy(otherData->constBegin()+otherSegment.begin(), otherData->constBegin()+otherSegment.end(), otherSegmentData.begin());
22267 // crop both vectors to ranges in which the keys overlap (which coord is key, depends on axisType):
22277 // set lowest point of cropped data to fit exactly key position of first static data point via linear interpolation:
22278 if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation
22281 slope = (croppedData->at(1).y()-croppedData->at(0).y())/(croppedData->at(1).x()-croppedData->at(0).x());
22284 (*croppedData)[0].setY(croppedData->at(0).y()+slope*(staticData->first().x()-croppedData->at(0).x()));
22293 // set highest point of cropped data to fit exactly key position of last static data point via linear interpolation:
22294 if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation
22297 slope = (croppedData->at(li).y()-croppedData->at(li-1).y())/(croppedData->at(li).x()-croppedData->at(li-1).x());
22300 (*croppedData)[li].setY(croppedData->at(li-1).y()+slope*(staticData->last().x()-croppedData->at(li-1).x()));
22311 // set lowest point of cropped data to fit exactly key position of first static data point via linear interpolation:
22312 if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation
22314 if (!qFuzzyCompare(croppedData->at(1).y(), croppedData->at(0).y())) // avoid division by zero in step plots
22315 slope = (croppedData->at(1).x()-croppedData->at(0).x())/(croppedData->at(1).y()-croppedData->at(0).y());
22318 (*croppedData)[0].setX(croppedData->at(0).x()+slope*(staticData->first().y()-croppedData->at(0).y()));
22327 // set highest point of cropped data to fit exactly key position of last static data point via linear interpolation:
22328 if (croppedData->size() < 2) return QPolygonF(); // need at least two points for interpolation
22330 if (!qFuzzyCompare(croppedData->at(li).y(), croppedData->at(li-1).y())) // avoid division by zero in step plots
22331 slope = (croppedData->at(li).x()-croppedData->at(li-1).x())/(croppedData->at(li).y()-croppedData->at(li-1).y());
22334 (*croppedData)[li].setX(croppedData->at(li-1).x()+slope*(staticData->last().y()-croppedData->at(li-1).y()));
22339 for (int i=otherSegmentData.size()-1; i>=0; --i) // insert reversed, otherwise the polygon will be twisted
22346 Finds the smallest index of \a data, whose points x value is just above \a x. Assumes x values in
22347 \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key
22369 Finds the highest index of \a data, whose points x value is just below \a x. Assumes x values in
22370 \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key
22392 Finds the smallest index of \a data, whose points y value is just above \a y. Assumes y values in
22393 \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key
22417 selectTest. The closest data point to \a pixelPoint is returned in \a closestData. Note that if
22418 the graph has a line representation, the returned distance may be smaller than the distance to
22421 If either the graph has no data or if the line style is \ref lsNone and the scatter style's shape
22422 is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the graph), returns -1.0.
22424double QCPGraph::pointDistance(const QPointF &pixelPoint, QCPGraphDataContainer::const_iterator &closestData) const
22434 // determine which key range comes into question, taking selection tolerance around pos into account:
22436 pixelsToCoords(pixelPoint-QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMin, dummy);
22437 pixelsToCoords(pixelPoint+QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), posKeyMax, dummy);
22445 const double currentDistSqr = QCPVector2D(coordsToPixels(it->key, it->value)-pixelPoint).lengthSquared();
22453 // calculate distance to graph line if there is one (if so, will probably be smaller than distance to closest data point):
22458 getLines(&lineData, QCPDataRange(0, dataCount())); // don't limit data range further since with sharp data spikes, line segments may be closer to test point than segments with closer key coordinate
22460 const int step = mLineStyle==lsImpulse ? 2 : 1; // impulse plot differs from other line styles in that the lineData points are only pairwise connected
22474 Finds the highest index of \a data, whose points y value is just below \a y. Assumes y values in
22475 \a data points are ordered ascending, as is ensured by \ref getLines/\ref getScatters if the key
22500////////////////////////////////////////////////////////////////////////////////////////////////////
22502////////////////////////////////////////////////////////////////////////////////////////////////////
22508 \li \a t: the free ordering parameter of this curve point, like in the mathematical vector <em>(x(t), y(t))</em>. (This is the \a sortKey)
22512 The container for storing multiple data points is \ref QCPCurveDataContainer. It is a typedef for
22525 For a general explanation of what this method is good for in the context of the data container,
22531 Returns a data point with the specified \a sortKey (assigned to the data point's \a t member).
22534 For a general explanation of what this method is good for in the context of the data container,
22540 Since the member \a key is the data point key coordinate and the member \a t is the data ordering
22543 For a general explanation of what this method is good for in the context of the data container,
22551 For a general explanation of what this method is good for in the context of the data container,
22559 For a general explanation of what this method is good for in the context of the data container,
22567 For a general explanation of what this method is good for in the context of the data container,
22594////////////////////////////////////////////////////////////////////////////////////////////////////
22596////////////////////////////////////////////////////////////////////////////////////////////////////
22603 Unlike QCPGraph, plottables of this type may have multiple points with the same key coordinate,
22605 coordinate \a t, which defines the order of the points described by the other two coordinates \a
22608 To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can
22609 also access and modify the curve's data via the \ref data method, which returns a pointer to the
22613 (<tt>qQNaN()</tt> or <tt>std::numeric_limits<double>::quiet_NaN()</tt>) in between the two data points that shall be
22618 The appearance of the curve is determined by the pen and the brush (\ref setPen, \ref setBrush).
22628 which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes
22629 ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead.
22638 Returns a shared pointer to the internal data storage of type \ref QCPCurveDataContainer. You may
22639 use it to directly manipulate the data, which may be more convenient and faster than using the
22647 axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have
22651 The created QCPCurve is automatically registered with the QCustomPlot instance inferred from \a
22652 keyAxis. This QCustomPlot instance takes ownership of the QCPCurve, so do not delete it manually
22678 Modifying the data in the container will then affect all curves that share the container. Sharing
22682 If you do not wish to share containers, but create a copy from an existing container, rather use
22695 Replaces the current data with the provided points in \a t, \a keys and \a values. The provided
22699 If you can guarantee that the passed data points are sorted by \a t in ascending order, you can
22704void QCPCurve::setData(const QVector<double> &t, const QVector<double> &keys, const QVector<double> &values, bool alreadySorted)
22713 Replaces the current data with the provided points in \a keys and \a values. The provided vectors
22717 The t parameter of each data point will be set to the integer index of the respective key/value
22730 QCPScatterStyle::ssNone, no scatter points are drawn (e.g. for line-only plots with appropriate
22744 This can be used to make the data appear sparser while for example still having a smooth line,
22757 Sets how the single data points are connected in the plot or how they are represented visually
22770 Adds the provided points in \a t, \a keys and \a values to the current data. The provided vectors
22774 If you can guarantee that the passed data points are sorted by \a keys in ascending order, you
22777 Alternatively, you can also access and modify the data directly via the \ref data method, which
22780void QCPCurve::addData(const QVector<double> &t, const QVector<double> &keys, const QVector<double> &values, bool alreadySorted)
22783 qDebug() << Q_FUNC_INFO << "ts, keys and values have different sizes:" << t.size() << keys.size() << values.size();
22806 The t parameter of each data point will be set to the integer index of the respective key/value
22809 Alternatively, you can also access and modify the data directly via the \ref data method, which
22815 qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size();
22840 Alternatively, you can also access and modify the data directly via the \ref data method, which
22855 Alternatively, you can also access and modify the data directly via the \ref data method, which
22869 If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data
22881 if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect))
22902QCPRange QCPCurve::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const
22924 QPen finalCurvePen = mPen; // determine the final pen already here, because the line optimization depends on its stroke width
22928 QCPDataRange lineDataRange = isSelectedSegment ? allSegments.at(i) : allSegments.at(i).adjusted(-1, 1); // unselected segments extend lines to bordering selected data point (safe to exceed total data bounds in first/last segment, getCurveLines takes care)
22933 for (QCPCurveDataContainer::const_iterator it = mDataContainer->constBegin(); it != mDataContainer->constEnd(); ++it)
22982 painter->fillRect(QRectF(rect.left(), rect.top()+rect.height()/2.0, rect.width(), rect.height()/3.0), mBrush);
22989 painter->drawLine(QLineF(rect.left(), rect.top()+rect.height()/2.0, rect.right()+5, rect.top()+rect.height()/2.0)); // +5 on x2 else last segment is missing from dashed/dotted pens
22996 if (mScatterStyle.shape() == QCPScatterStyle::ssPixmap && (mScatterStyle.pixmap().size().width() > rect.width() || mScatterStyle.pixmap().size().height() > rect.height()))
22999 scaledStyle.setPixmap(scaledStyle.pixmap().scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
23032void QCPCurve::drawScatterPlot(QCPPainter *painter, const QVector<QPointF> &points, const QCPScatterStyle &style) const
23047 Line segments that aren't visible in the current axis rect are handled in an optimized way. They
23049 regarding point count. The algorithm makes sure to preserve appearance of lines and fills inside
23055 \a dataRange specifies the beginning and ending data indices that will be taken into account for
23056 conversion. In this function, the specified range may exceed the total data bounds without harm:
23058 function to check for valid indices in \a dataRange, e.g. when extending ranges coming from \ref
23061 \a penWidth specifies the pen width that will be used to later draw the lines generated by this
23062 function. This is needed here to calculate an accordingly wider margin around the axis rect when
23065 Methods that are also involved in the algorithm are: \ref getRegion, \ref getOptimizedPoint, \ref
23070void QCPCurve::getCurveLines(QVector<QPointF> *lines, const QCPDataRange &dataRange, double penWidth) const
23076 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
23079 const double strokeMargin = qMax(qreal(1.0), qreal(penWidth*0.75)); // stroke radius + 50% safety
23080 const double keyMin = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().lower)-strokeMargin*keyAxis->pixelOrientation());
23081 const double keyMax = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyAxis->range().upper)+strokeMargin*keyAxis->pixelOrientation());
23082 const double valueMin = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueAxis->range().lower)-strokeMargin*valueAxis->pixelOrientation());
23083 const double valueMax = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueAxis->range().upper)+strokeMargin*valueAxis->pixelOrientation());
23092 QVector<QPointF> trailingPoints; // points that must be applied after all other points (are generated only when handling first point to get virtual segment between last and first point right)
23096 if (currentRegion != prevRegion) // changed region, possibly need to add some optimized edge points or original points if entering R
23103 lines->append(getOptimizedPoint(currentRegion, it->key, it->value, prevIt->key, prevIt->value, keyMin, valueMax, keyMax, valueMin));
23104 // in the situations 5->1/7/9/3 the segment may leave R and directly cross through two outer regions. In these cases we need to add an additional corner point
23105 *lines << getOptimizedCornerPoints(prevRegion, currentRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin);
23107 getTraverse(prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin, crossA, crossB))
23109 // add the two cross points optimized if segment crosses R and if segment isn't virtual zeroth segment between last and first curve point:
23111 getTraverseCornerPoints(prevRegion, currentRegion, keyMin, valueMax, keyMax, valueMin, beforeTraverseCornerPoints, afterTraverseCornerPoints);
23124 } else // doesn't cross R, line is just moving around in outside regions, so only need to add optimized point(s) at the boundary corner(s)
23126 *lines << getOptimizedCornerPoints(prevRegion, currentRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin);
23128 } else // segment does end in R, so we add previous point optimized and this point at original position
23130 if (it == itBegin) // it is first point in curve and prevIt is last one. So save optimized point for adding it to the lineData in the end
23131 trailingPoints << getOptimizedPoint(prevRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin);
23133 lines->append(getOptimizedPoint(prevRegion, prevIt->key, prevIt->value, it->key, it->value, keyMin, valueMax, keyMax, valueMin));
23155 Called by \ref draw to generate points in pixel coordinates which represent the scatters of the
23156 curve. If a scatter skip is configured (\ref setScatterSkip), the returned points are accordingly
23164 \a dataRange specifies the beginning and ending data indices that will be taken into account for
23167 \a scatterWidth specifies the scatter width that will be used to later draw the scatters at pixel
23173void QCPCurve::getScatters(QVector<QPointF> *scatters, const QCPDataRange &dataRange, double scatterWidth) const
23179 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
23193 keyRange.lower = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyRange.lower)-scatterWidth*keyAxis->pixelOrientation());
23194 keyRange.upper = keyAxis->pixelToCoord(keyAxis->coordToPixel(keyRange.upper)+scatterWidth*keyAxis->pixelOrientation());
23195 valueRange.lower = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueRange.lower)-scatterWidth*valueAxis->pixelOrientation());
23196 valueRange.upper = valueAxis->pixelToCoord(valueAxis->coordToPixel(valueRange.upper)+scatterWidth*valueAxis->pixelOrientation());
23200 while (doScatterSkip && it != end && itIndex % scatterModulo != 0) // advance begin iterator to first non-skipped scatter
23210 scatters->append(QPointF(valueAxis->coordToPixel(it->value), keyAxis->coordToPixel(it->key)));
23256 It returns the region of the given point (\a key, \a value) with respect to a rectangle defined
23259 The regions are enumerated from top to bottom (\a valueMin to \a valueMax) and left to right (\a
23268 With the rectangle being region 5, and the outer regions extending infinitely outwards. In the
23271int QCPCurve::getRegion(double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const
23304 This method is used in case the current segment passes from inside the visible rect (region 5,
23305 see \ref getRegion) to any of the outer regions (\a otherRegion). The current segment is given by
23310 For this function it doesn't matter whether (\a key, \a value) is the point inside region 5 or
23311 whether it's (\a otherKey, \a otherValue), i.e. whether the segment is coming from region 5 or
23312 leaving it. It is important though that \a otherRegion correctly identifies the other region not
23315QPointF QCPCurve::getOptimizedPoint(int otherRegion, double otherKey, double otherValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const
23317 // The intersection point interpolation here is done in pixel coordinates, so we don't need to
23337 intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx);
23338 if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not intersected, then it must be left edge (qMin/qMax necessary since axes may be reversed)
23341 intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx);
23348 intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx);
23354 intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx);
23355 if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not intersected, then it must be left edge (qMin/qMax necessary since axes may be reversed)
23358 intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx);
23365 intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx);
23370 break; // case 5 shouldn't happen for this function but we add it anyway to prevent potential discontinuity in branch table
23375 intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx);
23381 intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx);
23382 if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether top edge is not intersected, then it must be right edge (qMin/qMax necessary since axes may be reversed)
23385 intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx);
23392 intersectValuePx = otherValuePx + (valuePx-otherValuePx)/(keyPx-otherKeyPx)*(intersectKeyPx-otherKeyPx);
23398 intersectKeyPx = otherKeyPx + (keyPx-otherKeyPx)/(valuePx-otherValuePx)*(intersectValuePx-otherValuePx);
23399 if (intersectKeyPx < qMin(keyMinPx, keyMaxPx) || intersectKeyPx > qMax(keyMinPx, keyMaxPx)) // check whether bottom edge is not intersected, then it must be right edge (qMin/qMax necessary since axes may be reversed)
23417 In situations where a single segment skips over multiple regions it might become necessary to add
23419 doesn't unintentionally cut through the visible area of the axis rect and create plot artifacts.
23421 start, end, or traverse region 5. (Corner points where region 5 is traversed are calculated by
23424 For example, consider a segment which directly goes from region 4 to 2 but originally is far out
23426 projecting them on the top and left borders of region 5 will create a segment that surely crosses
23427 5, creating a visual artifact in the plot. This method prevents this by providing extra points at
23428 the top left corner, making the optimized curve correctly pass from region 4 to 1 to 2 without
23431QVector<QPointF> QCPCurve::getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin) const
23442 case 3: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); break; }
23443 case 7: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); break; }
23444 case 6: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; }
23445 case 8: { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; }
23446 case 9: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points
23448 { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); }
23450 { result << coordsToPixels(keyMin, valueMax) << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); }
23464 case 7: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); break; }
23465 case 9: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); break; }
23475 case 1: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); break; }
23476 case 9: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); break; }
23477 case 4: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; }
23478 case 8: { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; }
23479 case 7: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points
23481 { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); }
23483 { result << coordsToPixels(keyMin, valueMin) << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); }
23497 case 3: { result << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); break; }
23498 case 9: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMax, valueMin); break; }
23521 case 1: { result << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); break; }
23522 case 7: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMax, valueMax); break; }
23532 case 1: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); break; }
23533 case 9: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); break; }
23534 case 2: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); result.append(result.last()); break; }
23535 case 6: { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); result.append(result.last()); break; }
23536 case 3: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points
23538 { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); }
23540 { result << coordsToPixels(keyMax, valueMax) << coordsToPixels(keyMin, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); }
23554 case 1: { result << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); break; }
23555 case 3: { result << coordsToPixels(keyMax, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMin); break; }
23565 case 3: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); break; }
23566 case 7: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); break; }
23567 case 2: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); result.append(result.last()); break; }
23568 case 4: { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); result.append(result.last()); break; }
23569 case 1: { // in this case we need another distinction of cases: segment may pass below or above rect, requiring either bottom right or top left corner points
23571 { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMin, valueMin); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); }
23573 { result << coordsToPixels(keyMax, valueMin) << coordsToPixels(keyMax, valueMax); result.append(result.last()); result << coordsToPixels(keyMin, valueMax); }
23588 getRegion) may traverse the visible region 5. This function assumes that neither \a prevRegion
23591 If this method returns false, the segment for sure doesn't pass region 5. If it returns true, the
23689 This method assumes that the \ref mayTraverse test has returned true, so there is a chance the
23693 The return value of this method indicates whether the segment actually traverses region 5 or not.
23695 If the segment traverses 5, the output parameters \a crossA and \a crossB indicate the entry and
23698bool QCPCurve::getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, double valueMax, double keyMax, double valueMin, QPointF &crossA, QPointF &crossB) const
23700 // The intersection point interpolation here is done in pixel coordinates, so we don't need to
23716 // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5 is traversed here
23717 intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyPx, valueMinPx) : QPointF(valueMinPx, keyPx)); // direction will be taken care of at end of method
23718 intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyPx, valueMaxPx) : QPointF(valueMaxPx, keyPx));
23721 // due to region filter in mayTraverse(), if line is parallel to value or key axis, region 5 is traversed here
23722 intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMinPx, valuePx) : QPointF(valuePx, keyMinPx)); // direction will be taken care of at end of method
23723 intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMaxPx, valuePx) : QPointF(valuePx, keyMaxPx));
23730 if (gamma >= qMin(keyMinPx, keyMaxPx) && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed
23731 intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(gamma, valueMaxPx) : QPointF(valueMaxPx, gamma));
23734 if (gamma >= qMin(keyMinPx, keyMaxPx) && gamma <= qMax(keyMinPx, keyMaxPx)) // qMin/qMax necessary since axes may be reversed
23735 intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(gamma, valueMinPx) : QPointF(valueMinPx, gamma));
23739 if (gamma >= qMin(valueMinPx, valueMaxPx) && gamma <= qMax(valueMinPx, valueMaxPx)) // qMin/qMax necessary since axes may be reversed
23740 intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMinPx, gamma) : QPointF(gamma, keyMinPx));
23743 if (gamma >= qMin(valueMinPx, valueMaxPx) && gamma <= qMax(valueMinPx, valueMaxPx)) // qMin/qMax necessary since axes may be reversed
23744 intersections.append(mKeyAxis->orientation() == Qt::Horizontal ? QPointF(keyMaxPx, gamma) : QPointF(gamma, keyMaxPx));
23750 // line probably goes through corner of rect, and we got duplicate points there. single out the point pair with greatest distance in between:
23770 // one or even zero points found (shouldn't happen unless line perfectly tangent to corner), no need to draw segment
23790 This method assumes that the \ref getTraverse test has returned true, so the segment definitely
23793 In certain situations it is not sufficient to merely generate the entry and exit points of the
23794 segment into/out of region 5, as \ref getTraverse provides. It may happen that a single segment, in
23801 corner of region 5. In this configuration, the segment additionally crosses the border between
23802 region 1 and 2 before entering region 5. This makes it necessary to add an additional point in
23804 parameter \a beforeTraverse will contain the top left corner point, and \a afterTraverse will be
23807 In some cases, such as when going from region 1 to 9, it may even be necessary to add additional
23811void QCPCurve::getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, double keyMax, double valueMin, QVector<QPointF> &beforeTraverse, QVector<QPointF> &afterTraverse) const
23820 case 9: { beforeTraverse << coordsToPixels(keyMin, valueMax); afterTraverse << coordsToPixels(keyMax, valueMin); break; }
23839 case 7: { beforeTraverse << coordsToPixels(keyMin, valueMin); afterTraverse << coordsToPixels(keyMax, valueMax); break; }
23868 case 3: { beforeTraverse << coordsToPixels(keyMax, valueMax); afterTraverse << coordsToPixels(keyMin, valueMin); break; }
23887 case 1: { beforeTraverse << coordsToPixels(keyMax, valueMin); afterTraverse << coordsToPixels(keyMin, valueMax); break; }
23897 Calculates the (minimum) distance (in pixels) the curve's representation has from the given \a
23899 \ref selectTest. The closest data point to \a pixelPoint is returned in \a closestData. Note that
23900 if the curve has a line representation, the returned distance may be smaller than the distance to
23903 If either the curve has no data or if the line style is \ref lsNone and the scatter style's shape
23904 is \ref QCPScatterStyle::ssNone (i.e. there is no visual representation of the curve), returns
23907double QCPCurve::pointDistance(const QPointF &pixelPoint, QCPCurveDataContainer::const_iterator &closestData) const
23917 QPointF dataPoint = coordsToPixels(mDataContainer->constBegin()->key, mDataContainer->constBegin()->value);
23929 const double currentDistSqr = QCPVector2D(coordsToPixels(it->key, it->value)-pixelPoint).lengthSquared();
23937 // calculate distance to line if there is one (if so, will probably be smaller than distance to closest data point):
23941 getCurveLines(&lines, QCPDataRange(0, dataCount()), mParentPlot->selectionTolerance()*1.2); // optimized lines outside axis rect shouldn't respond to clicks at the edge, so use 1.2*tolerance as pen width
23944 double currentDistSqr = QCPVector2D(pixelPoint).distanceSquaredToLine(lines.at(i), lines.at(i+1));
23959////////////////////////////////////////////////////////////////////////////////////////////////////
23961////////////////////////////////////////////////////////////////////////////////////////////////////
23968 When showing multiple QCPBars in one plot which have bars at identical keys, it may be desirable
23969 to have them appearing next to each other at each key. This is what adding the respective QCPBars
23970 plottables to a QCPBarsGroup achieves. (An alternative approach is to stack them on top of each
23981 The spacing between the bars can be configured via \ref setSpacingType and \ref setSpacing. The
23982 bars in this group appear in the plot in the order they were appended. To insert a bars plottable
23983 at a certain index position, or to reposition a bars plottable which is already in the group, use
24056 Sets the spacing between adjacent bars. What the number passed as \a spacing actually means, is
24113 qDebug() << Q_FUNC_INFO << "bars plottable is already in this bars group:" << reinterpret_cast<quintptr>(bars);
24120 \a bars may already be part of this group. In that case, \a bars is just moved to the new index
24156 qDebug() << Q_FUNC_INFO << "bars plottable is not in this bars group:" << reinterpret_cast<quintptr>(bars);
24161 Adds the specified \a bars to the internal mBars list of bars. This method does not change the
24174 Removes the specified \a bars from the internal mBars list of bars. This method does not change
24186 Returns the pixel offset in the key dimension the specified \a bars plottable should have at the
24206 // determine key pixel offset of this base bars considering all other base bars in this barsgroup:
24211 if (baseBars.size() % 2 == 1 && index == (baseBars.size()-1)/2) // is center bar (int division on purpose)
24218 int dir = (index <= (baseBars.size()-1)/2) ? -1 : 1; // if bar is to lower keys of center, dir is negative
24226 baseBars.at((baseBars.size()-1)/2)->getPixelWidth(keyCoord, lowerPixelWidth, upperPixelWidth);
24228 result += getPixelSpacing(baseBars.at((baseBars.size()-1)/2), keyCoord); // center bar spacing
24248 Returns the spacing in pixels which is between this \a bars and the following one, both at the
24281////////////////////////////////////////////////////////////////////////////////////////////////////
24283////////////////////////////////////////////////////////////////////////////////////////////////////
24289 \li \a key: coordinate on the key axis of this bar (this is the \a mainKey and the \a sortKey)
24292 The container for storing multiple data points is \ref QCPBarsDataContainer. It is a typedef for
24305 For a general explanation of what this method is good for in the context of the data container,
24313 For a general explanation of what this method is good for in the context of the data container,
24319 Since the member \a key is both the data point key coordinate and the data ordering parameter,
24322 For a general explanation of what this method is good for in the context of the data container,
24330 For a general explanation of what this method is good for in the context of the data container,
24338 For a general explanation of what this method is good for in the context of the data container,
24346 For a general explanation of what this method is good for in the context of the data container,
24371////////////////////////////////////////////////////////////////////////////////////////////////////
24373////////////////////////////////////////////////////////////////////////////////////////////////////
24384 The appearance of the bars is determined by the pen and the brush (\ref setPen, \ref setBrush).
24387 Bar charts are stackable. This means, two QCPBars plottables can be placed on top of each other
24388 (see \ref QCPBars::moveAbove). So when two bars are at the same key position, they will appear
24391 If you would like to group multiple QCPBars plottables together so they appear side by side as
24404 which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes
24405 ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead.
24414 Returns a shared pointer to the internal data storage of type \ref QCPBarsDataContainer. You may
24415 use it to directly manipulate the data, which may be more convenient and faster than using the
24436 Constructs a bar chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value
24437 axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have
24441 The created QCPBars is automatically registered with the QCustomPlot instance inferred from \a
24442 keyAxis. This QCustomPlot instance takes ownership of the QCPBars, so do not delete it manually
24473 Modifying the data in the container will then affect all bars that share the container. Sharing
24477 If you do not wish to share containers, but create a copy from an existing container, rather use
24494 If you can guarantee that the passed data points are sorted by \a keys in ascending order, you
24499void QCPBars::setData(const QVector<double> &keys, const QVector<double> &values, bool alreadySorted)
24530 Sets to which QCPBarsGroup this QCPBars instance belongs to. Alternatively, you can also use \ref
24549 The base value defines where on the value coordinate the bars start. How far the bars extend from
24550 the base value is given by their individual value data. For example, if the base value is set to
24551 1, a bar with data value 2 will have its lowest point at value coordinate 1 and highest point at
24564 If this bars plottable is stacked on top of another bars plottable (\ref moveAbove), this method
24565 allows specifying a distance in \a pixels, by which the drawn bar rectangles will be separated by
24579 If you can guarantee that the passed data points are sorted by \a keys in ascending order, you
24582 Alternatively, you can also access and modify the data directly via the \ref data method, which
24585void QCPBars::addData(const QVector<double> &keys, const QVector<double> &values, bool alreadySorted)
24588 qDebug() << Q_FUNC_INFO << "keys and values have different sizes:" << keys.size() << values.size();
24607 Alternatively, you can also access and modify the data directly via the \ref data method, which
24616 Moves this bars plottable below \a bars. In other words, the bars of this plottable will appear
24617 below the bars of \a bars. The move target \a bars must use the same key and value axis as this
24620 Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already
24621 has a bars object below itself, this bars object is inserted between the two. If this bars object
24622 is already between two other bars, the two other bars will be stacked on top of each other after
24634 qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars";
24638 connectBars(mBarBelow.data(), mBarAbove.data()); // Note: also works if one (or both) of them is 0
24649 Moves this bars plottable above \a bars. In other words, the bars of this plottable will appear
24650 above the bars of \a bars. The move target \a bars must use the same key and value axis as this
24653 Inserting into and removing from existing bar stacking is handled gracefully. If \a bars already
24654 has a bars object above itself, this bars object is inserted between the two. If this bars object
24655 is already between two other bars, the two other bars will be stacked on top of each other after
24667 qDebug() << Q_FUNC_INFO << "passed QCPBars* doesn't have same key and value axis as this QCPBars";
24671 connectBars(mBarBelow.data(), mBarAbove.data()); // Note: also works if one (or both) of them is 0
24698 result.addDataRange(QCPDataRange(int(it-mDataContainer->constBegin()), int(it-mDataContainer->constBegin()+1)), false);
24707 If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data
24720 if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect))
24744 /* Note: If this QCPBars uses absolute pixels as width (or is in a QCPBarsGroup with spacing in
24781QCPRange QCPBars::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const
24788 bool haveLower = true; // set to true, because baseValue should always be visible in bar charts
24789 bool haveUpper = true; // set to true, because baseValue should always be visible in bar charts
24801 if (inSignDomain == QCP::sdBoth || (inSignDomain == QCP::sdNegative && current < 0) || (inSignDomain == QCP::sdPositive && current > 0))
24827 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return {}; }
24830 const double valuePixel = valueAxis->coordToPixel(getStackedBaseValue(it->key, it->value >= 0) + it->value);
24846 if (!mKeyAxis || !mValueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
24906 called by \ref draw to determine which data (key) range is visible at the current key axis range
24909 \a begin returns an iterator to the lowest data point that needs to be taken into account when
24913 \a end returns an iterator one higher than the highest visible data point. Same as before, \a end
24918void QCPBars::getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, QCPBarsDataContainer::const_iterator &end) const
24940 // walk left from begin to find lower bar that actually is completely outside visible pixel range:
24947 isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.right() >= lowerPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.left() <= lowerPixelBound));
24949 isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.top() <= lowerPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.bottom() >= lowerPixelBound));
24955 // walk right from ubound to find upper bar that actually is completely outside visible pixel range:
24961 isVisible = ((!mKeyAxis.data()->rangeReversed() && barRect.left() <= upperPixelBound) || (mKeyAxis.data()->rangeReversed() && barRect.right() >= upperPixelBound));
24974 Returns the rect in pixel coordinates of a single bar with the specified \a key and \a value. The
24982 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return {}; }
24992 double bottomOffset = (mBarBelow && mPen != Qt::NoPen ? 1 : 0)*(mPen.isCosmetic() ? 1 : mPen.widthF());
24999 return QRectF(QPointF(keyPixel+lowerPixelWidth, valuePixel), QPointF(keyPixel+upperPixelWidth, basePixel+bottomOffset)).normalized();
25002 return QRectF(QPointF(basePixel+bottomOffset, keyPixel+lowerPixelWidth), QPointF(valuePixel, keyPixel+upperPixelWidth)).normalized();
25008 This function is used to determine the width of the bar at coordinate \a key, according to the
25011 The output parameters \a lower and \a upper return the number of pixels the bar extends to lower
25012 and higher keys, relative to the \a key coordinate (so with a non-reversed horizontal axis, \a
25058 This function is called to find at which value to start drawing the base of a bar at \a key, when
25061 positive and negative bars are separated per stack (positive are stacked above baseValue upwards,
25062 negative are stacked below baseValue downwards). This can be indicated with \a positive. So if the
25069 double max = 0; // don't initialize with mBaseValue here because only base value of bottom-most bar has meaning in a bar stack
25071 double epsilon = qAbs(key)*(sizeof(key)==4 ? 1e-6 : 1e-14); // should be safe even when changed to use float at some point
25074 QCPBarsDataContainer::const_iterator it = mBarBelow.data()->mDataContainer->findBegin(key-epsilon);
25094 Connects \a below and \a above to each other via their mBarAbove/mBarBelow properties. The bar(s)
25134////////////////////////////////////////////////////////////////////////////////////////////////////
25136////////////////////////////////////////////////////////////////////////////////////////////////////
25143 \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey)
25153 sample data in half (50% of the sample data is below/above the median). (This is the \a mainValue)
25162 \li \a outliers: a QVector of outlier values that will be drawn as scatter points at the \a key
25165 The container for storing multiple data points is \ref QCPStatisticalBoxDataContainer. It is a
25179 For a general explanation of what this method is good for in the context of the data container,
25187 For a general explanation of what this method is good for in the context of the data container,
25193 Since the member \a key is both the data point key coordinate and the data ordering parameter,
25196 For a general explanation of what this method is good for in the context of the data container,
25204 For a general explanation of what this method is good for in the context of the data container,
25212 For a general explanation of what this method is good for in the context of the data container,
25218 Returns a QCPRange spanning from the \a minimum to the \a maximum member of this statistical box
25221 For a general explanation of what this method is good for in the context of the data container,
25241 Constructs a data point with the specified \a key, \a minimum, \a lowerQuartile, \a median, \a
25244QCPStatisticalBoxData::QCPStatisticalBoxData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector<double> &outliers) :
25256////////////////////////////////////////////////////////////////////////////////////////////////////
25258////////////////////////////////////////////////////////////////////////////////////////////////////
25265 To plot data, assign it with the \ref setData or \ref addData functions. Alternatively, you can
25266 also access and modify the data via the \ref data method, which returns a pointer to the internal
25269 Additionally each data point can itself have a list of outliers, drawn as scatter points at the
25270 key coordinate of the respective statistical box data point. They can either be set by using the
25282 which reach from the upper quartile to the maximum, and from the lower quartile to the minimum.
25283 The appearance of the whiskers can be modified with: \ref setWhiskerPen, \ref setWhiskerBarPen,
25284 \ref setWhiskerWidth. The whisker width is the width of the bar perpendicular to the whisker at
25285 the top (for maximum) and bottom (for minimum). If the whisker pen is changed, make sure to set
25286 the \c capStyle to \c Qt::FlatCap. Otherwise the backbone line might exceed the whisker bars by a
25302 which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes
25303 ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead.
25313 QCPStatisticalBoxDataContainer. You may use it to directly manipulate the data, which may be more
25320 Constructs a statistical box which uses \a keyAxis as its key axis ("x") and \a valueAxis as its
25321 value axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and
25325 The created QCPStatisticalBox is automatically registered with the QCustomPlot instance inferred
25326 from \a keyAxis. This QCustomPlot instance takes ownership of the QCPStatisticalBox, so do not
25347 Since a QSharedPointer is used, multiple QCPStatisticalBoxes may share the same data container
25348 safely. Modifying the data in the container will then affect all statistical boxes that share the
25353 If you do not wish to share containers, but create a copy from an existing container, rather use
25354 the \ref QCPDataContainer<DataType>::set method on the statistical box data container directly:
25365 Replaces the current data with the provided points in \a keys, \a minimum, \a lowerQuartile, \a
25366 median, \a upperQuartile and \a maximum. The provided vectors should have equal length. Else, the
25369 If you can guarantee that the passed data points are sorted by \a keys in ascending order, you
25374void QCPStatisticalBox::setData(const QVector<double> &keys, const QVector<double> &minimum, const QVector<double> &lowerQuartile, const QVector<double> &median, const QVector<double> &upperQuartile, const QVector<double> &maximum, bool alreadySorted)
25409 Make sure to set the \c capStyle of the passed \a pen to \c Qt::FlatCap. Otherwise the backbone
25410 line might exceed the whisker bars by a few pixels due to the pen cap being not perfectly flat.
25420 Sets the pen used for drawing the whisker bars. Those are the lines parallel to the key axis at
25456 \ref addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector<double> &outliers)
25465 Adds the provided points in \a keys, \a minimum, \a lowerQuartile, \a median, \a upperQuartile and
25466 \a maximum to the current data. The provided vectors should have equal length. Else, the number
25469 If you can guarantee that the passed data points are sorted by \a keys in ascending order, you
25472 Alternatively, you can also access and modify the data directly via the \ref data method, which
25475void QCPStatisticalBox::addData(const QVector<double> &keys, const QVector<double> &minimum, const QVector<double> &lowerQuartile, const QVector<double> &median, const QVector<double> &upperQuartile, const QVector<double> &maximum, bool alreadySorted)
25477 if (keys.size() != minimum.size() || minimum.size() != lowerQuartile.size() || lowerQuartile.size() != median.size() ||
25478 median.size() != upperQuartile.size() || upperQuartile.size() != maximum.size() || maximum.size() != keys.size())
25479 qDebug() << Q_FUNC_INFO << "keys, minimum, lowerQuartile, median, upperQuartile, maximum have different sizes:"
25480 << keys.size() << minimum.size() << lowerQuartile.size() << median.size() << upperQuartile.size() << maximum.size();
25481 const int n = qMin(keys.size(), qMin(minimum.size(), qMin(lowerQuartile.size(), qMin(median.size(), qMin(upperQuartile.size(), maximum.size())))));
25502 Adds the provided data point as \a key, \a minimum, \a lowerQuartile, \a median, \a upperQuartile
25505 Alternatively, you can also access and modify the data directly via the \ref data method, which
25508void QCPStatisticalBox::addData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum, const QVector<double> &outliers)
25510 mDataContainer->add(QCPStatisticalBoxData(key, minimum, lowerQuartile, median, upperQuartile, maximum, outliers));
25516QCPDataSelection QCPStatisticalBox::selectTestRect(const QRectF &rect, bool onlySelectable) const
25530 result.addDataRange(QCPDataRange(int(it-mDataContainer->constBegin()), int(it-mDataContainer->constBegin()+1)), false);
25539 If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data
25544double QCPStatisticalBox::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const
25552 if (mKeyAxis->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect))
25610QCPRange QCPStatisticalBox::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const
25621 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
25646 qDebug() << Q_FUNC_INFO << "Data point at" << it->key << "of drawn range has invalid data." << "Plottable name:" << name();
25693void QCPStatisticalBox::drawStatisticalBox(QCPPainter *painter, QCPStatisticalBoxDataContainer::const_iterator it, const QCPScatterStyle &outlierStyle) const
25703 painter->drawLine(QLineF(coordsToPixels(it->key-mWidth*0.5, it->median), coordsToPixels(it->key+mWidth*0.5, it->median)));
25720 called by \ref draw to determine which data (key) range is visible at the current key axis range
25723 \a begin returns an iterator to the lowest data point that needs to be taken into account when
25727 \a end returns an iterator one higher than the highest visible data point. Same as before, \a end
25732void QCPStatisticalBox::getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, QCPStatisticalBoxDataContainer::const_iterator &end) const
25741 begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower-mWidth*0.5); // subtract half width of box to include partially visible data points
25747 Returns the box in plot coordinates (keys in x, values in y of the returned rect) that covers the
25752QRectF QCPStatisticalBox::getQuartileBox(QCPStatisticalBoxDataContainer::const_iterator it) const
25762 Returns the whisker backbones (keys in x, values in y of the returned lines) that cover the value
25763 range from the minimum to the lower quartile, and from the upper quartile to the maximum of the
25768QVector<QLineF> QCPStatisticalBox::getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const
25771 result[0].setPoints(coordsToPixels(it->key, it->lowerQuartile), coordsToPixels(it->key, it->minimum)); // min backbone
25772 result[1].setPoints(coordsToPixels(it->key, it->upperQuartile), coordsToPixels(it->key, it->maximum)); // max backbone
25778 Returns the whisker bars (keys in x, values in y of the returned lines) that are placed at the
25783QVector<QLineF> QCPStatisticalBox::getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const
25786 result[0].setPoints(coordsToPixels(it->key-mWhiskerWidth*0.5, it->minimum), coordsToPixels(it->key+mWhiskerWidth*0.5, it->minimum)); // min bar
25787 result[1].setPoints(coordsToPixels(it->key-mWhiskerWidth*0.5, it->maximum), coordsToPixels(it->key+mWhiskerWidth*0.5, it->maximum)); // max bar
25796////////////////////////////////////////////////////////////////////////////////////////////////////
25798////////////////////////////////////////////////////////////////////////////////////////////////////
25803 This class is a data storage for \ref QCPColorMap. It holds a two-dimensional array, which \ref
25804 QCPColorMap then displays as a 2D image in the plot, where the array values are represented by a
25807 The size of the array can be controlled via \ref setSize (or \ref setKeySize, \ref setValueSize).
25808 Which plot coordinates these cells correspond to can be configured with \ref setRange (or \ref
25811 The data cells can be accessed in two ways: They can be directly addressed by an integer index
25812 with \ref setCell. This is the fastest method. Alternatively, they can be addressed by their plot
25813 coordinate with \ref setData. plot coordinate to cell index transformations and vice versa are
25816 A \ref QCPColorMapData also holds an on-demand two-dimensional array of alpha values which (if
25818 fillAlpha and \ref clearAlpha. The memory for the alpha map is only allocated if needed, i.e. on
25819 the first call of \ref setAlpha. \ref clearAlpha restores full opacity and frees the alpha map.
25822 QCPColorMap::rescaleDataRange with the necessary information quickly. Setting a cell to a value
25824 setting the cell that currently holds the maximum value to a smaller value doesn't decrease the
25825 maximum again, because finding the true new maximum would require going through the entire data
25826 array, which might be time consuming. The same holds for the data minimum. This functionality is
25828 true current minimum and maximum. The method QCPColorMap::rescaleDataRange offers a convenience
25837 Returns whether this instance carries no data. This is equivalent to having a size where at least
25844 Constructs a new QCPColorMapData instance. The instance has \a keySize cells in the key direction
25845 and \a valueSize cells in the value direction. These cells will be displayed by the \ref QCPColorMap
25850QCPColorMapData::QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange) :
25885 Overwrites this color map data instance with the data stored in \a other. The alpha map state is
25915 int keyCell = int( (key-mKeyRange.lower)/(mKeyRange.upper-mKeyRange.lower)*(mKeySize-1)+0.5 );
25916 int valueCell = int( (value-mValueRange.lower)/(mValueRange.upper-mValueRange.lower)*(mValueSize-1)+0.5 );
25935 If this color map data doesn't have an alpha map (because \ref setAlpha was never called after
25949 Resizes the data array to have \a keySize cells in the key dimension and \a valueSize cells in
25955 Setting at least one of \a keySize or \a valueSize to zero frees the internal data array and \ref
25971 try { // 2D arrays get memory intensive fast. So if the allocation fails, at least output debug message
26022 Sets the coordinate ranges the data shall be distributed over. This defines the rectangular area
26025 The outer cells will be centered on the range boundaries given to this function. For example, if
26026 the key size (\ref setKeySize) is 3 and \a keyRange is set to <tt>QCPRange(2, 3)</tt> there will
26038 Sets the coordinate range the data shall be distributed over in the key dimension. Together with
26039 the value range, This defines the rectangular area covered by the color map in plot coordinates.
26041 The outer cells will be centered on the range boundaries given to this function. For example, if
26042 the key size (\ref setKeySize) is 3 and \a keyRange is set to <tt>QCPRange(2, 3)</tt> there will
26053 Sets the coordinate range the data shall be distributed over in the value dimension. Together with
26054 the key range, This defines the rectangular area covered by the color map in plot coordinates.
26056 The outer cells will be centered on the range boundaries given to this function. For example, if
26057 the value size (\ref setValueSize) is 3 and \a valueRange is set to <tt>QCPRange(2, 3)</tt> there
26068 Sets the data of the cell, which lies at the plot coordinates given by \a key and \a value, to \a
26071 \note The QCPColorMap always displays the data at equal key/value intervals, even if the key or
26072 value axis is set to a logarithmic scaling. If you want to use QCPColorMap with logarithmic axes,
26073 you shouldn't use the \ref QCPColorMapData::setData method as it uses a linear transformation to
26081 int keyCell = int( (key-mKeyRange.lower)/(mKeyRange.upper-mKeyRange.lower)*(mKeySize-1)+0.5 );
26096 enumerate the cells starting from zero, up to the map's size-1 in the respective dimension (see
26120 Sets the alpha of the color map cell given by \a keyIndex and \a valueIndex to \a alpha. A value
26124 If an alpha map doesn't exist yet for this color map data, it will be created here. If you wish
26127 Note that the cell-wise alpha which can be configured here is independent of any alpha configured
26128 in the color map's gradient (\ref QCPColorGradient). If a cell is affected both by the cell-wise
26129 and gradient alpha, the alpha values will be blended accordingly during rendering of the color
26150 Calling this method is only advised if you are about to call \ref QCPColorMap::rescaleDataRange
26151 and can not guarantee that the cells holding the maximum or minimum data haven't been overwritten
26152 with a smaller or larger value respectively, since the buffered maximum/minimum values have been
26157 recalculateDataBounds for convenience. Setting this to true will call this method for you, before
26214 Sets the opacity of all color map cells to \a alpha. A value of 0 for \a alpha results in a fully
26233 Transforms plot coordinates given by \a key and \a value to cell indices of this QCPColorMapData
26234 instance. The resulting cell indices are returned via the output parameters \a keyIndex and \a
26239 If you are only interested in a key or value index, you may pass \c nullptr as \a valueIndex or
26242 \note The QCPColorMap always displays the data at equal key/value intervals, even if the key or
26243 value axis is set to a logarithmic scaling. If you want to use QCPColorMap with logarithmic axes,
26244 you shouldn't use the \ref QCPColorMapData::coordToCell method as it uses a linear transformation to
26249void QCPColorMapData::coordToCell(double key, double value, int *keyIndex, int *valueIndex) const
26258 Transforms cell indices given by \a keyIndex and \a valueIndex to cell indices of this QCPColorMapData
26262 If you are only interested in a key or value coordinate, you may pass \c nullptr as \a key or \a
26265 \note The QCPColorMap always displays the data at equal key/value intervals, even if the key or
26266 value axis is set to a logarithmic scaling. If you want to use QCPColorMap with logarithmic axes,
26267 you shouldn't use the \ref QCPColorMapData::cellToCoord method as it uses a linear transformation to
26272void QCPColorMapData::cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const
26284 values are not initialized at all. In this case, the alpha map should be initialized manually,
26287 If an alpha map exists already, it is deleted first. If this color map is empty (has either key
26290 The return value indicates the existence of the alpha map after the call. So this method returns
26300 try { // 2D arrays get memory intensive fast. So if the allocation fails, at least output debug message
26319////////////////////////////////////////////////////////////////////////////////////////////////////
26321////////////////////////////////////////////////////////////////////////////////////////////////////
26331 A color map has three dimensions to represent a data point: The \a key dimension, the \a value
26332 dimension and the \a data dimension. As with other plottables such as graphs, \a key and \a value
26333 correspond to two orthogonal axes on the QCustomPlot surface that you specify in the QCPColorMap
26334 constructor. The \a data dimension however is encoded as the color of the point at (\a key, \a
26338 QCPColorMapData::setSize. The plot coordinate range over which these points will be displayed is
26339 specified via \ref QCPColorMapData::setRange. The first cell will be centered on the lower range
26340 boundary and the last cell will be centered on the upper range boundary. The data can be set by
26341 either accessing the cells directly with QCPColorMapData::setCell or by addressing the cells via
26346 The cell with index (0, 0) is at the bottom left, if the color map uses normal (i.e. not reversed)
26350 typically placed to the right of the axis rect. See the documentation there for details on how to
26356 setGradient. See the documentation of \ref QCPColorGradient for details on configuring a color
26360 setDataRange. To make the data range encompass the whole data set minimum to maximum, call \ref
26361 rescaleDataRange. If your data may contain NaN values, use \ref QCPColorGradient::setNanHandling
26366 Transparency in color maps can be achieved by two mechanisms. On one hand, you can specify alpha
26367 values for color stops of the \ref QCPColorGradient, via the regular QColor interface. This will
26368 cause the color map data which gets mapped to colors around those color stops to appear with the
26375 The two transparencies will be joined together in the plot and otherwise not interfere with each
26376 other. They are mixed in a multiplicative matter, so an alpha of e.g. 50% (128/255) in both modes
26387 which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot instance takes
26388 ownership of the plottable, so do not delete it manually but use QCustomPlot::removePlottable() instead.
26392 \note The QCPColorMap always displays the data at equal key/value intervals, even if the key or
26393 value axis is set to a logarithmic scaling. If you want to use QCPColorMap with logarithmic axes,
26394 you shouldn't use the \ref QCPColorMapData::setData method as it uses a linear transformation to
26439 The created QCPColorMap is automatically registered with the QCustomPlot instance inferred from
26470 qDebug() << Q_FUNC_INFO << "The data pointer is already in (and owned by) this plottable" << reinterpret_cast<quintptr>(data);
26485 Sets the data range of this color map to \a dataRange. The data range defines which data values
26524 Sets the color gradient that is used to represent the data. For more details on how to create an
26528 data range, see \ref setDataRange. Data points that are outside this data range will either be
26545 Sets whether the color map image shall use bicubic interpolation when displaying the color map
26548 \image html QCPColorMap-interpolate.png "A 10*10 color map, with interpolation and without interpolation enabled"
26560 if \a enabled is set to false, the data points at the border of the color map are drawn with the
26565 \image html QCPColorMap-tightboundary.png "A color map, with tight boundary enabled and disabled"
26575 This means that both the color scale and the color map synchronize their gradient, data range and
26576 data scale type (\ref setGradient, \ref setDataRange, \ref setDataScaleType). Multiple color maps
26580 This function causes the color map to adopt the current color gradient, data range and data scale
26581 type of \a colorScale. After this call, you may change these properties at either the color map
26590 disconnect(this, SIGNAL(dataRangeChanged(QCPRange)), mColorScale.data(), SLOT(setDataRange(QCPRange)));
26591 disconnect(this, SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), mColorScale.data(), SLOT(setDataScaleType(QCPAxis::ScaleType)));
26592 disconnect(this, SIGNAL(gradientChanged(QCPColorGradient)), mColorScale.data(), SLOT(setGradient(QCPColorGradient)));
26593 disconnect(mColorScale.data(), SIGNAL(dataRangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange)));
26594 disconnect(mColorScale.data(), SIGNAL(gradientChanged(QCPColorGradient)), this, SLOT(setGradient(QCPColorGradient)));
26595 disconnect(mColorScale.data(), SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType)));
26603 connect(this, SIGNAL(dataRangeChanged(QCPRange)), mColorScale.data(), SLOT(setDataRange(QCPRange)));
26604 connect(this, SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), mColorScale.data(), SLOT(setDataScaleType(QCPAxis::ScaleType)));
26605 connect(this, SIGNAL(gradientChanged(QCPColorGradient)), mColorScale.data(), SLOT(setGradient(QCPColorGradient)));
26606 connect(mColorScale.data(), SIGNAL(dataRangeChanged(QCPRange)), this, SLOT(setDataRange(QCPRange)));
26607 connect(mColorScale.data(), SIGNAL(gradientChanged(QCPColorGradient)), this, SLOT(setGradient(QCPColorGradient)));
26608 connect(mColorScale.data(), SIGNAL(dataScaleTypeChanged(QCPAxis::ScaleType)), this, SLOT(setDataScaleType(QCPAxis::ScaleType)));
26613 Sets the data range (\ref setDataRange) to span the minimum and maximum values that occur in the
26614 current data set. This corresponds to the \ref rescaleKeyAxis or \ref rescaleValueAxis methods,
26621 maximum can only increase and the buffered minimum can only decrease. In consequence, changes to
26623 current maximum with a smaller value), aren't recognized and the buffered maximum overestimates
26624 the true maximum of the data set. The same happens for the buffered minimum. To recalculate the
26627 recalculateDataBounds calls this method before setting the data range to the buffered minimum and
26647 The current color map appearance is scaled down to \a thumbSize. Ideally, this should be equal to
26648 the size of the legend icon (see \ref QCPLegend::setIconSize). If it isn't exactly the configured
26653void QCPColorMap::updateLegendIcon(Qt::TransformationMode transformMode, const QSize &thumbSize)
26656 updateMapImage(); // try to update map image if it's null (happens if no draw has happened yet)
26660 bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed();
26661 bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed();
26662 mLegendIcon = QPixmap::fromImage(mMapImage.mirrored(mirrorX, mirrorY)).scaled(thumbSize, Qt::KeepAspectRatio, transformMode);
26667double QCPColorMap::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const
26675 if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect))
26682 details->setValue(QCPDataSelection(QCPDataRange(0, 1))); // temporary solution, to facilitate whole-plottable selection. Replace in future version with segmented 2D selection.
26712QCPRange QCPColorMap::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const
26747 This method is called by \ref QCPColorMap::draw if either the data has been modified or the map image
26765 int keyOversamplingFactor = mInterpolate ? 1 : int(1.0+100.0/double(keySize)); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on
26766 int valueOversamplingFactor = mInterpolate ? 1 : int(1.0+100.0/double(valueSize)); // make mMapImage have at least size 100, factor becomes 1 if size > 200 or interpolation is on
26768 // resize mMapImage to correct dimensions including possible oversampling factors, according to key/value axes orientation:
26769 if (keyAxis->orientation() == Qt::Horizontal && (mMapImage.width() != keySize*keyOversamplingFactor || mMapImage.height() != valueSize*valueOversamplingFactor))
26770 mMapImage = QImage(QSize(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor), format);
26771 else if (keyAxis->orientation() == Qt::Vertical && (mMapImage.width() != valueSize*valueOversamplingFactor || mMapImage.height() != keySize*keyOversamplingFactor))
26772 mMapImage = QImage(QSize(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor), format);
26781 QImage *localMapImage = &mMapImage; // this is the image on which the colorization operates. Either the final mMapImage, or if we need oversampling, mUndersampledMapImage
26785 if (keyAxis->orientation() == Qt::Horizontal && (mUndersampledMapImage.width() != keySize || mUndersampledMapImage.height() != valueSize))
26787 else if (keyAxis->orientation() == Qt::Vertical && (mUndersampledMapImage.width() != valueSize || mUndersampledMapImage.height() != keySize))
26789 localMapImage = &mUndersampledMapImage; // make the colorization run on the undersampled image
26791 mUndersampledMapImage = QImage(); // don't need oversampling mechanism anymore (map size has changed) but mUndersampledMapImage still has nonzero size, free it
26801 QRgb* pixels = reinterpret_cast<QRgb*>(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system)
26803 mGradient.colorize(rawData+line*rowCount, rawAlpha+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic);
26805 mGradient.colorize(rawData+line*rowCount, mDataRange, pixels, rowCount, 1, mDataScaleType==QCPAxis::stLogarithmic);
26813 QRgb* pixels = reinterpret_cast<QRgb*>(localMapImage->scanLine(lineCount-1-line)); // invert scanline index because QImage counts scanlines from top, but our vertical index counts from bottom (mathematical coordinate system)
26815 mGradient.colorize(rawData+line, rawAlpha+line, mDataRange, pixels, rowCount, lineCount, mDataScaleType==QCPAxis::stLogarithmic);
26817 mGradient.colorize(rawData+line, mDataRange, pixels, rowCount, lineCount, mDataScaleType==QCPAxis::stLogarithmic);
26824 mMapImage = mUndersampledMapImage.scaled(keySize*keyOversamplingFactor, valueSize*valueOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation);
26826 mMapImage = mUndersampledMapImage.scaled(valueSize*valueOversamplingFactor, keySize*keyOversamplingFactor, Qt::IgnoreAspectRatio, Qt::FastTransformation);
26845 QCPPainter *localPainter = painter; // will be redirected to paint on mapBuffer if painting vectorized
26846 QRectF mapBufferTarget; // the rect in absolute widget coordinates where the visible map portion/buffer will end up in
26859 QRectF imageRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower),
26861 // extend imageRect to contain outer halves/quarters of bordering/cornering pixels (cells are centered on map range boundary):
26878 const bool mirrorX = (keyAxis()->orientation() == Qt::Horizontal ? keyAxis() : valueAxis())->rangeReversed();
26879 const bool mirrorY = (valueAxis()->orientation() == Qt::Vertical ? valueAxis() : keyAxis())->rangeReversed();
26880 const bool smoothBackup = localPainter->renderHints().testFlag(QPainter::SmoothPixmapTransform);
26886 QRectF tightClipRect = QRectF(coordsToPixels(mMapData->keyRange().lower, mMapData->valueRange().lower),
26909 QPixmap scaledIcon = mLegendIcon.scaled(rect.size().toSize(), Qt::KeepAspectRatio, Qt::FastTransformation);
26927////////////////////////////////////////////////////////////////////////////////////////////////////
26929////////////////////////////////////////////////////////////////////////////////////////////////////
26935 \li \a key: coordinate on the key axis of this data point (this is the \a mainKey and the \a sortKey)
26941 The container for storing multiple data points is \ref QCPFinancialDataContainer. It is a typedef
26942 for \ref QCPDataContainer with \ref QCPFinancialData as the DataType template parameter. See the
26954 For a general explanation of what this method is good for in the context of the data container,
26962 For a general explanation of what this method is good for in the context of the data container,
26968 Since the member \a key is both the data point key coordinate and the data ordering parameter,
26971 For a general explanation of what this method is good for in the context of the data container,
26979 For a general explanation of what this method is good for in the context of the data container,
26987 For a general explanation of what this method is good for in the context of the data container,
26995 For a general explanation of what this method is good for in the context of the data container,
27016QCPFinancialData::QCPFinancialData(double key, double open, double high, double low, double close) :
27026////////////////////////////////////////////////////////////////////////////////////////////////////
27028////////////////////////////////////////////////////////////////////////////////////////////////////
27036 charts. The two common representations OHLC (Open-High-Low-Close) bars and Candlesticks can be
27042 convenience function \ref timeSeriesToOhlc to generate binned OHLC-data which can then be passed
27046 setWidthType. A typical choice is to set the width type to \ref wtPlotCoords (the default) and
27051 Charts can be either single- or two-colored (\ref setTwoColored). If set to be single-colored,
27052 lines are drawn with the plottable's pen (\ref setPen) and fills with the brush (\ref setBrush).
27054 If set to two-colored, positive changes of the value during an interval (\a close >= \a open) are
27055 represented with a different pen and brush than negative changes (\a close < \a open). These can
27057 setBrushNegative. In two-colored mode, the normal plottable pen/brush is ignored. Upon selection
27070 which registers it with the QCustomPlot instance of the passed axes. Note that this QCustomPlot
27083 Returns a pointer to the internal data storage of type \ref QCPFinancialDataContainer. You may
27084 use it to directly manipulate the data, which may be more convenient and faster than using the
27091 Constructs a financial chart which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value
27092 axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have
27096 The created QCPFinancial is automatically registered with the QCustomPlot instance inferred from \a
27097 keyAxis. This QCustomPlot instance takes ownership of the QCPFinancial, so do not delete it manually
27122 Since a QSharedPointer is used, multiple QCPFinancials may share the same data container safely.
27127 If you do not wish to share containers, but create a copy from an existing container, rather use
27140 Replaces the current data with the provided points in \a keys, \a open, \a high, \a low and \a
27141 close. The provided vectors should have equal length. Else, the number of added points will be
27144 If you can guarantee that the passed data points are sorted by \a keys in ascending order, you
27149void QCPFinancial::setData(const QVector<double> &keys, const QVector<double> &open, const QVector<double> &high, const QVector<double> &low, const QVector<double> &close, bool alreadySorted)
27174 Sets how the width of the financial bars is defined. See the documentation of \ref WidthType for
27187 Sets whether this chart shall contrast positive from negative trends per data point by using two
27201 If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills
27215 If \ref setTwoColored is set to true, this function controls the brush that is used to draw fills
27258 Adds the provided points in \a keys, \a open, \a high, \a low and \a close to the current data.
27259 The provided vectors should have equal length. Else, the number of added points will be the size
27262 If you can guarantee that the passed data points are sorted by \a keys in ascending order, you
27265 Alternatively, you can also access and modify the data directly via the \ref data method, which
27270void QCPFinancial::addData(const QVector<double> &keys, const QVector<double> &open, const QVector<double> &high, const QVector<double> &low, const QVector<double> &close, bool alreadySorted)
27272 if (keys.size() != open.size() || open.size() != high.size() || high.size() != low.size() || low.size() != close.size() || close.size() != keys.size())
27273 qDebug() << Q_FUNC_INFO << "keys, open, high, low, close have different sizes:" << keys.size() << open.size() << high.size() << low.size() << close.size();
27274 const int n = qMin(keys.size(), qMin(open.size(), qMin(high.size(), qMin(low.size(), close.size()))));
27297 Alternatively, you can also access and modify the data directly via the \ref data method, which
27324 result.addDataRange(QCPDataRange(int(it-mDataContainer->constBegin()), int(it-mDataContainer->constBegin()+1)), false);
27333 If \a details is not 0, it will be set to a \ref QCPDataSelection, describing the closest data
27338double QCPFinancial::selectTest(const QPointF &pos, bool onlySelectable, QVariant *details) const
27346 if (mKeyAxis.data()->axisRect()->rect().contains(pos.toPoint()) || mParentPlot->interactions().testFlag(QCP::iSelectPlottablesBeyondAxisRect))
27388QCPRange QCPFinancial::getValueRange(bool &foundRange, QCP::SignDomain inSignDomain, const QCPRange &inKeyRange) const
27394 A convenience function that converts time series data (\a value against \a time) to OHLC binned
27395 data points. The return value can then be passed on to \ref QCPFinancialDataContainer::set(const
27398 The size of the bins can be controlled with \a timeBinSize in the same units as \a time is given.
27399 For example, if the unit of \a time is seconds and single OHLC/Candlesticks should span an hour
27402 \a timeBinOffset allows to control precisely at what \a time coordinate a bin should start. The
27403 value passed as \a timeBinOffset doesn't need to be in the range encompassed by the \a time keys.
27407QCPFinancialDataContainer QCPFinancial::timeSeriesToOhlc(const QVector<double> &time, const QVector<double> &value, double timeBinSize, double timeBinOffset)
27414 QCPFinancialData currentBinData(0, value.first(), value.first(), value.first(), value.first());
27484 painter->setAntialiasing(false); // legend icon especially of csCandlestick looks better without antialiasing
27492 painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint()));
27493 painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft()));
27494 painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft()));
27495 painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft()));
27499 painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint()));
27500 painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft()));
27501 painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft()));
27502 painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft()));
27507 painter->drawLine(QLineF(0, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft()));
27508 painter->drawLine(QLineF(rect.width()*0.2, rect.height()*0.3, rect.width()*0.2, rect.height()*0.5).translated(rect.topLeft()));
27509 painter->drawLine(QLineF(rect.width()*0.8, rect.height()*0.5, rect.width()*0.8, rect.height()*0.7).translated(rect.topLeft()));
27518 painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.topLeft().toPoint()));
27519 painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft()));
27520 painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft()));
27521 painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft()));
27525 painter->setClipRegion(QRegion(QPolygon() << rect.bottomLeft().toPoint() << rect.topRight().toPoint() << rect.bottomRight().toPoint()));
27526 painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft()));
27527 painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft()));
27528 painter->drawRect(QRectF(rect.width()*0.25, rect.height()*0.25, rect.width()*0.5, rect.height()*0.5).translated(rect.topLeft()));
27533 painter->drawLine(QLineF(0, rect.height()*0.5, rect.width()*0.25, rect.height()*0.5).translated(rect.topLeft()));
27534 painter->drawLine(QLineF(rect.width()*0.75, rect.height()*0.5, rect.width(), rect.height()*0.5).translated(rect.topLeft()));
27544 This method is a helper function for \ref draw. It is used when the chart style is \ref csOhlc.
27546void QCPFinancial::drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected)
27550 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
27566 painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->high)), QPointF(keyPixel, valueAxis->coordToPixel(it->low)));
27568 double pixelWidth = getPixelWidth(it->key, keyPixel); // sign of this makes sure open/close are on correct sides
27587 painter->drawLine(QPointF(valueAxis->coordToPixel(it->high), keyPixel), QPointF(valueAxis->coordToPixel(it->low), keyPixel));
27589 double pixelWidth = getPixelWidth(it->key, keyPixel); // sign of this makes sure open/close are on correct sides
27601 This method is a helper function for \ref draw. It is used when the chart style is \ref csCandlestick.
27603void QCPFinancial::drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, bool isSelected)
27607 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return; }
27630 painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->high)), QPointF(keyPixel, valueAxis->coordToPixel(qMax(it->open, it->close))));
27632 painter->drawLine(QPointF(keyPixel, valueAxis->coordToPixel(it->low)), QPointF(keyPixel, valueAxis->coordToPixel(qMin(it->open, it->close))));
27635 painter->drawRect(QRectF(QPointF(keyPixel-pixelWidth, closePixel), QPointF(keyPixel+pixelWidth, openPixel)));
27658 painter->drawLine(QPointF(valueAxis->coordToPixel(it->high), keyPixel), QPointF(valueAxis->coordToPixel(qMax(it->open, it->close)), keyPixel));
27660 painter->drawLine(QPointF(valueAxis->coordToPixel(it->low), keyPixel), QPointF(valueAxis->coordToPixel(qMin(it->open, it->close)), keyPixel));
27670 This function is used to determine the width of the bar at coordinate \a key, according to the
27671 specified width (\ref setWidth) and width type (\ref setWidthType). Provide the pixel position of
27672 \a key in \a keyPixel (because usually this was already calculated via \ref QCPAxis::coordToPixel
27676 coordinate. So with a non-reversed horizontal axis, the return value is positive. With a reversed
27677 horizontal axis, the return value is negative. This is important so the open/close flags on the
27717 This method is a helper function for \ref selectTest. It is used to test for selection when the
27718 chart style is \ref csOhlc. It only tests against the data points between \a begin and \a end.
27721 representation of the plottable, and \a closestDataPoint will point to the respective data point.
27723double QCPFinancial::ohlcSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const
27728 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; }
27737 double currentDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->high)), QCPVector2D(keyPixel, valueAxis->coordToPixel(it->low)));
27750 double currentDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->high), keyPixel), QCPVector2D(valueAxis->coordToPixel(it->low), keyPixel));
27763 This method is a helper function for \ref selectTest. It is used to test for selection when the
27764 chart style is \ref csCandlestick. It only tests against the data points between \a begin and \a
27768 representation of the plottable, and \a closestDataPoint will point to the respective data point.
27770double QCPFinancial::candlestickSelectTest(const QPointF &pos, const QCPFinancialDataContainer::const_iterator &begin, const QCPFinancialDataContainer::const_iterator &end, QCPFinancialDataContainer::const_iterator &closestDataPoint) const
27775 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return -1; }
27790 currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99;
27795 double highLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->high)), QCPVector2D(keyPixel, valueAxis->coordToPixel(qMax(it->open, it->close))));
27796 double lowLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(keyPixel, valueAxis->coordToPixel(it->low)), QCPVector2D(keyPixel, valueAxis->coordToPixel(qMin(it->open, it->close))));
27817 currentDistSqr = mParentPlot->selectionTolerance()*0.99 * mParentPlot->selectionTolerance()*0.99;
27822 double highLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->high), keyPixel), QCPVector2D(valueAxis->coordToPixel(qMax(it->open, it->close)), keyPixel));
27823 double lowLineDistSqr = QCPVector2D(pos).distanceSquaredToLine(QCPVector2D(valueAxis->coordToPixel(it->low), keyPixel), QCPVector2D(valueAxis->coordToPixel(qMin(it->open, it->close)), keyPixel));
27838 called by the drawing methods to determine which data (key) range is visible at the current key
27841 \a begin returns an iterator to the lowest data point that needs to be taken into account when
27850void QCPFinancial::getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, QCPFinancialDataContainer::const_iterator &end) const
27859 begin = mDataContainer->findBegin(mKeyAxis.data()->range().lower-mWidth*0.5); // subtract half width of ohlc/candlestick to include partially visible data points
27865 Returns the hit box in pixel coordinates that will be used for data selection with the selection
27872 if (!keyAxis || !valueAxis) { qDebug() << Q_FUNC_INFO << "invalid key or value axis"; return {}; }
27879 return QRectF(keyPixel-keyWidthPixels, highPixel, keyWidthPixels*2, lowPixel-highPixel).normalized();
27881 return QRectF(highPixel, keyPixel-keyWidthPixels, lowPixel-highPixel, keyWidthPixels*2).normalized();
27889////////////////////////////////////////////////////////////////////////////////////////////////////
27891////////////////////////////////////////////////////////////////////////////////////////////////////
27899 \li \a errorPlus: how much the error bar extends towards positive coordinates from the data point
27902 The container for storing the error bar information is \ref QCPErrorBarsDataContainer. It is a
27927 Constructs an error bar with negative and positive errors set to \a errorMinus and \a errorPlus,
27937////////////////////////////////////////////////////////////////////////////////////////////////////
27939////////////////////////////////////////////////////////////////////////////////////////////////////
27946 The \ref QCPErrorBars plottable can be attached to other one-dimensional plottables (e.g. \ref
27949 Use \ref setDataPlottable to define for which plottable the \ref QCPErrorBars shall display the
27955 error data of the \ref QCPErrorBars are associated one-to-one via their index to the data points
27956 of the data plottable. You can directly access and manipulate the error bar data via \ref data.
27959 <tt>std::numeric_limits<double>::quiet_NaN()</tt>) to not show the respective error bar on the data point at
27965 whiskers (\ref setWhiskerWidth). Further, the error bar backbones may leave a gap around the data
27966 point center to prevent that error bars are drawn too close to or even through scatter points.
27974 Returns a shared pointer to the internal data storage of type \ref QCPErrorBarsDataContainer. You
27975 may use it to directly manipulate the error values, which may be more convenient and faster than
27982 Constructs an error bars plottable which uses \a keyAxis as its key axis ("x") and \a valueAxis as its value
27983 axis ("y"). \a keyAxis and \a valueAxis must reside in the same QCustomPlot instance and not have
27988 plottable and the data plottable that the error bars shall be drawn on (\ref setDataPlottable).
27990 The created \ref QCPErrorBars is automatically registered with the QCustomPlot instance inferred
27991 from \a keyAxis. This QCustomPlot instance takes ownership of the \ref QCPErrorBars, so do not
28019 If you do not wish to share containers, but create a copy from an existing container, assign the
28023 uses a \c QVector<QCPErrorBarsData> as its data container, instead of a \ref QCPDataContainer.)
28034 Sets symmetrical error values as specified in \a error. The errors will be associated one-to-one
28057void QCPErrorBars::setData(const QVector<double> &errorMinus, const QVector<double> &errorPlus)
28064 Sets the data plottable to which the error bars will be applied. The error values specified e.g.
28065 via \ref setData will be associated one-to-one by the data point index to the data points of \a
28066 plottable. This means that the error bars will adopt the key/value coordinates of the data point
28070 QCPPlottableInterface1D. Further, it must not be a \ref QCPErrorBars instance itself. If either
28074 For proper display, care must also be taken that the key and value axes of the \a plottable match