X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=lib%2FQCustomPlot%2FQCustomPlot.h;fp=lib%2FQCustomPlot%2FQCustomPlot.h;h=a0de2568c3f6279565cedfa425e6bf8823a16a0f;hb=ecb8960092356e3080fa8a7dfbddd07c71a19cf2;hp=0000000000000000000000000000000000000000;hpb=e521a1ad224a3f392d87039a96cb2db5abaa0dd9;p=cpPlugins.git diff --git a/lib/QCustomPlot/QCustomPlot.h b/lib/QCustomPlot/QCustomPlot.h new file mode 100644 index 0000000..a0de256 --- /dev/null +++ b/lib/QCustomPlot/QCustomPlot.h @@ -0,0 +1,3772 @@ +/*************************************************************************** +** ** +** QCustomPlot, an easy to use, modern plotting widget for Qt ** +** Copyright (C) 2011-2015 Emanuel Eichhammer ** +** ** +** This program is free software: you can redistribute it and/or modify ** +** it under the terms of the GNU General Public License as published by ** +** the Free Software Foundation, either version 3 of the License, or ** +** (at your option) any later version. ** +** ** +** This program is distributed in the hope that it will be useful, ** +** but WITHOUT ANY WARRANTY; without even the implied warranty of ** +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** +** GNU General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see http://www.gnu.org/licenses/. ** +** ** +**************************************************************************** +** Author: Emanuel Eichhammer ** +** Website/Contact: http://www.qcustomplot.com/ ** +** Date: 22.12.15 ** +** Version: 1.3.2 ** +****************************************************************************/ + +#ifndef QCUSTOMPLOT_H +#define QCUSTOMPLOT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +# include +# include +# include +#else +# include +# include +#endif + +class QCPPainter; +class QCustomPlot; +class QCPLayerable; +class QCPLayoutElement; +class QCPLayout; +class QCPAxis; +class QCPAxisRect; +class QCPAxisPainterPrivate; +class QCPAbstractPlottable; +class QCPGraph; +class QCPAbstractItem; +class QCPItemPosition; +class QCPLayer; +class QCPPlotTitle; +class QCPLegend; +class QCPAbstractLegendItem; +class QCPColorMap; +class QCPColorScale; +class QCPBars; + + +/*! \file */ + + +// decl definitions for shared library compilation/usage: +/* LFV + #if defined(QCUSTOMPLOT_COMPILE_LIBRARY) + # define QCP_LIB_DECL Q_DECL_EXPORT + #elif defined(QCUSTOMPLOT_USE_LIBRARY) + # define QCP_LIB_DECL Q_DECL_IMPORT + #else + # define QCP_LIB_DECL + #endif +*/ +#include +#define QCP_LIB_DECL cp_QCustomPlot_EXPORT + +/*! + The QCP Namespace contains general enums and QFlags used throughout the QCustomPlot library +*/ +namespace QCP +{ +/*! + Defines the sides of a rectangular entity to which margins can be applied. + + \see QCPLayoutElement::setAutoMargins, QCPAxisRect::setAutoMargins +*/ +enum MarginSide { msLeft = 0x01 ///< 0x01 left margin + ,msRight = 0x02 ///< 0x02 right margin + ,msTop = 0x04 ///< 0x04 top margin + ,msBottom = 0x08 ///< 0x08 bottom margin + ,msAll = 0xFF ///< 0xFF all margins + ,msNone = 0x00 ///< 0x00 no margin + }; +Q_DECLARE_FLAGS(MarginSides, MarginSide) + +/*! + Defines what objects of a plot can be forcibly drawn antialiased/not antialiased. If an object is + neither forcibly drawn antialiased nor forcibly drawn not antialiased, it is up to the respective + element how it is drawn. Typically it provides a \a setAntialiased function for this. + + \c AntialiasedElements is a flag of or-combined elements of this enum type. + + \see QCustomPlot::setAntialiasedElements, QCustomPlot::setNotAntialiasedElements +*/ +enum AntialiasedElement { aeAxes = 0x0001 ///< 0x0001 Axis base line and tick marks + ,aeGrid = 0x0002 ///< 0x0002 Grid lines + ,aeSubGrid = 0x0004 ///< 0x0004 Sub grid lines + ,aeLegend = 0x0008 ///< 0x0008 Legend box + ,aeLegendItems = 0x0010 ///< 0x0010 Legend items + ,aePlottables = 0x0020 ///< 0x0020 Main lines of plottables (excluding error bars, see element \ref aeErrorBars) + ,aeItems = 0x0040 ///< 0x0040 Main lines of items + ,aeScatters = 0x0080 ///< 0x0080 Scatter symbols of plottables (excluding scatter symbols of type ssPixmap) + ,aeErrorBars = 0x0100 ///< 0x0100 Error bars + ,aeFills = 0x0200 ///< 0x0200 Borders of fills (e.g. under or between graphs) + ,aeZeroLine = 0x0400 ///< 0x0400 Zero-lines, see \ref QCPGrid::setZeroLinePen + ,aeAll = 0xFFFF ///< 0xFFFF All elements + ,aeNone = 0x0000 ///< 0x0000 No elements + }; +Q_DECLARE_FLAGS(AntialiasedElements, AntialiasedElement) + +/*! + Defines plotting hints that control various aspects of the quality and speed of plotting. + + \see QCustomPlot::setPlottingHints +*/ +enum PlottingHint { phNone = 0x000 ///< 0x000 No hints are set + ,phFastPolylines = 0x001 ///< 0x001 Graph/Curve lines are drawn with a faster method. This reduces the quality + ///< especially of the line segment joins. (Only relevant for solid line pens.) + ,phForceRepaint = 0x002 ///< 0x002 causes an immediate repaint() instead of a soft update() when QCustomPlot::replot() is called with parameter \ref QCustomPlot::rpHint. + ///< This is set by default to prevent the plot from freezing on fast consecutive replots (e.g. user drags ranges with mouse). + ,phCacheLabels = 0x004 ///< 0x004 axis (tick) labels will be cached as pixmaps, increasing replot performance. + }; +Q_DECLARE_FLAGS(PlottingHints, PlottingHint) + +/*! + Defines the mouse interactions possible with QCustomPlot. + + \c Interactions is a flag of or-combined elements of this enum type. + + \see QCustomPlot::setInteractions +*/ +enum Interaction { iRangeDrag = 0x001 ///< 0x001 Axis ranges are draggable (see \ref QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeDragAxes) + ,iRangeZoom = 0x002 ///< 0x002 Axis ranges are zoomable with the mouse wheel (see \ref QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeZoomAxes) + ,iMultiSelect = 0x004 ///< 0x004 The user can select multiple objects by holding the modifier set by \ref QCustomPlot::setMultiSelectModifier while clicking + ,iSelectPlottables = 0x008 ///< 0x008 Plottables are selectable (e.g. graphs, curves, bars,... see QCPAbstractPlottable) + ,iSelectAxes = 0x010 ///< 0x010 Axes are selectable (or parts of them, see QCPAxis::setSelectableParts) + ,iSelectLegend = 0x020 ///< 0x020 Legends are selectable (or their child items, see QCPLegend::setSelectableParts) + ,iSelectItems = 0x040 ///< 0x040 Items are selectable (Rectangles, Arrows, Textitems, etc. see \ref QCPAbstractItem) + ,iSelectOther = 0x080 ///< 0x080 All other objects are selectable (e.g. your own derived layerables, the plot title,...) + }; +Q_DECLARE_FLAGS(Interactions, Interaction) + +/*! \internal + + Returns whether the specified \a value is considered an invalid data value for plottables (i.e. + is \e nan or \e +/-inf). This function is used to check data validity upon replots, when the + compiler flag \c QCUSTOMPLOT_CHECK_DATA is set. +*/ +inline bool isInvalidData(double value) +{ + return qIsNaN(value) || qIsInf(value); +} + +/*! \internal + \overload + + Checks two arguments instead of one. +*/ +inline bool isInvalidData(double value1, double value2) +{ + return isInvalidData(value1) || isInvalidData(value2); +} + +/*! \internal + + Sets the specified \a side of \a margins to \a value + + \see getMarginValue +*/ +inline void setMarginValue(QMargins &margins, QCP::MarginSide side, int value) +{ + switch (side) + { + case QCP::msLeft: margins.setLeft(value); break; + case QCP::msRight: margins.setRight(value); break; + case QCP::msTop: margins.setTop(value); break; + case QCP::msBottom: margins.setBottom(value); break; + case QCP::msAll: margins = QMargins(value, value, value, value); break; + default: break; + } +} + +/*! \internal + + Returns the value of the specified \a side of \a margins. If \a side is \ref QCP::msNone or + \ref QCP::msAll, returns 0. + + \see setMarginValue +*/ +inline int getMarginValue(const QMargins &margins, QCP::MarginSide side) +{ + switch (side) + { + case QCP::msLeft: return margins.left(); + case QCP::msRight: return margins.right(); + case QCP::msTop: return margins.top(); + case QCP::msBottom: return margins.bottom(); + default: break; + } + return 0; +} + +} // end of namespace QCP + +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::AntialiasedElements) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::PlottingHints) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::MarginSides) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCP::Interactions) + + +class QCP_LIB_DECL QCPScatterStyle +{ + Q_GADGET +public: + /*! + Defines the shape used for scatter points. + + On plottables/items that draw scatters, the sizes of these visualizations (with exception of + \ref ssDot and \ref ssPixmap) can be controlled with the \ref setSize function. Scatters are + drawn with the pen and brush specified with \ref setPen and \ref setBrush. + */ + Q_ENUMS(ScatterShape) + enum ScatterShape { ssNone ///< no scatter symbols are drawn (e.g. in QCPGraph, data only represented with lines) + ,ssDot ///< \enumimage{ssDot.png} a single pixel (use \ref ssDisc or \ref ssCircle if you want a round shape with a certain radius) + ,ssCross ///< \enumimage{ssCross.png} a cross + ,ssPlus ///< \enumimage{ssPlus.png} a plus + ,ssCircle ///< \enumimage{ssCircle.png} a circle + ,ssDisc ///< \enumimage{ssDisc.png} a circle which is filled with the pen's color (not the brush as with ssCircle) + ,ssSquare ///< \enumimage{ssSquare.png} a square + ,ssDiamond ///< \enumimage{ssDiamond.png} a diamond + ,ssStar ///< \enumimage{ssStar.png} a star with eight arms, i.e. a combination of cross and plus + ,ssTriangle ///< \enumimage{ssTriangle.png} an equilateral triangle, standing on baseline + ,ssTriangleInverted ///< \enumimage{ssTriangleInverted.png} an equilateral triangle, standing on corner + ,ssCrossSquare ///< \enumimage{ssCrossSquare.png} a square with a cross inside + ,ssPlusSquare ///< \enumimage{ssPlusSquare.png} a square with a plus inside + ,ssCrossCircle ///< \enumimage{ssCrossCircle.png} a circle with a cross inside + ,ssPlusCircle ///< \enumimage{ssPlusCircle.png} a circle with a plus inside + ,ssPeace ///< \enumimage{ssPeace.png} a circle, with one vertical and two downward diagonal lines + ,ssPixmap ///< a custom pixmap specified by \ref setPixmap, centered on the data point coordinates + ,ssCustom ///< custom painter operations are performed per scatter (As QPainterPath, see \ref setCustomPath) + }; + + QCPScatterStyle(); + QCPScatterStyle(ScatterShape shape, double size=6); + QCPScatterStyle(ScatterShape shape, const QColor &color, double size); + QCPScatterStyle(ScatterShape shape, const QColor &color, const QColor &fill, double size); + QCPScatterStyle(ScatterShape shape, const QPen &pen, const QBrush &brush, double size); + QCPScatterStyle(const QPixmap &pixmap); + QCPScatterStyle(const QPainterPath &customPath, const QPen &pen, const QBrush &brush=Qt::NoBrush, double size=6); + + // getters: + double size() const { return mSize; } + ScatterShape shape() const { return mShape; } + QPen pen() const { return mPen; } + QBrush brush() const { return mBrush; } + QPixmap pixmap() const { return mPixmap; } + QPainterPath customPath() const { return mCustomPath; } + + // setters: + void setSize(double size); + void setShape(ScatterShape shape); + void setPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setPixmap(const QPixmap &pixmap); + void setCustomPath(const QPainterPath &customPath); + + // non-property methods: + bool isNone() const { return mShape == ssNone; } + bool isPenDefined() const { return mPenDefined; } + void applyTo(QCPPainter *painter, const QPen &defaultPen) const; + void drawShape(QCPPainter *painter, QPointF pos) const; + void drawShape(QCPPainter *painter, double x, double y) const; + +protected: + // property members: + double mSize; + ScatterShape mShape; + QPen mPen; + QBrush mBrush; + QPixmap mPixmap; + QPainterPath mCustomPath; + + // non-property members: + bool mPenDefined; +}; +Q_DECLARE_TYPEINFO(QCPScatterStyle, Q_MOVABLE_TYPE); + + +class QCP_LIB_DECL QCPPainter : public QPainter +{ + Q_GADGET +public: + /*! + Defines special modes the painter can operate in. They disable or enable certain subsets of features/fixes/workarounds, + depending on whether they are wanted on the respective output device. + */ + enum PainterMode { pmDefault = 0x00 ///< 0x00 Default mode for painting on screen devices + ,pmVectorized = 0x01 ///< 0x01 Mode for vectorized painting (e.g. PDF export). For example, this prevents some antialiasing fixes. + ,pmNoCaching = 0x02 ///< 0x02 Mode for all sorts of exports (e.g. PNG, PDF,...). For example, this prevents using cached pixmap labels + ,pmNonCosmetic = 0x04 ///< 0x04 Turns pen widths 0 to 1, i.e. disables cosmetic pens. (A cosmetic pen is always drawn with width 1 pixel in the vector image/pdf viewer, independent of zoom.) + }; + Q_FLAGS(PainterMode PainterModes) + Q_DECLARE_FLAGS(PainterModes, PainterMode) + + QCPPainter(); + QCPPainter(QPaintDevice *device); + ~QCPPainter(); + + // getters: + bool antialiasing() const { return testRenderHint(QPainter::Antialiasing); } + PainterModes modes() const { return mModes; } + + // setters: + void setAntialiasing(bool enabled); + void setMode(PainterMode mode, bool enabled=true); + void setModes(PainterModes modes); + + // methods hiding non-virtual base class functions (QPainter bug workarounds): + bool begin(QPaintDevice *device); + void setPen(const QPen &pen); + void setPen(const QColor &color); + void setPen(Qt::PenStyle penStyle); + void drawLine(const QLineF &line); + void drawLine(const QPointF &p1, const QPointF &p2) {drawLine(QLineF(p1, p2));} + void save(); + void restore(); + + // non-virtual methods: + void makeNonCosmetic(); + +protected: + // property members: + PainterModes mModes; + bool mIsAntialiasing; + + // non-property members: + QStack mAntialiasingStack; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPainter::PainterModes) + + +class QCP_LIB_DECL QCPLayer : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) + Q_PROPERTY(QString name READ name) + Q_PROPERTY(int index READ index) + Q_PROPERTY(QList children READ children) + Q_PROPERTY(bool visible READ visible WRITE setVisible) + /// \endcond +public: + QCPLayer(QCustomPlot* parentPlot, const QString &layerName); + ~QCPLayer(); + + // getters: + QCustomPlot *parentPlot() const { return mParentPlot; } + QString name() const { return mName; } + int index() const { return mIndex; } + QList children() const { return mChildren; } + bool visible() const { return mVisible; } + + // setters: + void setVisible(bool visible); + +protected: + // property members: + QCustomPlot *mParentPlot; + QString mName; + int mIndex; + QList mChildren; + bool mVisible; + + // non-virtual methods: + void addChild(QCPLayerable *layerable, bool prepend); + void removeChild(QCPLayerable *layerable); + +private: + Q_DISABLE_COPY(QCPLayer) + + friend class QCustomPlot; + friend class QCPLayerable; +}; + +class QCP_LIB_DECL QCPLayerable : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool visible READ visible WRITE setVisible) + Q_PROPERTY(QCustomPlot* parentPlot READ parentPlot) + Q_PROPERTY(QCPLayerable* parentLayerable READ parentLayerable) + Q_PROPERTY(QCPLayer* layer READ layer WRITE setLayer NOTIFY layerChanged) + Q_PROPERTY(bool antialiased READ antialiased WRITE setAntialiased) + /// \endcond +public: + QCPLayerable(QCustomPlot *plot, QString targetLayer=QString(), QCPLayerable *parentLayerable=0); + ~QCPLayerable(); + + // getters: + bool visible() const { return mVisible; } + QCustomPlot *parentPlot() const { return mParentPlot; } + QCPLayerable *parentLayerable() const { return mParentLayerable.data(); } + QCPLayer *layer() const { return mLayer; } + bool antialiased() const { return mAntialiased; } + + // setters: + void setVisible(bool on); + Q_SLOT bool setLayer(QCPLayer *layer); + bool setLayer(const QString &layerName); + void setAntialiased(bool enabled); + + // introduced virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + // non-property methods: + bool realVisibility() const; + +signals: + void layerChanged(QCPLayer *newLayer); + +protected: + // property members: + bool mVisible; + QCustomPlot *mParentPlot; + QPointer mParentLayerable; + QCPLayer *mLayer; + bool mAntialiased; + + // introduced virtual methods: + virtual void parentPlotInitialized(QCustomPlot *parentPlot); + virtual QCP::Interaction selectionCategory() const; + virtual QRect clipRect() const; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const = 0; + virtual void draw(QCPPainter *painter) = 0; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + + // non-property methods: + void initializeParentPlot(QCustomPlot *parentPlot); + void setParentLayerable(QCPLayerable* parentLayerable); + bool moveToLayer(QCPLayer *layer, bool prepend); + void applyAntialiasingHint(QCPPainter *painter, bool localAntialiased, QCP::AntialiasedElement overrideElement) const; + +private: + Q_DISABLE_COPY(QCPLayerable) + + friend class QCustomPlot; + friend class QCPAxisRect; +}; + + +class QCP_LIB_DECL QCPRange +{ +public: + double lower, upper; + + QCPRange(); + QCPRange(double lower, double upper); + + bool operator==(const QCPRange& other) const { return lower == other.lower && upper == other.upper; } + bool operator!=(const QCPRange& other) const { return !(*this == other); } + + QCPRange &operator+=(const double& value) { lower+=value; upper+=value; return *this; } + QCPRange &operator-=(const double& value) { lower-=value; upper-=value; return *this; } + QCPRange &operator*=(const double& value) { lower*=value; upper*=value; return *this; } + QCPRange &operator/=(const double& value) { lower/=value; upper/=value; return *this; } + friend inline const QCPRange operator+(const QCPRange&, double); + friend inline const QCPRange operator+(double, const QCPRange&); + friend inline const QCPRange operator-(const QCPRange& range, double value); + friend inline const QCPRange operator*(const QCPRange& range, double value); + friend inline const QCPRange operator*(double value, const QCPRange& range); + friend inline const QCPRange operator/(const QCPRange& range, double value); + + double size() const; + double center() const; + void normalize(); + void expand(const QCPRange &otherRange); + QCPRange expanded(const QCPRange &otherRange) const; + QCPRange sanitizedForLogScale() const; + QCPRange sanitizedForLinScale() const; + bool contains(double value) const; + + static bool validRange(double lower, double upper); + static bool validRange(const QCPRange &range); + static const double minRange; //1e-280; + static const double maxRange; //1e280; + +}; +Q_DECLARE_TYPEINFO(QCPRange, Q_MOVABLE_TYPE); + +/* documentation of inline functions */ + +/*! \fn QCPRange &QCPRange::operator+=(const double& value) + + Adds \a value to both boundaries of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator-=(const double& value) + + Subtracts \a value from both boundaries of the range. +*/ + +/*! \fn QCPRange &QCPRange::operator*=(const double& value) + + Multiplies both boundaries of the range by \a value. +*/ + +/*! \fn QCPRange &QCPRange::operator/=(const double& value) + + Divides both boundaries of the range by \a value. +*/ + +/* end documentation of inline functions */ + +/*! + Adds \a value to both boundaries of the range. +*/ +inline const QCPRange operator+(const QCPRange& range, double value) +{ + QCPRange result(range); + result += value; + return result; +} + +/*! + Adds \a value to both boundaries of the range. +*/ +inline const QCPRange operator+(double value, const QCPRange& range) +{ + QCPRange result(range); + result += value; + return result; +} + +/*! + Subtracts \a value from both boundaries of the range. +*/ +inline const QCPRange operator-(const QCPRange& range, double value) +{ + QCPRange result(range); + result -= value; + return result; +} + +/*! + Multiplies both boundaries of the range by \a value. +*/ +inline const QCPRange operator*(const QCPRange& range, double value) +{ + QCPRange result(range); + result *= value; + return result; +} + +/*! + Multiplies both boundaries of the range by \a value. +*/ +inline const QCPRange operator*(double value, const QCPRange& range) +{ + QCPRange result(range); + result *= value; + return result; +} + +/*! + Divides both boundaries of the range by \a value. +*/ +inline const QCPRange operator/(const QCPRange& range, double value) +{ + QCPRange result(range); + result /= value; + return result; +} + + +class QCP_LIB_DECL QCPMarginGroup : public QObject +{ + Q_OBJECT +public: + QCPMarginGroup(QCustomPlot *parentPlot); + ~QCPMarginGroup(); + + // non-virtual methods: + QList elements(QCP::MarginSide side) const { return mChildren.value(side); } + bool isEmpty() const; + void clear(); + +protected: + // non-property members: + QCustomPlot *mParentPlot; + QHash > mChildren; + + // non-virtual methods: + int commonMargin(QCP::MarginSide side) const; + void addChild(QCP::MarginSide side, QCPLayoutElement *element); + void removeChild(QCP::MarginSide side, QCPLayoutElement *element); + +private: + Q_DISABLE_COPY(QCPMarginGroup) + + friend class QCPLayoutElement; +}; + + +class QCP_LIB_DECL QCPLayoutElement : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPLayout* layout READ layout) + Q_PROPERTY(QRect rect READ rect) + Q_PROPERTY(QRect outerRect READ outerRect WRITE setOuterRect) + Q_PROPERTY(QMargins margins READ margins WRITE setMargins) + Q_PROPERTY(QMargins minimumMargins READ minimumMargins WRITE setMinimumMargins) + Q_PROPERTY(QSize minimumSize READ minimumSize WRITE setMinimumSize) + Q_PROPERTY(QSize maximumSize READ maximumSize WRITE setMaximumSize) + /// \endcond +public: + /*! + Defines the phases of the update process, that happens just before a replot. At each phase, + \ref update is called with the according UpdatePhase value. + */ + enum UpdatePhase { upPreparation ///< Phase used for any type of preparation that needs to be done before margin calculation and layout + ,upMargins ///< Phase in which the margins are calculated and set + ,upLayout ///< Final phase in which the layout system places the rects of the elements + }; + Q_ENUMS(UpdatePhase) + + explicit QCPLayoutElement(QCustomPlot *parentPlot=0); + virtual ~QCPLayoutElement(); + + // getters: + QCPLayout *layout() const { return mParentLayout; } + QRect rect() const { return mRect; } + QRect outerRect() const { return mOuterRect; } + QMargins margins() const { return mMargins; } + QMargins minimumMargins() const { return mMinimumMargins; } + QCP::MarginSides autoMargins() const { return mAutoMargins; } + QSize minimumSize() const { return mMinimumSize; } + QSize maximumSize() const { return mMaximumSize; } + QCPMarginGroup *marginGroup(QCP::MarginSide side) const { return mMarginGroups.value(side, (QCPMarginGroup*)0); } + QHash marginGroups() const { return mMarginGroups; } + + // setters: + void setOuterRect(const QRect &rect); + void setMargins(const QMargins &margins); + void setMinimumMargins(const QMargins &margins); + void setAutoMargins(QCP::MarginSides sides); + void setMinimumSize(const QSize &size); + void setMinimumSize(int width, int height); + void setMaximumSize(const QSize &size); + void setMaximumSize(int width, int height); + void setMarginGroup(QCP::MarginSides sides, QCPMarginGroup *group); + + // introduced virtual methods: + virtual void update(UpdatePhase phase); + virtual QSize minimumSizeHint() const; + virtual QSize maximumSizeHint() const; + virtual QList elements(bool recursive) const; + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + +protected: + // property members: + QCPLayout *mParentLayout; + QSize mMinimumSize, mMaximumSize; + QRect mRect, mOuterRect; + QMargins mMargins, mMinimumMargins; + QCP::MarginSides mAutoMargins; + QHash mMarginGroups; + + // introduced virtual methods: + virtual int calculateAutoMargin(QCP::MarginSide side); + // events: + virtual void mousePressEvent(QMouseEvent *event) {Q_UNUSED(event)} + virtual void mouseMoveEvent(QMouseEvent *event) {Q_UNUSED(event)} + virtual void mouseReleaseEvent(QMouseEvent *event) {Q_UNUSED(event)} + virtual void mouseDoubleClickEvent(QMouseEvent *event) {Q_UNUSED(event)} + virtual void wheelEvent(QWheelEvent *event) {Q_UNUSED(event)} + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const { Q_UNUSED(painter) } + virtual void draw(QCPPainter *painter) { Q_UNUSED(painter) } + virtual void parentPlotInitialized(QCustomPlot *parentPlot); + +private: + Q_DISABLE_COPY(QCPLayoutElement) + + friend class QCustomPlot; + friend class QCPLayout; + friend class QCPMarginGroup; +}; + + +class QCP_LIB_DECL QCPLayout : public QCPLayoutElement +{ + Q_OBJECT +public: + explicit QCPLayout(); + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase); + virtual QList elements(bool recursive) const; + + // introduced virtual methods: + virtual int elementCount() const = 0; + virtual QCPLayoutElement* elementAt(int index) const = 0; + virtual QCPLayoutElement* takeAt(int index) = 0; + virtual bool take(QCPLayoutElement* element) = 0; + virtual void simplify(); + + // non-virtual methods: + bool removeAt(int index); + bool remove(QCPLayoutElement* element); + void clear(); + +protected: + // introduced virtual methods: + virtual void updateLayout(); + + // non-virtual methods: + void sizeConstraintsChanged() const; + void adoptElement(QCPLayoutElement *el); + void releaseElement(QCPLayoutElement *el); + QVector getSectionSizes(QVector maxSizes, QVector minSizes, QVector stretchFactors, int totalSize) const; + +private: + Q_DISABLE_COPY(QCPLayout) + friend class QCPLayoutElement; +}; + + +class QCP_LIB_DECL QCPLayoutGrid : public QCPLayout +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(int rowCount READ rowCount) + Q_PROPERTY(int columnCount READ columnCount) + Q_PROPERTY(QList columnStretchFactors READ columnStretchFactors WRITE setColumnStretchFactors) + Q_PROPERTY(QList rowStretchFactors READ rowStretchFactors WRITE setRowStretchFactors) + Q_PROPERTY(int columnSpacing READ columnSpacing WRITE setColumnSpacing) + Q_PROPERTY(int rowSpacing READ rowSpacing WRITE setRowSpacing) + /// \endcond +public: + explicit QCPLayoutGrid(); + virtual ~QCPLayoutGrid(); + + // getters: + int rowCount() const; + int columnCount() const; + QList columnStretchFactors() const { return mColumnStretchFactors; } + QList rowStretchFactors() const { return mRowStretchFactors; } + int columnSpacing() const { return mColumnSpacing; } + int rowSpacing() const { return mRowSpacing; } + + // setters: + void setColumnStretchFactor(int column, double factor); + void setColumnStretchFactors(const QList &factors); + void setRowStretchFactor(int row, double factor); + void setRowStretchFactors(const QList &factors); + void setColumnSpacing(int pixels); + void setRowSpacing(int pixels); + + // reimplemented virtual methods: + virtual void updateLayout(); + virtual int elementCount() const; + virtual QCPLayoutElement* elementAt(int index) const; + virtual QCPLayoutElement* takeAt(int index); + virtual bool take(QCPLayoutElement* element); + virtual QList elements(bool recursive) const; + virtual void simplify(); + virtual QSize minimumSizeHint() const; + virtual QSize maximumSizeHint() const; + + // non-virtual methods: + QCPLayoutElement *element(int row, int column) const; + bool addElement(int row, int column, QCPLayoutElement *element); + bool hasElement(int row, int column); + void expandTo(int newRowCount, int newColumnCount); + void insertRow(int newIndex); + void insertColumn(int newIndex); + +protected: + // property members: + QList > mElements; + QList mColumnStretchFactors; + QList mRowStretchFactors; + int mColumnSpacing, mRowSpacing; + + // non-virtual methods: + void getMinimumRowColSizes(QVector *minColWidths, QVector *minRowHeights) const; + void getMaximumRowColSizes(QVector *maxColWidths, QVector *maxRowHeights) const; + +private: + Q_DISABLE_COPY(QCPLayoutGrid) +}; + + +class QCP_LIB_DECL QCPLayoutInset : public QCPLayout +{ + Q_OBJECT +public: + /*! + Defines how the placement and sizing is handled for a certain element in a QCPLayoutInset. + */ + enum InsetPlacement { ipFree ///< The element may be positioned/sized arbitrarily, see \ref setInsetRect + ,ipBorderAligned ///< The element is aligned to one of the layout sides, see \ref setInsetAlignment + }; + + explicit QCPLayoutInset(); + virtual ~QCPLayoutInset(); + + // getters: + InsetPlacement insetPlacement(int index) const; + Qt::Alignment insetAlignment(int index) const; + QRectF insetRect(int index) const; + + // setters: + void setInsetPlacement(int index, InsetPlacement placement); + void setInsetAlignment(int index, Qt::Alignment alignment); + void setInsetRect(int index, const QRectF &rect); + + // reimplemented virtual methods: + virtual void updateLayout(); + virtual int elementCount() const; + virtual QCPLayoutElement* elementAt(int index) const; + virtual QCPLayoutElement* takeAt(int index); + virtual bool take(QCPLayoutElement* element); + virtual void simplify() {} + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + // non-virtual methods: + void addElement(QCPLayoutElement *element, Qt::Alignment alignment); + void addElement(QCPLayoutElement *element, const QRectF &rect); + +protected: + // property members: + QList mElements; + QList mInsetPlacement; + QList mInsetAlignment; + QList mInsetRect; + +private: + Q_DISABLE_COPY(QCPLayoutInset) +}; + + +class QCP_LIB_DECL QCPLineEnding +{ + Q_GADGET +public: + /*! + Defines the type of ending decoration for line-like items, e.g. an arrow. + + \image html QCPLineEnding.png + + The width and length of these decorations can be controlled with the functions \ref setWidth + and \ref setLength. Some decorations like \ref esDisc, \ref esSquare, \ref esDiamond and \ref esBar only + support a width, the length property is ignored. + + \see QCPItemLine::setHead, QCPItemLine::setTail, QCPItemCurve::setHead, QCPItemCurve::setTail, QCPAxis::setLowerEnding, QCPAxis::setUpperEnding + */ + Q_ENUMS(EndingStyle) + enum EndingStyle { esNone ///< No ending decoration + ,esFlatArrow ///< A filled arrow head with a straight/flat back (a triangle) + ,esSpikeArrow ///< A filled arrow head with an indented back + ,esLineArrow ///< A non-filled arrow head with open back + ,esDisc ///< A filled circle + ,esSquare ///< A filled square + ,esDiamond ///< A filled diamond (45° rotated square) + ,esBar ///< A bar perpendicular to the line + ,esHalfBar ///< A bar perpendicular to the line, pointing out to only one side (to which side can be changed with \ref setInverted) + ,esSkewedBar ///< A bar that is skewed (skew controllable via \ref setLength) + }; + + QCPLineEnding(); + QCPLineEnding(EndingStyle style, double width=8, double length=10, bool inverted=false); + + // getters: + EndingStyle style() const { return mStyle; } + double width() const { return mWidth; } + double length() const { return mLength; } + bool inverted() const { return mInverted; } + + // setters: + void setStyle(EndingStyle style); + void setWidth(double width); + void setLength(double length); + void setInverted(bool inverted); + + // non-property methods: + double boundingDistance() const; + double realLength() const; + void draw(QCPPainter *painter, const QVector2D &pos, const QVector2D &dir) const; + void draw(QCPPainter *painter, const QVector2D &pos, double angle) const; + +protected: + // property members: + EndingStyle mStyle; + double mWidth, mLength; + bool mInverted; +}; +Q_DECLARE_TYPEINFO(QCPLineEnding, Q_MOVABLE_TYPE); + + +class QCP_LIB_DECL QCPGrid :public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool subGridVisible READ subGridVisible WRITE setSubGridVisible) + Q_PROPERTY(bool antialiasedSubGrid READ antialiasedSubGrid WRITE setAntialiasedSubGrid) + Q_PROPERTY(bool antialiasedZeroLine READ antialiasedZeroLine WRITE setAntialiasedZeroLine) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen subGridPen READ subGridPen WRITE setSubGridPen) + Q_PROPERTY(QPen zeroLinePen READ zeroLinePen WRITE setZeroLinePen) + /// \endcond +public: + QCPGrid(QCPAxis *parentAxis); + + // getters: + bool subGridVisible() const { return mSubGridVisible; } + bool antialiasedSubGrid() const { return mAntialiasedSubGrid; } + bool antialiasedZeroLine() const { return mAntialiasedZeroLine; } + QPen pen() const { return mPen; } + QPen subGridPen() const { return mSubGridPen; } + QPen zeroLinePen() const { return mZeroLinePen; } + + // setters: + void setSubGridVisible(bool visible); + void setAntialiasedSubGrid(bool enabled); + void setAntialiasedZeroLine(bool enabled); + void setPen(const QPen &pen); + void setSubGridPen(const QPen &pen); + void setZeroLinePen(const QPen &pen); + +protected: + // property members: + bool mSubGridVisible; + bool mAntialiasedSubGrid, mAntialiasedZeroLine; + QPen mPen, mSubGridPen, mZeroLinePen; + // non-property members: + QCPAxis *mParentAxis; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + virtual void draw(QCPPainter *painter); + + // non-virtual methods: + void drawGridLines(QCPPainter *painter) const; + void drawSubGridLines(QCPPainter *painter) const; + + friend class QCPAxis; +}; + + +class QCP_LIB_DECL QCPAxis : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(AxisType axisType READ axisType) + Q_PROPERTY(QCPAxisRect* axisRect READ axisRect) + Q_PROPERTY(ScaleType scaleType READ scaleType WRITE setScaleType NOTIFY scaleTypeChanged) + Q_PROPERTY(double scaleLogBase READ scaleLogBase WRITE setScaleLogBase) + Q_PROPERTY(QCPRange range READ range WRITE setRange NOTIFY rangeChanged) + Q_PROPERTY(bool rangeReversed READ rangeReversed WRITE setRangeReversed) + Q_PROPERTY(bool autoTicks READ autoTicks WRITE setAutoTicks) + Q_PROPERTY(int autoTickCount READ autoTickCount WRITE setAutoTickCount) + Q_PROPERTY(bool autoTickLabels READ autoTickLabels WRITE setAutoTickLabels) + Q_PROPERTY(bool autoTickStep READ autoTickStep WRITE setAutoTickStep) + Q_PROPERTY(bool autoSubTicks READ autoSubTicks WRITE setAutoSubTicks) + Q_PROPERTY(bool ticks READ ticks WRITE setTicks) + Q_PROPERTY(bool tickLabels READ tickLabels WRITE setTickLabels) + Q_PROPERTY(int tickLabelPadding READ tickLabelPadding WRITE setTickLabelPadding) + Q_PROPERTY(LabelType tickLabelType READ tickLabelType WRITE setTickLabelType) + Q_PROPERTY(QFont tickLabelFont READ tickLabelFont WRITE setTickLabelFont) + Q_PROPERTY(QColor tickLabelColor READ tickLabelColor WRITE setTickLabelColor) + Q_PROPERTY(double tickLabelRotation READ tickLabelRotation WRITE setTickLabelRotation) + Q_PROPERTY(LabelSide tickLabelSide READ tickLabelSide WRITE setTickLabelSide) + Q_PROPERTY(QString dateTimeFormat READ dateTimeFormat WRITE setDateTimeFormat) + Q_PROPERTY(Qt::TimeSpec dateTimeSpec READ dateTimeSpec WRITE setDateTimeSpec) + Q_PROPERTY(QString numberFormat READ numberFormat WRITE setNumberFormat) + Q_PROPERTY(int numberPrecision READ numberPrecision WRITE setNumberPrecision) + Q_PROPERTY(double tickStep READ tickStep WRITE setTickStep) + Q_PROPERTY(QVector tickVector READ tickVector WRITE setTickVector) + Q_PROPERTY(QVector tickVectorLabels READ tickVectorLabels WRITE setTickVectorLabels) + Q_PROPERTY(int tickLengthIn READ tickLengthIn WRITE setTickLengthIn) + Q_PROPERTY(int tickLengthOut READ tickLengthOut WRITE setTickLengthOut) + Q_PROPERTY(int subTickCount READ subTickCount WRITE setSubTickCount) + Q_PROPERTY(int subTickLengthIn READ subTickLengthIn WRITE setSubTickLengthIn) + Q_PROPERTY(int subTickLengthOut READ subTickLengthOut WRITE setSubTickLengthOut) + Q_PROPERTY(QPen basePen READ basePen WRITE setBasePen) + Q_PROPERTY(QPen tickPen READ tickPen WRITE setTickPen) + Q_PROPERTY(QPen subTickPen READ subTickPen WRITE setSubTickPen) + Q_PROPERTY(QFont labelFont READ labelFont WRITE setLabelFont) + Q_PROPERTY(QColor labelColor READ labelColor WRITE setLabelColor) + Q_PROPERTY(QString label READ label WRITE setLabel) + Q_PROPERTY(int labelPadding READ labelPadding WRITE setLabelPadding) + Q_PROPERTY(int padding READ padding WRITE setPadding) + Q_PROPERTY(int offset READ offset WRITE setOffset) + Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectionChanged) + Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectableChanged) + Q_PROPERTY(QFont selectedTickLabelFont READ selectedTickLabelFont WRITE setSelectedTickLabelFont) + Q_PROPERTY(QFont selectedLabelFont READ selectedLabelFont WRITE setSelectedLabelFont) + Q_PROPERTY(QColor selectedTickLabelColor READ selectedTickLabelColor WRITE setSelectedTickLabelColor) + Q_PROPERTY(QColor selectedLabelColor READ selectedLabelColor WRITE setSelectedLabelColor) + Q_PROPERTY(QPen selectedBasePen READ selectedBasePen WRITE setSelectedBasePen) + Q_PROPERTY(QPen selectedTickPen READ selectedTickPen WRITE setSelectedTickPen) + Q_PROPERTY(QPen selectedSubTickPen READ selectedSubTickPen WRITE setSelectedSubTickPen) + Q_PROPERTY(QCPLineEnding lowerEnding READ lowerEnding WRITE setLowerEnding) + Q_PROPERTY(QCPLineEnding upperEnding READ upperEnding WRITE setUpperEnding) + Q_PROPERTY(QCPGrid* grid READ grid) + /// \endcond +public: + /*! + Defines at which side of the axis rect the axis will appear. This also affects how the tick + marks are drawn, on which side the labels are placed etc. + */ + enum AxisType { atLeft = 0x01 ///< 0x01 Axis is vertical and on the left side of the axis rect + ,atRight = 0x02 ///< 0x02 Axis is vertical and on the right side of the axis rect + ,atTop = 0x04 ///< 0x04 Axis is horizontal and on the top side of the axis rect + ,atBottom = 0x08 ///< 0x08 Axis is horizontal and on the bottom side of the axis rect + }; + Q_FLAGS(AxisType AxisTypes) + Q_DECLARE_FLAGS(AxisTypes, AxisType) + /*! + When automatic tick label generation is enabled (\ref setAutoTickLabels), defines how the + coordinate of the tick is interpreted, i.e. translated into a string. + + \see setTickLabelType + */ + enum LabelType { ltNumber ///< Tick coordinate is regarded as normal number and will be displayed as such. (see \ref setNumberFormat) + ,ltDateTime ///< Tick coordinate is regarded as a date/time (seconds since 1970-01-01T00:00:00 UTC) and will be displayed and formatted as such. (for details, see \ref setDateTimeFormat) + }; + Q_ENUMS(LabelType) + /*! + Defines on which side of the axis the tick labels (numbers) shall appear. + + \see setTickLabelSide + */ + enum LabelSide { lsInside ///< Tick labels will be displayed inside the axis rect and clipped to the inner axis rect + ,lsOutside ///< Tick labels will be displayed outside the axis rect + }; + Q_ENUMS(LabelSide) + /*! + Defines the scale of an axis. + \see setScaleType + */ + enum ScaleType { stLinear ///< Linear scaling + ,stLogarithmic ///< Logarithmic scaling with correspondingly transformed plots and (major) tick marks at every base power (see \ref setScaleLogBase). + }; + Q_ENUMS(ScaleType) + /*! + Defines the selectable parts of an axis. + \see setSelectableParts, setSelectedParts + */ + enum SelectablePart { spNone = 0 ///< None of the selectable parts + ,spAxis = 0x001 ///< The axis backbone and tick marks + ,spTickLabels = 0x002 ///< Tick labels (numbers) of this axis (as a whole, not individually) + ,spAxisLabel = 0x004 ///< The axis label + }; + Q_FLAGS(SelectablePart SelectableParts) + Q_DECLARE_FLAGS(SelectableParts, SelectablePart) + + explicit QCPAxis(QCPAxisRect *parent, AxisType type); + virtual ~QCPAxis(); + + // getters: + AxisType axisType() const { return mAxisType; } + QCPAxisRect *axisRect() const { return mAxisRect; } + ScaleType scaleType() const { return mScaleType; } + double scaleLogBase() const { return mScaleLogBase; } + const QCPRange range() const { return mRange; } + bool rangeReversed() const { return mRangeReversed; } + bool autoTicks() const { return mAutoTicks; } + int autoTickCount() const { return mAutoTickCount; } + bool autoTickLabels() const { return mAutoTickLabels; } + bool autoTickStep() const { return mAutoTickStep; } + bool autoSubTicks() const { return mAutoSubTicks; } + bool ticks() const { return mTicks; } + bool tickLabels() const { return mTickLabels; } + int tickLabelPadding() const; + LabelType tickLabelType() const { return mTickLabelType; } + QFont tickLabelFont() const { return mTickLabelFont; } + QColor tickLabelColor() const { return mTickLabelColor; } + double tickLabelRotation() const; + LabelSide tickLabelSide() const; + QString dateTimeFormat() const { return mDateTimeFormat; } + Qt::TimeSpec dateTimeSpec() const { return mDateTimeSpec; } + QString numberFormat() const; + int numberPrecision() const { return mNumberPrecision; } + double tickStep() const { return mTickStep; } + QVector tickVector() const { return mTickVector; } + QVector tickVectorLabels() const { return mTickVectorLabels; } + int tickLengthIn() const; + int tickLengthOut() const; + int subTickCount() const { return mSubTickCount; } + int subTickLengthIn() const; + int subTickLengthOut() const; + QPen basePen() const { return mBasePen; } + QPen tickPen() const { return mTickPen; } + QPen subTickPen() const { return mSubTickPen; } + QFont labelFont() const { return mLabelFont; } + QColor labelColor() const { return mLabelColor; } + QString label() const { return mLabel; } + int labelPadding() const; + int padding() const { return mPadding; } + int offset() const; + SelectableParts selectedParts() const { return mSelectedParts; } + SelectableParts selectableParts() const { return mSelectableParts; } + QFont selectedTickLabelFont() const { return mSelectedTickLabelFont; } + QFont selectedLabelFont() const { return mSelectedLabelFont; } + QColor selectedTickLabelColor() const { return mSelectedTickLabelColor; } + QColor selectedLabelColor() const { return mSelectedLabelColor; } + QPen selectedBasePen() const { return mSelectedBasePen; } + QPen selectedTickPen() const { return mSelectedTickPen; } + QPen selectedSubTickPen() const { return mSelectedSubTickPen; } + QCPLineEnding lowerEnding() const; + QCPLineEnding upperEnding() const; + QCPGrid *grid() const { return mGrid; } + + // setters: + Q_SLOT void setScaleType(QCPAxis::ScaleType type); + void setScaleLogBase(double base); + Q_SLOT void setRange(const QCPRange &range); + void setRange(double lower, double upper); + void setRange(double position, double size, Qt::AlignmentFlag alignment); + void setRangeLower(double lower); + void setRangeUpper(double upper); + void setRangeReversed(bool reversed); + void setAutoTicks(bool on); + void setAutoTickCount(int approximateCount); + void setAutoTickLabels(bool on); + void setAutoTickStep(bool on); + void setAutoSubTicks(bool on); + void setTicks(bool show); + void setTickLabels(bool show); + void setTickLabelPadding(int padding); + void setTickLabelType(LabelType type); + void setTickLabelFont(const QFont &font); + void setTickLabelColor(const QColor &color); + void setTickLabelRotation(double degrees); + void setTickLabelSide(LabelSide side); + void setDateTimeFormat(const QString &format); + void setDateTimeSpec(const Qt::TimeSpec &timeSpec); + void setNumberFormat(const QString &formatCode); + void setNumberPrecision(int precision); + void setTickStep(double step); + void setTickVector(const QVector &vec); + void setTickVectorLabels(const QVector &vec); + void setTickLength(int inside, int outside=0); + void setTickLengthIn(int inside); + void setTickLengthOut(int outside); + void setSubTickCount(int count); + void setSubTickLength(int inside, int outside=0); + void setSubTickLengthIn(int inside); + void setSubTickLengthOut(int outside); + void setBasePen(const QPen &pen); + void setTickPen(const QPen &pen); + void setSubTickPen(const QPen &pen); + void setLabelFont(const QFont &font); + void setLabelColor(const QColor &color); + void setLabel(const QString &str); + void setLabelPadding(int padding); + void setPadding(int padding); + void setOffset(int offset); + void setSelectedTickLabelFont(const QFont &font); + void setSelectedLabelFont(const QFont &font); + void setSelectedTickLabelColor(const QColor &color); + void setSelectedLabelColor(const QColor &color); + void setSelectedBasePen(const QPen &pen); + void setSelectedTickPen(const QPen &pen); + void setSelectedSubTickPen(const QPen &pen); + Q_SLOT void setSelectableParts(const QCPAxis::SelectableParts &selectableParts); + Q_SLOT void setSelectedParts(const QCPAxis::SelectableParts &selectedParts); + void setLowerEnding(const QCPLineEnding &ending); + void setUpperEnding(const QCPLineEnding &ending); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + // non-property methods: + Qt::Orientation orientation() const { return mOrientation; } + void moveRange(double diff); + void scaleRange(double factor, double center); + void setScaleRatio(const QCPAxis *otherAxis, double ratio=1.0); + void rescale(bool onlyVisiblePlottables=false); + double pixelToCoord(double value) const; + double coordToPixel(double value) const; + SelectablePart getPartAt(const QPointF &pos) const; + QList plottables() const; + QList graphs() const; + QList items() const; + + static AxisType marginSideToAxisType(QCP::MarginSide side); + static Qt::Orientation orientation(AxisType type) { return type==atBottom||type==atTop ? Qt::Horizontal : Qt::Vertical; } + static AxisType opposite(AxisType type); + +signals: + void ticksRequest(); + void rangeChanged(const QCPRange &newRange); + void rangeChanged(const QCPRange &newRange, const QCPRange &oldRange); + void scaleTypeChanged(QCPAxis::ScaleType scaleType); + void selectionChanged(const QCPAxis::SelectableParts &parts); + void selectableChanged(const QCPAxis::SelectableParts &parts); + +protected: + // property members: + // axis base: + AxisType mAxisType; + QCPAxisRect *mAxisRect; + //int mOffset; // in QCPAxisPainter + int mPadding; + Qt::Orientation mOrientation; + SelectableParts mSelectableParts, mSelectedParts; + QPen mBasePen, mSelectedBasePen; + //QCPLineEnding mLowerEnding, mUpperEnding; // in QCPAxisPainter + // axis label: + //int mLabelPadding; // in QCPAxisPainter + QString mLabel; + QFont mLabelFont, mSelectedLabelFont; + QColor mLabelColor, mSelectedLabelColor; + // tick labels: + //int mTickLabelPadding; // in QCPAxisPainter + bool mTickLabels, mAutoTickLabels; + //double mTickLabelRotation; // in QCPAxisPainter + LabelType mTickLabelType; + QFont mTickLabelFont, mSelectedTickLabelFont; + QColor mTickLabelColor, mSelectedTickLabelColor; + QString mDateTimeFormat; + Qt::TimeSpec mDateTimeSpec; + int mNumberPrecision; + QLatin1Char mNumberFormatChar; + bool mNumberBeautifulPowers; + //bool mNumberMultiplyCross; // QCPAxisPainter + // ticks and subticks: + bool mTicks; + double mTickStep; + int mSubTickCount, mAutoTickCount; + bool mAutoTicks, mAutoTickStep, mAutoSubTicks; + //int mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut; // QCPAxisPainter + QPen mTickPen, mSelectedTickPen; + QPen mSubTickPen, mSelectedSubTickPen; + // scale and range: + QCPRange mRange; + bool mRangeReversed; + ScaleType mScaleType; + double mScaleLogBase, mScaleLogBaseLogInv; + + // non-property members: + QCPGrid *mGrid; + QCPAxisPainterPrivate *mAxisPainter; + int mLowestVisibleTick, mHighestVisibleTick; + QVector mTickVector; + QVector mTickVectorLabels; + QVector mSubTickVector; + bool mCachedMarginValid; + int mCachedMargin; + + // introduced virtual methods: + virtual void setupTickVectors(); + virtual void generateAutoTicks(); + virtual int calculateAutoSubTickCount(double tickStep) const; + virtual int calculateMargin(); + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + virtual void draw(QCPPainter *painter); + virtual QCP::Interaction selectionCategory() const; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + + // non-virtual methods: + void visibleTickBounds(int &lowIndex, int &highIndex) const; + double baseLog(double value) const; + double basePow(double value) const; + QPen getBasePen() const; + QPen getTickPen() const; + QPen getSubTickPen() const; + QFont getTickLabelFont() const; + QFont getLabelFont() const; + QColor getTickLabelColor() const; + QColor getLabelColor() const; + +private: + Q_DISABLE_COPY(QCPAxis) + + friend class QCustomPlot; + friend class QCPGrid; + friend class QCPAxisRect; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::SelectableParts) +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPAxis::AxisTypes) +Q_DECLARE_METATYPE(QCPAxis::SelectablePart) + + +class QCPAxisPainterPrivate +{ +public: + explicit QCPAxisPainterPrivate(QCustomPlot *parentPlot); + virtual ~QCPAxisPainterPrivate(); + + virtual void draw(QCPPainter *painter); + virtual int size() const; + void clearCache(); + + QRect axisSelectionBox() const { return mAxisSelectionBox; } + QRect tickLabelsSelectionBox() const { return mTickLabelsSelectionBox; } + QRect labelSelectionBox() const { return mLabelSelectionBox; } + + // public property members: + QCPAxis::AxisType type; + QPen basePen; + QCPLineEnding lowerEnding, upperEnding; // directly accessed by QCPAxis setters/getters + int labelPadding; // directly accessed by QCPAxis setters/getters + QFont labelFont; + QColor labelColor; + QString label; + int tickLabelPadding; // directly accessed by QCPAxis setters/getters + double tickLabelRotation; // directly accessed by QCPAxis setters/getters + QCPAxis::LabelSide tickLabelSide; // directly accessed by QCPAxis setters/getters + bool substituteExponent; + bool numberMultiplyCross; // directly accessed by QCPAxis setters/getters + int tickLengthIn, tickLengthOut, subTickLengthIn, subTickLengthOut; // directly accessed by QCPAxis setters/getters + QPen tickPen, subTickPen; + QFont tickLabelFont; + QColor tickLabelColor; + QRect axisRect, viewportRect; + double offset; // directly accessed by QCPAxis setters/getters + bool abbreviateDecimalPowers; + bool reversedEndings; + + QVector subTickPositions; + QVector tickPositions; + QVector tickLabels; + +protected: + struct CachedLabel + { + QPointF offset; + QPixmap pixmap; + }; + struct TickLabelData + { + QString basePart, expPart; + QRect baseBounds, expBounds, totalBounds, rotatedTotalBounds; + QFont baseFont, expFont; + }; + QCustomPlot *mParentPlot; + QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to changed parameters + QCache mLabelCache; + QRect mAxisSelectionBox, mTickLabelsSelectionBox, mLabelSelectionBox; + + virtual QByteArray generateLabelParameterHash() const; + + virtual void placeTickLabel(QCPPainter *painter, double position, int distanceToAxis, const QString &text, QSize *tickLabelsSize); + virtual void drawTickLabel(QCPPainter *painter, double x, double y, const TickLabelData &labelData) const; + virtual TickLabelData getTickLabelData(const QFont &font, const QString &text) const; + virtual QPointF getTickLabelDrawOffset(const TickLabelData &labelData) const; + virtual void getMaxTickLabelSize(const QFont &font, const QString &text, QSize *tickLabelsSize) const; +}; + + +class QCP_LIB_DECL QCPAbstractPlottable : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(bool antialiasedFill READ antialiasedFill WRITE setAntialiasedFill) + Q_PROPERTY(bool antialiasedScatters READ antialiasedScatters WRITE setAntialiasedScatters) + Q_PROPERTY(bool antialiasedErrorBars READ antialiasedErrorBars WRITE setAntialiasedErrorBars) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(QCPAxis* keyAxis READ keyAxis WRITE setKeyAxis) + Q_PROPERTY(QCPAxis* valueAxis READ valueAxis WRITE setValueAxis) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) + /// \endcond +public: + QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis); + + // getters: + QString name() const { return mName; } + bool antialiasedFill() const { return mAntialiasedFill; } + bool antialiasedScatters() const { return mAntialiasedScatters; } + bool antialiasedErrorBars() const { return mAntialiasedErrorBars; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + QCPAxis *keyAxis() const { return mKeyAxis.data(); } + QCPAxis *valueAxis() const { return mValueAxis.data(); } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setName(const QString &name); + void setAntialiasedFill(bool enabled); + void setAntialiasedScatters(bool enabled); + void setAntialiasedErrorBars(bool enabled); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setKeyAxis(QCPAxis *axis); + void setValueAxis(QCPAxis *axis); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // introduced virtual methods: + virtual void clearData() = 0; + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const = 0; + virtual bool addToLegend(); + virtual bool removeFromLegend() const; + + // non-property methods: + void rescaleAxes(bool onlyEnlarge=false) const; + void rescaleKeyAxis(bool onlyEnlarge=false) const; + void rescaleValueAxis(bool onlyEnlarge=false) const; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + +protected: + /*! + Represents negative and positive sign domain for passing to \ref getKeyRange and \ref getValueRange. + */ + enum SignDomain { sdNegative ///< The negative sign domain, i.e. numbers smaller than zero + ,sdBoth ///< Both sign domains, including zero, i.e. all (rational) numbers + ,sdPositive ///< The positive sign domain, i.e. numbers greater than zero + }; + + // property members: + QString mName; + bool mAntialiasedFill, mAntialiasedScatters, mAntialiasedErrorBars; + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + QPointer mKeyAxis, mValueAxis; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual QRect clipRect() const; + virtual void draw(QCPPainter *painter) = 0; + virtual QCP::Interaction selectionCategory() const; + void applyDefaultAntialiasingHint(QCPPainter *painter) const; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + + // introduced virtual methods: + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const = 0; + virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const = 0; + virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const = 0; + + // non-virtual methods: + void coordsToPixels(double key, double value, double &x, double &y) const; + const QPointF coordsToPixels(double key, double value) const; + void pixelsToCoords(double x, double y, double &key, double &value) const; + void pixelsToCoords(const QPointF &pixelPos, double &key, double &value) const; + QPen mainPen() const; + QBrush mainBrush() const; + void applyFillAntialiasingHint(QCPPainter *painter) const; + void applyScattersAntialiasingHint(QCPPainter *painter) const; + void applyErrorBarsAntialiasingHint(QCPPainter *painter) const; + double distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const; + +private: + Q_DISABLE_COPY(QCPAbstractPlottable) + + friend class QCustomPlot; + friend class QCPAxis; + friend class QCPPlottableLegendItem; +}; + + +class QCP_LIB_DECL QCPItemAnchor +{ +public: + QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString name, int anchorId=-1); + virtual ~QCPItemAnchor(); + + // getters: + QString name() const { return mName; } + virtual QPointF pixelPoint() const; + +protected: + // property members: + QString mName; + + // non-property members: + QCustomPlot *mParentPlot; + QCPAbstractItem *mParentItem; + int mAnchorId; + QSet mChildrenX, mChildrenY; + + // introduced virtual methods: + virtual QCPItemPosition *toQCPItemPosition() { return 0; } + + // non-virtual methods: + void addChildX(QCPItemPosition* pos); // called from pos when this anchor is set as parent + void removeChildX(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted + void addChildY(QCPItemPosition* pos); // called from pos when this anchor is set as parent + void removeChildY(QCPItemPosition *pos); // called from pos when its parent anchor is reset or pos deleted + +private: + Q_DISABLE_COPY(QCPItemAnchor) + + friend class QCPItemPosition; +}; + + + +class QCP_LIB_DECL QCPItemPosition : public QCPItemAnchor +{ +public: + /*! + Defines the ways an item position can be specified. Thus it defines what the numbers passed to + \ref setCoords actually mean. + + \see setType + */ + enum PositionType { ptAbsolute ///< Static positioning in pixels, starting from the top left corner of the viewport/widget. + ,ptViewportRatio ///< Static positioning given by a fraction of the viewport size. For example, if you call setCoords(0, 0), the position will be at the top + ///< left corner of the viewport/widget. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and + ///< vertically at the top of the viewport/widget, etc. + ,ptAxisRectRatio ///< Static positioning given by a fraction of the axis rect size (see \ref setAxisRect). For example, if you call setCoords(0, 0), the position will be at the top + ///< left corner of the axis rect. setCoords(1, 1) will be at the bottom right corner, setCoords(0.5, 0) will be horizontally centered and + ///< vertically at the top of the axis rect, etc. You can also go beyond the axis rect by providing negative coordinates or coordinates larger than 1. + ,ptPlotCoords ///< Dynamic positioning at a plot coordinate defined by two axes (see \ref setAxes). + }; + + QCPItemPosition(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString name); + virtual ~QCPItemPosition(); + + // getters: + PositionType type() const { return typeX(); } + PositionType typeX() const { return mPositionTypeX; } + PositionType typeY() const { return mPositionTypeY; } + QCPItemAnchor *parentAnchor() const { return parentAnchorX(); } + QCPItemAnchor *parentAnchorX() const { return mParentAnchorX; } + QCPItemAnchor *parentAnchorY() const { return mParentAnchorY; } + double key() const { return mKey; } + double value() const { return mValue; } + QPointF coords() const { return QPointF(mKey, mValue); } + QCPAxis *keyAxis() const { return mKeyAxis.data(); } + QCPAxis *valueAxis() const { return mValueAxis.data(); } + QCPAxisRect *axisRect() const; + virtual QPointF pixelPoint() const; + + // setters: + void setType(PositionType type); + void setTypeX(PositionType type); + void setTypeY(PositionType type); + bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition=false); + void setCoords(double key, double value); + void setCoords(const QPointF &coords); + void setAxes(QCPAxis* keyAxis, QCPAxis* valueAxis); + void setAxisRect(QCPAxisRect *axisRect); + void setPixelPoint(const QPointF &pixelPoint); + +protected: + // property members: + PositionType mPositionTypeX, mPositionTypeY; + QPointer mKeyAxis, mValueAxis; + QPointer mAxisRect; + double mKey, mValue; + QCPItemAnchor *mParentAnchorX, *mParentAnchorY; + + // reimplemented virtual methods: + virtual QCPItemPosition *toQCPItemPosition() { return this; } + +private: + Q_DISABLE_COPY(QCPItemPosition) + +}; + + +class QCP_LIB_DECL QCPAbstractItem : public QCPLayerable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(bool clipToAxisRect READ clipToAxisRect WRITE setClipToAxisRect) + Q_PROPERTY(QCPAxisRect* clipAxisRect READ clipAxisRect WRITE setClipAxisRect) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) + /// \endcond +public: + QCPAbstractItem(QCustomPlot *parentPlot); + virtual ~QCPAbstractItem(); + + // getters: + bool clipToAxisRect() const { return mClipToAxisRect; } + QCPAxisRect *clipAxisRect() const; + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setClipToAxisRect(bool clip); + void setClipAxisRect(QCPAxisRect *rect); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const = 0; + + // non-virtual methods: + QList positions() const { return mPositions; } + QList anchors() const { return mAnchors; } + QCPItemPosition *position(const QString &name) const; + QCPItemAnchor *anchor(const QString &name) const; + bool hasAnchor(const QString &name) const; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + +protected: + // property members: + bool mClipToAxisRect; + QPointer mClipAxisRect; + QList mPositions; + QList mAnchors; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual QCP::Interaction selectionCategory() const; + virtual QRect clipRect() const; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + virtual void draw(QCPPainter *painter) = 0; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + + // introduced virtual methods: + virtual QPointF anchorPixelPoint(int anchorId) const; + + // non-virtual methods: + double distSqrToLine(const QPointF &start, const QPointF &end, const QPointF &point) const; + double rectSelectTest(const QRectF &rect, const QPointF &pos, bool filledRect) const; + QCPItemPosition *createPosition(const QString &name); + QCPItemAnchor *createAnchor(const QString &name, int anchorId); + +private: + Q_DISABLE_COPY(QCPAbstractItem) + + friend class QCustomPlot; + friend class QCPItemAnchor; +}; + + +class QCP_LIB_DECL QCustomPlot : public QWidget +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QRect viewport READ viewport WRITE setViewport) + Q_PROPERTY(QPixmap background READ background WRITE setBackground) + Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) + Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) + Q_PROPERTY(QCPLayoutGrid* plotLayout READ plotLayout) + Q_PROPERTY(bool autoAddPlottableToLegend READ autoAddPlottableToLegend WRITE setAutoAddPlottableToLegend) + Q_PROPERTY(int selectionTolerance READ selectionTolerance WRITE setSelectionTolerance) + Q_PROPERTY(bool noAntialiasingOnDrag READ noAntialiasingOnDrag WRITE setNoAntialiasingOnDrag) + Q_PROPERTY(Qt::KeyboardModifier multiSelectModifier READ multiSelectModifier WRITE setMultiSelectModifier) + /// \endcond +public: + /*! + Defines how a layer should be inserted relative to an other layer. + + \see addLayer, moveLayer + */ + enum LayerInsertMode { limBelow ///< Layer is inserted below other layer + ,limAbove ///< Layer is inserted above other layer + }; + Q_ENUMS(LayerInsertMode) + + /*! + Defines with what timing the QCustomPlot surface is refreshed after a replot. + + \see replot + */ + enum RefreshPriority { rpImmediate ///< The QCustomPlot surface is immediately refreshed, by calling QWidget::repaint() after the replot + ,rpQueued ///< Queues the refresh such that it is performed at a slightly delayed point in time after the replot, by calling QWidget::update() after the replot + ,rpHint ///< Whether to use immediate repaint or queued update depends on whether the plotting hint \ref QCP::phForceRepaint is set, see \ref setPlottingHints. + }; + + explicit QCustomPlot(QWidget *parent = 0); + virtual ~QCustomPlot(); + + // getters: + QRect viewport() const { return mViewport; } + QPixmap background() const { return mBackgroundPixmap; } + bool backgroundScaled() const { return mBackgroundScaled; } + Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } + QCPLayoutGrid *plotLayout() const { return mPlotLayout; } + QCP::AntialiasedElements antialiasedElements() const { return mAntialiasedElements; } + QCP::AntialiasedElements notAntialiasedElements() const { return mNotAntialiasedElements; } + bool autoAddPlottableToLegend() const { return mAutoAddPlottableToLegend; } + const QCP::Interactions interactions() const { return mInteractions; } + int selectionTolerance() const { return mSelectionTolerance; } + bool noAntialiasingOnDrag() const { return mNoAntialiasingOnDrag; } + QCP::PlottingHints plottingHints() const { return mPlottingHints; } + Qt::KeyboardModifier multiSelectModifier() const { return mMultiSelectModifier; } + + // setters: + void setViewport(const QRect &rect); + void setBackground(const QPixmap &pm); + void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); + void setBackground(const QBrush &brush); + void setBackgroundScaled(bool scaled); + void setBackgroundScaledMode(Qt::AspectRatioMode mode); + void setAntialiasedElements(const QCP::AntialiasedElements &antialiasedElements); + void setAntialiasedElement(QCP::AntialiasedElement antialiasedElement, bool enabled=true); + void setNotAntialiasedElements(const QCP::AntialiasedElements ¬AntialiasedElements); + void setNotAntialiasedElement(QCP::AntialiasedElement notAntialiasedElement, bool enabled=true); + void setAutoAddPlottableToLegend(bool on); + void setInteractions(const QCP::Interactions &interactions); + void setInteraction(const QCP::Interaction &interaction, bool enabled=true); + void setSelectionTolerance(int pixels); + void setNoAntialiasingOnDrag(bool enabled); + void setPlottingHints(const QCP::PlottingHints &hints); + void setPlottingHint(QCP::PlottingHint hint, bool enabled=true); + void setMultiSelectModifier(Qt::KeyboardModifier modifier); + + // non-property methods: + // plottable interface: + QCPAbstractPlottable *plottable(int index); + QCPAbstractPlottable *plottable(); + bool addPlottable(QCPAbstractPlottable *plottable); + bool removePlottable(QCPAbstractPlottable *plottable); + bool removePlottable(int index); + int clearPlottables(); + int plottableCount() const; + QList selectedPlottables() const; + QCPAbstractPlottable *plottableAt(const QPointF &pos, bool onlySelectable=false) const; + bool hasPlottable(QCPAbstractPlottable *plottable) const; + + // specialized interface for QCPGraph: + QCPGraph *graph(int index) const; + QCPGraph *graph() const; + QCPGraph *addGraph(QCPAxis *keyAxis=0, QCPAxis *valueAxis=0); + bool removeGraph(QCPGraph *graph); + bool removeGraph(int index); + int clearGraphs(); + int graphCount() const; + QList selectedGraphs() const; + + // item interface: + QCPAbstractItem *item(int index) const; + QCPAbstractItem *item() const; + bool addItem(QCPAbstractItem* item); + bool removeItem(QCPAbstractItem *item); + bool removeItem(int index); + int clearItems(); + int itemCount() const; + QList selectedItems() const; + QCPAbstractItem *itemAt(const QPointF &pos, bool onlySelectable=false) const; + bool hasItem(QCPAbstractItem *item) const; + + // layer interface: + QCPLayer *layer(const QString &name) const; + QCPLayer *layer(int index) const; + QCPLayer *currentLayer() const; + bool setCurrentLayer(const QString &name); + bool setCurrentLayer(QCPLayer *layer); + int layerCount() const; + bool addLayer(const QString &name, QCPLayer *otherLayer=0, LayerInsertMode insertMode=limAbove); + bool removeLayer(QCPLayer *layer); + bool moveLayer(QCPLayer *layer, QCPLayer *otherLayer, LayerInsertMode insertMode=limAbove); + + // axis rect/layout interface: + int axisRectCount() const; + QCPAxisRect* axisRect(int index=0) const; + QList axisRects() const; + QCPLayoutElement* layoutElementAt(const QPointF &pos) const; + Q_SLOT void rescaleAxes(bool onlyVisiblePlottables=false); + + QList selectedAxes() const; + QList selectedLegends() const; + Q_SLOT void deselectAll(); + + bool savePdf(const QString &fileName, bool noCosmeticPen=false, int width=0, int height=0, const QString &pdfCreator=QString(), const QString &pdfTitle=QString()); + bool savePng(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1); + bool saveJpg(const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1); + bool saveBmp(const QString &fileName, int width=0, int height=0, double scale=1.0); + bool saveRastered(const QString &fileName, int width, int height, double scale, const char *format, int quality=-1); + QPixmap toPixmap(int width=0, int height=0, double scale=1.0); + void toPainter(QCPPainter *painter, int width=0, int height=0); + Q_SLOT void replot(QCustomPlot::RefreshPriority refreshPriority=QCustomPlot::rpHint); + + QCPAxis *xAxis, *yAxis, *xAxis2, *yAxis2; + QCPLegend *legend; + +signals: + void mouseDoubleClick(QMouseEvent *event); + void mousePress(QMouseEvent *event); + void mouseMove(QMouseEvent *event); + void mouseRelease(QMouseEvent *event); + void mouseWheel(QWheelEvent *event); + + void plottableClick(QCPAbstractPlottable *plottable, QMouseEvent *event); + void plottableDoubleClick(QCPAbstractPlottable *plottable, QMouseEvent *event); + void itemClick(QCPAbstractItem *item, QMouseEvent *event); + void itemDoubleClick(QCPAbstractItem *item, QMouseEvent *event); + void axisClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); + void axisDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event); + void legendClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); + void legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item, QMouseEvent *event); + void titleClick(QMouseEvent *event, QCPPlotTitle *title); + void titleDoubleClick(QMouseEvent *event, QCPPlotTitle *title); + + void selectionChangedByUser(); + void beforeReplot(); + void afterReplot(); + +protected: + // property members: + QRect mViewport; + QCPLayoutGrid *mPlotLayout; + bool mAutoAddPlottableToLegend; + QList mPlottables; + QList mGraphs; // extra list of plottables also in mPlottables that are of type QCPGraph + QList mItems; + QList mLayers; + QCP::AntialiasedElements mAntialiasedElements, mNotAntialiasedElements; + QCP::Interactions mInteractions; + int mSelectionTolerance; + bool mNoAntialiasingOnDrag; + QBrush mBackgroundBrush; + QPixmap mBackgroundPixmap; + QPixmap mScaledBackgroundPixmap; + bool mBackgroundScaled; + Qt::AspectRatioMode mBackgroundScaledMode; + QCPLayer *mCurrentLayer; + QCP::PlottingHints mPlottingHints; + Qt::KeyboardModifier mMultiSelectModifier; + + // non-property members: + QPixmap mPaintBuffer; + QPoint mMousePressPos; + QPointer mMouseEventElement; + bool mReplotting; + + // reimplemented virtual methods: + virtual QSize minimumSizeHint() const; + virtual QSize sizeHint() const; + virtual void paintEvent(QPaintEvent *event); + virtual void resizeEvent(QResizeEvent *event); + virtual void mouseDoubleClickEvent(QMouseEvent *event); + virtual void mousePressEvent(QMouseEvent *event); + virtual void mouseMoveEvent(QMouseEvent *event); + virtual void mouseReleaseEvent(QMouseEvent *event); + virtual void wheelEvent(QWheelEvent *event); + + // introduced virtual methods: + virtual void draw(QCPPainter *painter); + virtual void axisRemoved(QCPAxis *axis); + virtual void legendRemoved(QCPLegend *legend); + + // non-virtual methods: + void updateLayerIndices() const; + QCPLayerable *layerableAt(const QPointF &pos, bool onlySelectable, QVariant *selectionDetails=0) const; + void drawBackground(QCPPainter *painter); + + friend class QCPLegend; + friend class QCPAxis; + friend class QCPLayer; + friend class QCPAxisRect; +}; + + +class QCP_LIB_DECL QCPColorGradient +{ + Q_GADGET +public: + /*! + Defines the color spaces in which color interpolation between gradient stops can be performed. + + \see setColorInterpolation + */ + enum ColorInterpolation { ciRGB ///< Color channels red, green and blue are linearly interpolated + ,ciHSV ///< Color channels hue, saturation and value are linearly interpolated (The hue is interpolated over the shortest angle distance) + }; + Q_ENUMS(ColorInterpolation) + + /*! + Defines the available presets that can be loaded with \ref loadPreset. See the documentation + there for an image of the presets. + */ + enum GradientPreset { gpGrayscale ///< Continuous lightness from black to white (suited for non-biased data representation) + ,gpHot ///< Continuous lightness from black over firey colors to white (suited for non-biased data representation) + ,gpCold ///< Continuous lightness from black over icey colors to white (suited for non-biased data representation) + ,gpNight ///< Continuous lightness from black over weak blueish colors to white (suited for non-biased data representation) + ,gpCandy ///< Blue over pink to white + ,gpGeography ///< Colors suitable to represent different elevations on geographical maps + ,gpIon ///< Half hue spectrum from black over purple to blue and finally green (creates banding illusion but allows more precise magnitude estimates) + ,gpThermal ///< Colors suitable for thermal imaging, ranging from dark blue over purple to orange, yellow and white + ,gpPolar ///< Colors suitable to emphasize polarity around the center, with blue for negative, black in the middle and red for positive values + ,gpSpectrum ///< An approximation of the visible light spectrum (creates banding illusion but allows more precise magnitude estimates) + ,gpJet ///< Hue variation similar to a spectrum, often used in numerical visualization (creates banding illusion but allows more precise magnitude estimates) + ,gpHues ///< Full hue cycle, with highest and lowest color red (suitable for periodic data, such as angles and phases, see \ref setPeriodic) + }; + Q_ENUMS(GradientPreset) + + QCPColorGradient(GradientPreset preset=gpCold); + bool operator==(const QCPColorGradient &other) const; + bool operator!=(const QCPColorGradient &other) const { return !(*this == other); } + + // getters: + int levelCount() const { return mLevelCount; } + QMap colorStops() const { return mColorStops; } + ColorInterpolation colorInterpolation() const { return mColorInterpolation; } + bool periodic() const { return mPeriodic; } + + // setters: + void setLevelCount(int n); + void setColorStops(const QMap &colorStops); + void setColorStopAt(double position, const QColor &color); + void setColorInterpolation(ColorInterpolation interpolation); + void setPeriodic(bool enabled); + + // non-property methods: + void colorize(const double *data, const QCPRange &range, QRgb *scanLine, int n, int dataIndexFactor=1, bool logarithmic=false); + QRgb color(double position, const QCPRange &range, bool logarithmic=false); + void loadPreset(GradientPreset preset); + void clearColorStops(); + QCPColorGradient inverted() const; + +protected: + void updateColorBuffer(); + + // property members: + int mLevelCount; + QMap mColorStops; + ColorInterpolation mColorInterpolation; + bool mPeriodic; + + // non-property members: + QVector mColorBuffer; + bool mColorBufferInvalidated; +}; + + +class QCP_LIB_DECL QCPAxisRect : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPixmap background READ background WRITE setBackground) + Q_PROPERTY(bool backgroundScaled READ backgroundScaled WRITE setBackgroundScaled) + Q_PROPERTY(Qt::AspectRatioMode backgroundScaledMode READ backgroundScaledMode WRITE setBackgroundScaledMode) + Q_PROPERTY(Qt::Orientations rangeDrag READ rangeDrag WRITE setRangeDrag) + Q_PROPERTY(Qt::Orientations rangeZoom READ rangeZoom WRITE setRangeZoom) + /// \endcond +public: + explicit QCPAxisRect(QCustomPlot *parentPlot, bool setupDefaultAxes=true); + virtual ~QCPAxisRect(); + + // getters: + QPixmap background() const { return mBackgroundPixmap; } + bool backgroundScaled() const { return mBackgroundScaled; } + Qt::AspectRatioMode backgroundScaledMode() const { return mBackgroundScaledMode; } + Qt::Orientations rangeDrag() const { return mRangeDrag; } + Qt::Orientations rangeZoom() const { return mRangeZoom; } + QCPAxis *rangeDragAxis(Qt::Orientation orientation); + QCPAxis *rangeZoomAxis(Qt::Orientation orientation); + double rangeZoomFactor(Qt::Orientation orientation); + + // setters: + void setBackground(const QPixmap &pm); + void setBackground(const QPixmap &pm, bool scaled, Qt::AspectRatioMode mode=Qt::KeepAspectRatioByExpanding); + void setBackground(const QBrush &brush); + void setBackgroundScaled(bool scaled); + void setBackgroundScaledMode(Qt::AspectRatioMode mode); + void setRangeDrag(Qt::Orientations orientations); + void setRangeZoom(Qt::Orientations orientations); + void setRangeDragAxes(QCPAxis *horizontal, QCPAxis *vertical); + void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical); + void setRangeZoomFactor(double horizontalFactor, double verticalFactor); + void setRangeZoomFactor(double factor); + + // non-property methods: + int axisCount(QCPAxis::AxisType type) const; + QCPAxis *axis(QCPAxis::AxisType type, int index=0) const; + QList axes(QCPAxis::AxisTypes types) const; + QList axes() const; + QCPAxis *addAxis(QCPAxis::AxisType type, QCPAxis *axis=0); + QList addAxes(QCPAxis::AxisTypes types); + bool removeAxis(QCPAxis *axis); + QCPLayoutInset *insetLayout() const { return mInsetLayout; } + + void setupFullAxesBox(bool connectRanges=false); + QList plottables() const; + QList graphs() const; + QList items() const; + + // read-only interface imitating a QRect: + int left() const { return mRect.left(); } + int right() const { return mRect.right(); } + int top() const { return mRect.top(); } + int bottom() const { return mRect.bottom(); } + int width() const { return mRect.width(); } + int height() const { return mRect.height(); } + QSize size() const { return mRect.size(); } + QPoint topLeft() const { return mRect.topLeft(); } + QPoint topRight() const { return mRect.topRight(); } + QPoint bottomLeft() const { return mRect.bottomLeft(); } + QPoint bottomRight() const { return mRect.bottomRight(); } + QPoint center() const { return mRect.center(); } + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase); + virtual QList elements(bool recursive) const; + +protected: + // property members: + QBrush mBackgroundBrush; + QPixmap mBackgroundPixmap; + QPixmap mScaledBackgroundPixmap; + bool mBackgroundScaled; + Qt::AspectRatioMode mBackgroundScaledMode; + QCPLayoutInset *mInsetLayout; + Qt::Orientations mRangeDrag, mRangeZoom; + QPointer mRangeDragHorzAxis, mRangeDragVertAxis, mRangeZoomHorzAxis, mRangeZoomVertAxis; + double mRangeZoomFactorHorz, mRangeZoomFactorVert; + // non-property members: + QCPRange mDragStartHorzRange, mDragStartVertRange; + QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; + QPoint mDragStart; + bool mDragging; + QHash > mAxes; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + virtual void draw(QCPPainter *painter); + virtual int calculateAutoMargin(QCP::MarginSide side); + // events: + virtual void mousePressEvent(QMouseEvent *event); + virtual void mouseMoveEvent(QMouseEvent *event); + virtual void mouseReleaseEvent(QMouseEvent *event); + virtual void wheelEvent(QWheelEvent *event); + + // non-property methods: + void drawBackground(QCPPainter *painter); + void updateAxesOffset(QCPAxis::AxisType type); + +private: + Q_DISABLE_COPY(QCPAxisRect) + + friend class QCustomPlot; +}; + + +class QCP_LIB_DECL QCPAbstractLegendItem : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPLegend* parentLegend READ parentLegend) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectionChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectableChanged) + /// \endcond +public: + explicit QCPAbstractLegendItem(QCPLegend *parent); + + // getters: + QCPLegend *parentLegend() const { return mParentLegend; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + +protected: + // property members: + QCPLegend *mParentLegend; + QFont mFont; + QColor mTextColor; + QFont mSelectedFont; + QColor mSelectedTextColor; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual QCP::Interaction selectionCategory() const; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + virtual QRect clipRect() const; + virtual void draw(QCPPainter *painter) = 0; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + +private: + Q_DISABLE_COPY(QCPAbstractLegendItem) + + friend class QCPLegend; +}; + + +class QCP_LIB_DECL QCPPlottableLegendItem : public QCPAbstractLegendItem +{ + Q_OBJECT +public: + QCPPlottableLegendItem(QCPLegend *parent, QCPAbstractPlottable *plottable); + + // getters: + QCPAbstractPlottable *plottable() { return mPlottable; } + +protected: + // property members: + QCPAbstractPlottable *mPlottable; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual QSize minimumSizeHint() const; + + // non-virtual methods: + QPen getIconBorderPen() const; + QColor getTextColor() const; + QFont getFont() const; +}; + + +class QCP_LIB_DECL QCPLegend : public QCPLayoutGrid +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen borderPen READ borderPen WRITE setBorderPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QSize iconSize READ iconSize WRITE setIconSize) + Q_PROPERTY(int iconTextPadding READ iconTextPadding WRITE setIconTextPadding) + Q_PROPERTY(QPen iconBorderPen READ iconBorderPen WRITE setIconBorderPen) + Q_PROPERTY(SelectableParts selectableParts READ selectableParts WRITE setSelectableParts NOTIFY selectionChanged) + Q_PROPERTY(SelectableParts selectedParts READ selectedParts WRITE setSelectedParts NOTIFY selectableChanged) + Q_PROPERTY(QPen selectedBorderPen READ selectedBorderPen WRITE setSelectedBorderPen) + Q_PROPERTY(QPen selectedIconBorderPen READ selectedIconBorderPen WRITE setSelectedIconBorderPen) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + /// \endcond +public: + /*! + Defines the selectable parts of a legend + + \see setSelectedParts, setSelectableParts + */ + enum SelectablePart { spNone = 0x000 ///< 0x000 None + ,spLegendBox = 0x001 ///< 0x001 The legend box (frame) + ,spItems = 0x002 ///< 0x002 Legend items individually (see \ref selectedItems) + }; + Q_FLAGS(SelectablePart SelectableParts) + Q_DECLARE_FLAGS(SelectableParts, SelectablePart) + + explicit QCPLegend(); + virtual ~QCPLegend(); + + // getters: + QPen borderPen() const { return mBorderPen; } + QBrush brush() const { return mBrush; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QSize iconSize() const { return mIconSize; } + int iconTextPadding() const { return mIconTextPadding; } + QPen iconBorderPen() const { return mIconBorderPen; } + SelectableParts selectableParts() const { return mSelectableParts; } + SelectableParts selectedParts() const; + QPen selectedBorderPen() const { return mSelectedBorderPen; } + QPen selectedIconBorderPen() const { return mSelectedIconBorderPen; } + QBrush selectedBrush() const { return mSelectedBrush; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + + // setters: + void setBorderPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setIconSize(const QSize &size); + void setIconSize(int width, int height); + void setIconTextPadding(int padding); + void setIconBorderPen(const QPen &pen); + Q_SLOT void setSelectableParts(const SelectableParts &selectableParts); + Q_SLOT void setSelectedParts(const SelectableParts &selectedParts); + void setSelectedBorderPen(const QPen &pen); + void setSelectedIconBorderPen(const QPen &pen); + void setSelectedBrush(const QBrush &brush); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + // non-virtual methods: + QCPAbstractLegendItem *item(int index) const; + QCPPlottableLegendItem *itemWithPlottable(const QCPAbstractPlottable *plottable) const; + int itemCount() const; + bool hasItem(QCPAbstractLegendItem *item) const; + bool hasItemWithPlottable(const QCPAbstractPlottable *plottable) const; + bool addItem(QCPAbstractLegendItem *item); + bool removeItem(int index); + bool removeItem(QCPAbstractLegendItem *item); + void clearItems(); + QList selectedItems() const; + +signals: + void selectionChanged(QCPLegend::SelectableParts parts); + void selectableChanged(QCPLegend::SelectableParts parts); + +protected: + // property members: + QPen mBorderPen, mIconBorderPen; + QBrush mBrush; + QFont mFont; + QColor mTextColor; + QSize mIconSize; + int mIconTextPadding; + SelectableParts mSelectedParts, mSelectableParts; + QPen mSelectedBorderPen, mSelectedIconBorderPen; + QBrush mSelectedBrush; + QFont mSelectedFont; + QColor mSelectedTextColor; + + // reimplemented virtual methods: + virtual void parentPlotInitialized(QCustomPlot *parentPlot); + virtual QCP::Interaction selectionCategory() const; + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + virtual void draw(QCPPainter *painter); + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + + // non-virtual methods: + QPen getBorderPen() const; + QBrush getBrush() const; + +private: + Q_DISABLE_COPY(QCPLegend) + + friend class QCustomPlot; + friend class QCPAbstractLegendItem; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(QCPLegend::SelectableParts) +Q_DECLARE_METATYPE(QCPLegend::SelectablePart) + + +class QCP_LIB_DECL QCPPlotTitle : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QColor selectedTextColor READ selectedTextColor WRITE setSelectedTextColor) + Q_PROPERTY(bool selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) + Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectionChanged) + /// \endcond +public: + explicit QCPPlotTitle(QCustomPlot *parentPlot); + explicit QCPPlotTitle(QCustomPlot *parentPlot, const QString &text); + + // getters: + QString text() const { return mText; } + QFont font() const { return mFont; } + QColor textColor() const { return mTextColor; } + QFont selectedFont() const { return mSelectedFont; } + QColor selectedTextColor() const { return mSelectedTextColor; } + bool selectable() const { return mSelectable; } + bool selected() const { return mSelected; } + + // setters: + void setText(const QString &text); + void setFont(const QFont &font); + void setTextColor(const QColor &color); + void setSelectedFont(const QFont &font); + void setSelectedTextColor(const QColor &color); + Q_SLOT void setSelectable(bool selectable); + Q_SLOT void setSelected(bool selected); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + +signals: + void selectionChanged(bool selected); + void selectableChanged(bool selectable); + +protected: + // property members: + QString mText; + QFont mFont; + QColor mTextColor; + QFont mSelectedFont; + QColor mSelectedTextColor; + QRect mTextBoundingRect; + bool mSelectable, mSelected; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + virtual void draw(QCPPainter *painter); + virtual QSize minimumSizeHint() const; + virtual QSize maximumSizeHint() const; + // events: + virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, bool *selectionStateChanged); + virtual void deselectEvent(bool *selectionStateChanged); + + // non-virtual methods: + QFont mainFont() const; + QColor mainTextColor() const; + +private: + Q_DISABLE_COPY(QCPPlotTitle) +}; + + +class QCPColorScaleAxisRectPrivate : public QCPAxisRect +{ + Q_OBJECT +public: + explicit QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale); +protected: + QCPColorScale *mParentColorScale; + QImage mGradientImage; + bool mGradientImageInvalidated; + // re-using some methods of QCPAxisRect to make them available to friend class QCPColorScale + using QCPAxisRect::calculateAutoMargin; + using QCPAxisRect::mousePressEvent; + using QCPAxisRect::mouseMoveEvent; + using QCPAxisRect::mouseReleaseEvent; + using QCPAxisRect::wheelEvent; + using QCPAxisRect::update; + virtual void draw(QCPPainter *painter); + void updateGradientImage(); + Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts); + Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts); + friend class QCPColorScale; +}; + + +class QCP_LIB_DECL QCPColorScale : public QCPLayoutElement +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPAxis::AxisType type READ type WRITE setType) + Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) + Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) + Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) + Q_PROPERTY(QString label READ label WRITE setLabel) + Q_PROPERTY(int barWidth READ barWidth WRITE setBarWidth) + Q_PROPERTY(bool rangeDrag READ rangeDrag WRITE setRangeDrag) + Q_PROPERTY(bool rangeZoom READ rangeZoom WRITE setRangeZoom) + /// \endcond +public: + explicit QCPColorScale(QCustomPlot *parentPlot); + virtual ~QCPColorScale(); + + // getters: + QCPAxis *axis() const { return mColorAxis.data(); } + QCPAxis::AxisType type() const { return mType; } + QCPRange dataRange() const { return mDataRange; } + QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } + QCPColorGradient gradient() const { return mGradient; } + QString label() const; + int barWidth () const { return mBarWidth; } + bool rangeDrag() const; + bool rangeZoom() const; + + // setters: + void setType(QCPAxis::AxisType type); + Q_SLOT void setDataRange(const QCPRange &dataRange); + Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); + Q_SLOT void setGradient(const QCPColorGradient &gradient); + void setLabel(const QString &str); + void setBarWidth(int width); + void setRangeDrag(bool enabled); + void setRangeZoom(bool enabled); + + // non-property methods: + QList colorMaps() const; + void rescaleDataRange(bool onlyVisibleMaps); + + // reimplemented virtual methods: + virtual void update(UpdatePhase phase); + +signals: + void dataRangeChanged(QCPRange newRange); + void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + void gradientChanged(QCPColorGradient newGradient); + +protected: + // property members: + QCPAxis::AxisType mType; + QCPRange mDataRange; + QCPAxis::ScaleType mDataScaleType; + QCPColorGradient mGradient; + int mBarWidth; + + // non-property members: + QPointer mAxisRect; + QPointer mColorAxis; + + // reimplemented virtual methods: + virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const; + // events: + virtual void mousePressEvent(QMouseEvent *event); + virtual void mouseMoveEvent(QMouseEvent *event); + virtual void mouseReleaseEvent(QMouseEvent *event); + virtual void wheelEvent(QWheelEvent *event); + +private: + Q_DISABLE_COPY(QCPColorScale) + + friend class QCPColorScaleAxisRectPrivate; +}; + + +/*! \file */ + + + +class QCP_LIB_DECL QCPData +{ +public: + QCPData(); + QCPData(double key, double value); + double key, value; + double keyErrorPlus, keyErrorMinus; + double valueErrorPlus, valueErrorMinus; +}; +Q_DECLARE_TYPEINFO(QCPData, Q_MOVABLE_TYPE); + +/*! \typedef QCPDataMap + Container for storing \ref QCPData items in a sorted fashion. The key of the map + is the key member of the QCPData instance. + + This is the container in which QCPGraph holds its data. + \see QCPData, QCPGraph::setData +*/ +typedef QMap QCPDataMap; +typedef QMapIterator QCPDataMapIterator; +typedef QMutableMapIterator QCPDataMutableMapIterator; + + +class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) + Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) + Q_PROPERTY(ErrorType errorType READ errorType WRITE setErrorType) + Q_PROPERTY(QPen errorPen READ errorPen WRITE setErrorPen) + Q_PROPERTY(double errorBarSize READ errorBarSize WRITE setErrorBarSize) + Q_PROPERTY(bool errorBarSkipSymbol READ errorBarSkipSymbol WRITE setErrorBarSkipSymbol) + Q_PROPERTY(QCPGraph* channelFillGraph READ channelFillGraph WRITE setChannelFillGraph) + Q_PROPERTY(bool adaptiveSampling READ adaptiveSampling WRITE setAdaptiveSampling) + /// \endcond +public: + /*! + Defines how the graph's line is represented visually in the plot. The line is drawn with the + current pen of the graph (\ref setPen). + \see setLineStyle + */ + enum LineStyle { lsNone ///< data points are not connected with any lines (e.g. data only represented + ///< with symbols according to the scatter style, see \ref setScatterStyle) + ,lsLine ///< data points are connected by a straight line + ,lsStepLeft ///< line is drawn as steps where the step height is the value of the left data point + ,lsStepRight ///< line is drawn as steps where the step height is the value of the right data point + ,lsStepCenter ///< line is drawn as steps where the step is in between two data points + ,lsImpulse ///< each data point is represented by a line parallel to the value axis, which reaches from the data point to the zero-value-line + }; + Q_ENUMS(LineStyle) + /*! + Defines what kind of error bars are drawn for each data point + */ + enum ErrorType { etNone ///< No error bars are shown + ,etKey ///< Error bars for the key dimension of the data point are shown + ,etValue ///< Error bars for the value dimension of the data point are shown + ,etBoth ///< Error bars for both key and value dimensions of the data point are shown + }; + Q_ENUMS(ErrorType) + + explicit QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPGraph(); + + // getters: + QCPDataMap *data() const { return mData; } + LineStyle lineStyle() const { return mLineStyle; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + ErrorType errorType() const { return mErrorType; } + QPen errorPen() const { return mErrorPen; } + double errorBarSize() const { return mErrorBarSize; } + bool errorBarSkipSymbol() const { return mErrorBarSkipSymbol; } + QCPGraph *channelFillGraph() const { return mChannelFillGraph.data(); } + bool adaptiveSampling() const { return mAdaptiveSampling; } + + // setters: + void setData(QCPDataMap *data, bool copy=false); + void setData(const QVector &key, const QVector &value); + void setDataKeyError(const QVector &key, const QVector &value, const QVector &keyError); + void setDataKeyError(const QVector &key, const QVector &value, const QVector &keyErrorMinus, const QVector &keyErrorPlus); + void setDataValueError(const QVector &key, const QVector &value, const QVector &valueError); + void setDataValueError(const QVector &key, const QVector &value, const QVector &valueErrorMinus, const QVector &valueErrorPlus); + void setDataBothError(const QVector &key, const QVector &value, const QVector &keyError, const QVector &valueError); + void setDataBothError(const QVector &key, const QVector &value, const QVector &keyErrorMinus, const QVector &keyErrorPlus, const QVector &valueErrorMinus, const QVector &valueErrorPlus); + void setLineStyle(LineStyle ls); + void setScatterStyle(const QCPScatterStyle &style); + void setErrorType(ErrorType errorType); + void setErrorPen(const QPen &pen); + void setErrorBarSize(double size); + void setErrorBarSkipSymbol(bool enabled); + void setChannelFillGraph(QCPGraph *targetGraph); + void setAdaptiveSampling(bool enabled); + + // non-property methods: + void addData(const QCPDataMap &dataMap); + void addData(const QCPData &data); + void addData(double key, double value); + void addData(const QVector &keys, const QVector &values); + void removeDataBefore(double key); + void removeDataAfter(double key); + void removeData(double fromKey, double toKey); + void removeData(double key); + + // reimplemented virtual methods: + virtual void clearData(); + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + using QCPAbstractPlottable::rescaleAxes; + using QCPAbstractPlottable::rescaleKeyAxis; + using QCPAbstractPlottable::rescaleValueAxis; + void rescaleAxes(bool onlyEnlarge, bool includeErrorBars) const; // overloads base class interface + void rescaleKeyAxis(bool onlyEnlarge, bool includeErrorBars) const; // overloads base class interface + void rescaleValueAxis(bool onlyEnlarge, bool includeErrorBars) const; // overloads base class interface + +protected: + // property members: + QCPDataMap *mData; + QPen mErrorPen; + LineStyle mLineStyle; + QCPScatterStyle mScatterStyle; + ErrorType mErrorType; + double mErrorBarSize; + bool mErrorBarSkipSymbol; + QPointer mChannelFillGraph; + bool mAdaptiveSampling; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; + virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain, bool includeErrors) const; // overloads base class interface + virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain, bool includeErrors) const; // overloads base class interface + + // introduced virtual methods: + virtual void drawFill(QCPPainter *painter, QVector *lineData) const; + virtual void drawScatterPlot(QCPPainter *painter, QVector *scatterData) const; + virtual void drawLinePlot(QCPPainter *painter, QVector *lineData) const; + virtual void drawImpulsePlot(QCPPainter *painter, QVector *lineData) const; + + // non-virtual methods: + void getPreparedData(QVector *lineData, QVector *scatterData) const; + void getPlotData(QVector *lineData, QVector *scatterData) const; + void getScatterPlotData(QVector *scatterData) const; + void getLinePlotData(QVector *linePixelData, QVector *scatterData) const; + void getStepLeftPlotData(QVector *linePixelData, QVector *scatterData) const; + void getStepRightPlotData(QVector *linePixelData, QVector *scatterData) const; + void getStepCenterPlotData(QVector *linePixelData, QVector *scatterData) const; + void getImpulsePlotData(QVector *linePixelData, QVector *scatterData) const; + void drawError(QCPPainter *painter, double x, double y, const QCPData &data) const; + void getVisibleDataBounds(QCPDataMap::const_iterator &lower, QCPDataMap::const_iterator &upper) const; + int countDataInBounds(const QCPDataMap::const_iterator &lower, const QCPDataMap::const_iterator &upper, int maxCount) const; + void addFillBasePoints(QVector *lineData) const; + void removeFillBasePoints(QVector *lineData) const; + QPointF lowerFillBasePoint(double lowerKey) const; + QPointF upperFillBasePoint(double upperKey) const; + const QPolygonF getChannelFillPolygon(const QVector *lineData) const; + int findIndexBelowX(const QVector *data, double x) const; + int findIndexAboveX(const QVector *data, double x) const; + int findIndexBelowY(const QVector *data, double y) const; + int findIndexAboveY(const QVector *data, double y) const; + double pointDistance(const QPointF &pixelPoint) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + + +/*! \file */ + + + +class QCP_LIB_DECL QCPCurveData +{ +public: + QCPCurveData(); + QCPCurveData(double t, double key, double value); + double t, key, value; +}; +Q_DECLARE_TYPEINFO(QCPCurveData, Q_MOVABLE_TYPE); + +/*! \typedef QCPCurveDataMap + Container for storing \ref QCPCurveData items in a sorted fashion. The key of the map + is the t member of the QCPCurveData instance. + + This is the container in which QCPCurve holds its data. + \see QCPCurveData, QCPCurve::setData +*/ + +typedef QMap QCPCurveDataMap; +typedef QMapIterator QCPCurveDataMapIterator; +typedef QMutableMapIterator QCPCurveDataMutableMapIterator; + + +class QCP_LIB_DECL QCPCurve : public QCPAbstractPlottable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) + Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) + /// \endcond +public: + /*! + Defines how the curve's line is represented visually in the plot. The line is drawn with the + current pen of the curve (\ref setPen). + \see setLineStyle + */ + enum LineStyle { lsNone ///< No line is drawn between data points (e.g. only scatters) + ,lsLine ///< Data points are connected with a straight line + }; + explicit QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPCurve(); + + // getters: + QCPCurveDataMap *data() const { return mData; } + QCPScatterStyle scatterStyle() const { return mScatterStyle; } + LineStyle lineStyle() const { return mLineStyle; } + + // setters: + void setData(QCPCurveDataMap *data, bool copy=false); + void setData(const QVector &t, const QVector &key, const QVector &value); + void setData(const QVector &key, const QVector &value); + void setScatterStyle(const QCPScatterStyle &style); + void setLineStyle(LineStyle style); + + // non-property methods: + void addData(const QCPCurveDataMap &dataMap); + void addData(const QCPCurveData &data); + void addData(double t, double key, double value); + void addData(double key, double value); + void addData(const QVector &ts, const QVector &keys, const QVector &values); + void removeDataBefore(double t); + void removeDataAfter(double t); + void removeData(double fromt, double tot); + void removeData(double t); + + // reimplemented virtual methods: + virtual void clearData(); + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + +protected: + // property members: + QCPCurveDataMap *mData; + QCPScatterStyle mScatterStyle; + LineStyle mLineStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; + virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + + // introduced virtual methods: + virtual void drawScatterPlot(QCPPainter *painter, const QVector *pointData) const; + + // non-virtual methods: + void getCurveData(QVector *lineData) const; + int getRegion(double x, double y, double rectLeft, double rectTop, double rectRight, double rectBottom) const; + QPointF getOptimizedPoint(int prevRegion, double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom) const; + QVector getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom) const; + bool mayTraverse(int prevRegion, int currentRegion) const; + bool getTraverse(double prevKey, double prevValue, double key, double value, double rectLeft, double rectTop, double rectRight, double rectBottom, QPointF &crossA, QPointF &crossB) const; + void getTraverseCornerPoints(int prevRegion, int currentRegion, double rectLeft, double rectTop, double rectRight, double rectBottom, QVector &beforeTraverse, QVector &afterTraverse) const; + double pointDistance(const QPointF &pixelPoint) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + + +/*! \file */ + + + +class QCP_LIB_DECL QCPBarsGroup : public QObject +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(SpacingType spacingType READ spacingType WRITE setSpacingType) + Q_PROPERTY(double spacing READ spacing WRITE setSpacing) + /// \endcond +public: + /*! + Defines the ways the spacing between bars in the group can be specified. Thus it defines what + the number passed to \ref setSpacing actually means. + + \see setSpacingType, setSpacing + */ + enum SpacingType { stAbsolute ///< Bar spacing is in absolute pixels + ,stAxisRectRatio ///< Bar spacing is given by a fraction of the axis rect size + ,stPlotCoords ///< Bar spacing is in key coordinates and thus scales with the key axis range + }; + QCPBarsGroup(QCustomPlot *parentPlot); + ~QCPBarsGroup(); + + // getters: + SpacingType spacingType() const { return mSpacingType; } + double spacing() const { return mSpacing; } + + // setters: + void setSpacingType(SpacingType spacingType); + void setSpacing(double spacing); + + // non-virtual methods: + QList bars() const { return mBars; } + QCPBars* bars(int index) const; + int size() const { return mBars.size(); } + bool isEmpty() const { return mBars.isEmpty(); } + void clear(); + bool contains(QCPBars *bars) const { return mBars.contains(bars); } + void append(QCPBars *bars); + void insert(int i, QCPBars *bars); + void remove(QCPBars *bars); + +protected: + // non-property members: + QCustomPlot *mParentPlot; + SpacingType mSpacingType; + double mSpacing; + QList mBars; + + // non-virtual methods: + void registerBars(QCPBars *bars); + void unregisterBars(QCPBars *bars); + + // virtual methods: + double keyPixelOffset(const QCPBars *bars, double keyCoord); + double getPixelSpacing(const QCPBars *bars, double keyCoord); + +private: + Q_DISABLE_COPY(QCPBarsGroup) + + friend class QCPBars; +}; + + +class QCP_LIB_DECL QCPBarData +{ +public: + QCPBarData(); + QCPBarData(double key, double value); + double key, value; +}; +Q_DECLARE_TYPEINFO(QCPBarData, Q_MOVABLE_TYPE); + +/*! \typedef QCPBarDataMap + Container for storing \ref QCPBarData items in a sorted fashion. The key of the map + is the key member of the QCPBarData instance. + + This is the container in which QCPBars holds its data. + \see QCPBarData, QCPBars::setData +*/ +typedef QMap QCPBarDataMap; +typedef QMapIterator QCPBarDataMapIterator; +typedef QMutableMapIterator QCPBarDataMutableMapIterator; + + +class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType) + Q_PROPERTY(QCPBarsGroup* barsGroup READ barsGroup WRITE setBarsGroup) + Q_PROPERTY(double baseValue READ baseValue WRITE setBaseValue) + Q_PROPERTY(QCPBars* barBelow READ barBelow) + Q_PROPERTY(QCPBars* barAbove READ barAbove) + /// \endcond +public: + /*! + Defines the ways the width of the bar can be specified. Thus it defines what the number passed + to \ref setWidth actually means. + + \see setWidthType, setWidth + */ + enum WidthType { wtAbsolute ///< Bar width is in absolute pixels + ,wtAxisRectRatio ///< Bar width is given by a fraction of the axis rect size + ,wtPlotCoords ///< Bar width is in key coordinates and thus scales with the key axis range + }; + Q_ENUMS(WidthType) + + explicit QCPBars(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPBars(); + + // getters: + double width() const { return mWidth; } + WidthType widthType() const { return mWidthType; } + QCPBarsGroup *barsGroup() const { return mBarsGroup; } + double baseValue() const { return mBaseValue; } + QCPBars *barBelow() const { return mBarBelow.data(); } + QCPBars *barAbove() const { return mBarAbove.data(); } + QCPBarDataMap *data() const { return mData; } + + // setters: + void setWidth(double width); + void setWidthType(WidthType widthType); + void setBarsGroup(QCPBarsGroup *barsGroup); + void setBaseValue(double baseValue); + void setData(QCPBarDataMap *data, bool copy=false); + void setData(const QVector &key, const QVector &value); + + // non-property methods: + void moveBelow(QCPBars *bars); + void moveAbove(QCPBars *bars); + void addData(const QCPBarDataMap &dataMap); + void addData(const QCPBarData &data); + void addData(double key, double value); + void addData(const QVector &keys, const QVector &values); + void removeDataBefore(double key); + void removeDataAfter(double key); + void removeData(double fromKey, double toKey); + void removeData(double key); + + // reimplemented virtual methods: + virtual void clearData(); + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + +protected: + // property members: + QCPBarDataMap *mData; + double mWidth; + WidthType mWidthType; + QCPBarsGroup *mBarsGroup; + double mBaseValue; + QPointer mBarBelow, mBarAbove; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; + virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + + // non-virtual methods: + void getVisibleDataBounds(QCPBarDataMap::const_iterator &lower, QCPBarDataMap::const_iterator &upperEnd) const; + QPolygonF getBarPolygon(double key, double value) const; + void getPixelWidth(double key, double &lower, double &upper) const; + double getStackedBaseValue(double key, bool positive) const; + static void connectBars(QCPBars* lower, QCPBars* upper); + + friend class QCustomPlot; + friend class QCPLegend; + friend class QCPBarsGroup; +}; + + +/*! \file */ + + + +class QCP_LIB_DECL QCPStatisticalBox : public QCPAbstractPlottable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(double key READ key WRITE setKey) + Q_PROPERTY(double minimum READ minimum WRITE setMinimum) + Q_PROPERTY(double lowerQuartile READ lowerQuartile WRITE setLowerQuartile) + Q_PROPERTY(double median READ median WRITE setMedian) + Q_PROPERTY(double upperQuartile READ upperQuartile WRITE setUpperQuartile) + Q_PROPERTY(double maximum READ maximum WRITE setMaximum) + Q_PROPERTY(QVector outliers READ outliers WRITE setOutliers) + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth) + Q_PROPERTY(QPen whiskerPen READ whiskerPen WRITE setWhiskerPen) + Q_PROPERTY(QPen whiskerBarPen READ whiskerBarPen WRITE setWhiskerBarPen) + Q_PROPERTY(QPen medianPen READ medianPen WRITE setMedianPen) + Q_PROPERTY(QCPScatterStyle outlierStyle READ outlierStyle WRITE setOutlierStyle) + /// \endcond +public: + explicit QCPStatisticalBox(QCPAxis *keyAxis, QCPAxis *valueAxis); + + // getters: + double key() const { return mKey; } + double minimum() const { return mMinimum; } + double lowerQuartile() const { return mLowerQuartile; } + double median() const { return mMedian; } + double upperQuartile() const { return mUpperQuartile; } + double maximum() const { return mMaximum; } + QVector outliers() const { return mOutliers; } + double width() const { return mWidth; } + double whiskerWidth() const { return mWhiskerWidth; } + QPen whiskerPen() const { return mWhiskerPen; } + QPen whiskerBarPen() const { return mWhiskerBarPen; } + QPen medianPen() const { return mMedianPen; } + QCPScatterStyle outlierStyle() const { return mOutlierStyle; } + + // setters: + void setKey(double key); + void setMinimum(double value); + void setLowerQuartile(double value); + void setMedian(double value); + void setUpperQuartile(double value); + void setMaximum(double value); + void setOutliers(const QVector &values); + void setData(double key, double minimum, double lowerQuartile, double median, double upperQuartile, double maximum); + void setWidth(double width); + void setWhiskerWidth(double width); + void setWhiskerPen(const QPen &pen); + void setWhiskerBarPen(const QPen &pen); + void setMedianPen(const QPen &pen); + void setOutlierStyle(const QCPScatterStyle &style); + + // non-property methods: + virtual void clearData(); + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + +protected: + // property members: + QVector mOutliers; + double mKey, mMinimum, mLowerQuartile, mMedian, mUpperQuartile, mMaximum; + double mWidth; + double mWhiskerWidth; + QPen mWhiskerPen, mWhiskerBarPen, mMedianPen; + QCPScatterStyle mOutlierStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; + virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + + // introduced virtual methods: + virtual void drawQuartileBox(QCPPainter *painter, QRectF *quartileBox=0) const; + virtual void drawMedian(QCPPainter *painter) const; + virtual void drawWhiskers(QCPPainter *painter) const; + virtual void drawOutliers(QCPPainter *painter) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + + +class QCP_LIB_DECL QCPColorMapData +{ +public: + QCPColorMapData(int keySize, int valueSize, const QCPRange &keyRange, const QCPRange &valueRange); + ~QCPColorMapData(); + QCPColorMapData(const QCPColorMapData &other); + QCPColorMapData &operator=(const QCPColorMapData &other); + + // getters: + int keySize() const { return mKeySize; } + int valueSize() const { return mValueSize; } + QCPRange keyRange() const { return mKeyRange; } + QCPRange valueRange() const { return mValueRange; } + QCPRange dataBounds() const { return mDataBounds; } + double data(double key, double value); + double cell(int keyIndex, int valueIndex); + + // setters: + void setSize(int keySize, int valueSize); + void setKeySize(int keySize); + void setValueSize(int valueSize); + void setRange(const QCPRange &keyRange, const QCPRange &valueRange); + void setKeyRange(const QCPRange &keyRange); + void setValueRange(const QCPRange &valueRange); + void setData(double key, double value, double z); + void setCell(int keyIndex, int valueIndex, double z); + + // non-property methods: + void recalculateDataBounds(); + void clear(); + void fill(double z); + bool isEmpty() const { return mIsEmpty; } + void coordToCell(double key, double value, int *keyIndex, int *valueIndex) const; + void cellToCoord(int keyIndex, int valueIndex, double *key, double *value) const; + +protected: + // property members: + int mKeySize, mValueSize; + QCPRange mKeyRange, mValueRange; + bool mIsEmpty; + // non-property members: + double *mData; + QCPRange mDataBounds; + bool mDataModified; + + friend class QCPColorMap; +}; + + +class QCP_LIB_DECL QCPColorMap : public QCPAbstractPlottable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged) + Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY dataScaleTypeChanged) + Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged) + Q_PROPERTY(bool interpolate READ interpolate WRITE setInterpolate) + Q_PROPERTY(bool tightBoundary READ tightBoundary WRITE setTightBoundary) + Q_PROPERTY(QCPColorScale* colorScale READ colorScale WRITE setColorScale) + /// \endcond +public: + explicit QCPColorMap(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPColorMap(); + + // getters: + QCPColorMapData *data() const { return mMapData; } + QCPRange dataRange() const { return mDataRange; } + QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; } + bool interpolate() const { return mInterpolate; } + bool tightBoundary() const { return mTightBoundary; } + QCPColorGradient gradient() const { return mGradient; } + QCPColorScale *colorScale() const { return mColorScale.data(); } + + // setters: + void setData(QCPColorMapData *data, bool copy=false); + Q_SLOT void setDataRange(const QCPRange &dataRange); + Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType); + Q_SLOT void setGradient(const QCPColorGradient &gradient); + void setInterpolate(bool enabled); + void setTightBoundary(bool enabled); + void setColorScale(QCPColorScale *colorScale); + + // non-property methods: + void rescaleDataRange(bool recalculateDataBounds=false); + Q_SLOT void updateLegendIcon(Qt::TransformationMode transformMode=Qt::SmoothTransformation, const QSize &thumbSize=QSize(32, 18)); + + // reimplemented virtual methods: + virtual void clearData(); + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + +signals: + void dataRangeChanged(QCPRange newRange); + void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); + void gradientChanged(QCPColorGradient newGradient); + +protected: + // property members: + QCPRange mDataRange; + QCPAxis::ScaleType mDataScaleType; + QCPColorMapData *mMapData; + QCPColorGradient mGradient; + bool mInterpolate; + bool mTightBoundary; + QPointer mColorScale; + // non-property members: + QImage mMapImage, mUndersampledMapImage; + QPixmap mLegendIcon; + bool mMapImageInvalidated; + + // introduced virtual methods: + virtual void updateMapImage(); + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; + virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + + +/*! \file */ + + + +class QCP_LIB_DECL QCPFinancialData +{ +public: + QCPFinancialData(); + QCPFinancialData(double key, double open, double high, double low, double close); + double key, open, high, low, close; +}; +Q_DECLARE_TYPEINFO(QCPFinancialData, Q_MOVABLE_TYPE); + +/*! \typedef QCPFinancialDataMap + Container for storing \ref QCPFinancialData items in a sorted fashion. The key of the map + is the key member of the QCPFinancialData instance. + + This is the container in which QCPFinancial holds its data. + \see QCPFinancial, QCPFinancial::setData +*/ +typedef QMap QCPFinancialDataMap; +typedef QMapIterator QCPFinancialDataMapIterator; +typedef QMutableMapIterator QCPFinancialDataMutableMapIterator; + + +class QCP_LIB_DECL QCPFinancial : public QCPAbstractPlottable +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(ChartStyle chartStyle READ chartStyle WRITE setChartStyle) + Q_PROPERTY(double width READ width WRITE setWidth) + Q_PROPERTY(bool twoColored READ twoColored WRITE setTwoColored) + Q_PROPERTY(QBrush brushPositive READ brushPositive WRITE setBrushPositive) + Q_PROPERTY(QBrush brushNegative READ brushNegative WRITE setBrushNegative) + Q_PROPERTY(QPen penPositive READ penPositive WRITE setPenPositive) + Q_PROPERTY(QPen penNegative READ penNegative WRITE setPenNegative) + /// \endcond +public: + /*! + Defines the possible representations of OHLC data in the plot. + + \see setChartStyle + */ + enum ChartStyle { csOhlc ///< Open-High-Low-Close bar representation + ,csCandlestick ///< Candlestick representation + }; + Q_ENUMS(ChartStyle) + + explicit QCPFinancial(QCPAxis *keyAxis, QCPAxis *valueAxis); + virtual ~QCPFinancial(); + + // getters: + QCPFinancialDataMap *data() const { return mData; } + ChartStyle chartStyle() const { return mChartStyle; } + double width() const { return mWidth; } + bool twoColored() const { return mTwoColored; } + QBrush brushPositive() const { return mBrushPositive; } + QBrush brushNegative() const { return mBrushNegative; } + QPen penPositive() const { return mPenPositive; } + QPen penNegative() const { return mPenNegative; } + + + // setters: + void setData(QCPFinancialDataMap *data, bool copy=false); + void setData(const QVector &key, const QVector &open, const QVector &high, const QVector &low, const QVector &close); + void setChartStyle(ChartStyle style); + void setWidth(double width); + void setTwoColored(bool twoColored); + void setBrushPositive(const QBrush &brush); + void setBrushNegative(const QBrush &brush); + void setPenPositive(const QPen &pen); + void setPenNegative(const QPen &pen); + + // non-property methods: + void addData(const QCPFinancialDataMap &dataMap); + void addData(const QCPFinancialData &data); + void addData(double key, double open, double high, double low, double close); + void addData(const QVector &key, const QVector &open, const QVector &high, const QVector &low, const QVector &close); + void removeDataBefore(double key); + void removeDataAfter(double key); + void removeData(double fromKey, double toKey); + void removeData(double key); + + // reimplemented virtual methods: + virtual void clearData(); + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + // static methods: + static QCPFinancialDataMap timeSeriesToOhlc(const QVector &time, const QVector &value, double timeBinSize, double timeBinOffset = 0); + +protected: + // property members: + QCPFinancialDataMap *mData; + ChartStyle mChartStyle; + double mWidth; + bool mTwoColored; + QBrush mBrushPositive, mBrushNegative; + QPen mPenPositive, mPenNegative; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const; + virtual QCPRange getKeyRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + virtual QCPRange getValueRange(bool &foundRange, SignDomain inSignDomain=sdBoth) const; + + // non-virtual methods: + void drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end); + void drawCandlestickPlot(QCPPainter *painter, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end); + double ohlcSelectTest(const QPointF &pos, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end) const; + double candlestickSelectTest(const QPointF &pos, const QCPFinancialDataMap::const_iterator &begin, const QCPFinancialDataMap::const_iterator &end) const; + void getVisibleDataBounds(QCPFinancialDataMap::const_iterator &lower, QCPFinancialDataMap::const_iterator &upper) const; + + friend class QCustomPlot; + friend class QCPLegend; +}; + + +class QCP_LIB_DECL QCPItemStraightLine : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + /// \endcond +public: + QCPItemStraightLine(QCustomPlot *parentPlot); + virtual ~QCPItemStraightLine(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + QCPItemPosition * const point1; + QCPItemPosition * const point2; + +protected: + // property members: + QPen mPen, mSelectedPen; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + + // non-virtual methods: + double distToStraightLine(const QVector2D &point1, const QVector2D &vec, const QVector2D &point) const; + QLineF getRectClippedStraightLine(const QVector2D &point1, const QVector2D &vec, const QRect &rect) const; + QPen mainPen() const; +}; + + +class QCP_LIB_DECL QCPItemLine : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) + Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) + /// \endcond +public: + QCPItemLine(QCustomPlot *parentPlot); + virtual ~QCPItemLine(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QCPLineEnding head() const { return mHead; } + QCPLineEnding tail() const { return mTail; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setHead(const QCPLineEnding &head); + void setTail(const QCPLineEnding &tail); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + QCPItemPosition * const start; + QCPItemPosition * const end; + +protected: + // property members: + QPen mPen, mSelectedPen; + QCPLineEnding mHead, mTail; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + + // non-virtual methods: + QLineF getRectClippedLine(const QVector2D &start, const QVector2D &end, const QRect &rect) const; + QPen mainPen() const; +}; + + +class QCP_LIB_DECL QCPItemCurve : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QCPLineEnding head READ head WRITE setHead) + Q_PROPERTY(QCPLineEnding tail READ tail WRITE setTail) + /// \endcond +public: + QCPItemCurve(QCustomPlot *parentPlot); + virtual ~QCPItemCurve(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QCPLineEnding head() const { return mHead; } + QCPLineEnding tail() const { return mTail; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setHead(const QCPLineEnding &head); + void setTail(const QCPLineEnding &tail); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + QCPItemPosition * const start; + QCPItemPosition * const startDir; + QCPItemPosition * const endDir; + QCPItemPosition * const end; + +protected: + // property members: + QPen mPen, mSelectedPen; + QCPLineEnding mHead, mTail; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + + // non-virtual methods: + QPen mainPen() const; +}; + + +class QCP_LIB_DECL QCPItemRect : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + /// \endcond +public: + QCPItemRect(QCustomPlot *parentPlot); + virtual ~QCPItemRect(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual QPointF anchorPixelPoint(int anchorId) const; + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; + + +class QCP_LIB_DECL QCPItemText : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QColor color READ color WRITE setColor) + Q_PROPERTY(QColor selectedColor READ selectedColor WRITE setSelectedColor) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(QFont font READ font WRITE setFont) + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont) + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(Qt::Alignment positionAlignment READ positionAlignment WRITE setPositionAlignment) + Q_PROPERTY(Qt::Alignment textAlignment READ textAlignment WRITE setTextAlignment) + Q_PROPERTY(double rotation READ rotation WRITE setRotation) + Q_PROPERTY(QMargins padding READ padding WRITE setPadding) + /// \endcond +public: + QCPItemText(QCustomPlot *parentPlot); + virtual ~QCPItemText(); + + // getters: + QColor color() const { return mColor; } + QColor selectedColor() const { return mSelectedColor; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + QFont font() const { return mFont; } + QFont selectedFont() const { return mSelectedFont; } + QString text() const { return mText; } + Qt::Alignment positionAlignment() const { return mPositionAlignment; } + Qt::Alignment textAlignment() const { return mTextAlignment; } + double rotation() const { return mRotation; } + QMargins padding() const { return mPadding; } + + // setters; + void setColor(const QColor &color); + void setSelectedColor(const QColor &color); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setFont(const QFont &font); + void setSelectedFont(const QFont &font); + void setText(const QString &text); + void setPositionAlignment(Qt::Alignment alignment); + void setTextAlignment(Qt::Alignment alignment); + void setRotation(double degrees); + void setPadding(const QMargins &padding); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + QCPItemPosition * const position; + QCPItemAnchor * const topLeft; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottomRight; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTopLeft, aiTop, aiTopRight, aiRight, aiBottomRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QColor mColor, mSelectedColor; + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + QFont mFont, mSelectedFont; + QString mText; + Qt::Alignment mPositionAlignment; + Qt::Alignment mTextAlignment; + double mRotation; + QMargins mPadding; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual QPointF anchorPixelPoint(int anchorId) const; + + // non-virtual methods: + QPointF getTextDrawPoint(const QPointF &pos, const QRectF &rect, Qt::Alignment positionAlignment) const; + QFont mainFont() const; + QColor mainColor() const; + QPen mainPen() const; + QBrush mainBrush() const; +}; + + +class QCP_LIB_DECL QCPItemEllipse : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + /// \endcond +public: + QCPItemEllipse(QCustomPlot *parentPlot); + virtual ~QCPItemEllipse(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const topLeftRim; + QCPItemAnchor * const top; + QCPItemAnchor * const topRightRim; + QCPItemAnchor * const right; + QCPItemAnchor * const bottomRightRim; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeftRim; + QCPItemAnchor * const left; + QCPItemAnchor * const center; + +protected: + enum AnchorIndex {aiTopLeftRim, aiTop, aiTopRightRim, aiRight, aiBottomRightRim, aiBottom, aiBottomLeftRim, aiLeft, aiCenter}; + + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual QPointF anchorPixelPoint(int anchorId) const; + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; + + +class QCP_LIB_DECL QCPItemPixmap : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap) + Q_PROPERTY(bool scaled READ scaled WRITE setScaled) + Q_PROPERTY(Qt::AspectRatioMode aspectRatioMode READ aspectRatioMode) + Q_PROPERTY(Qt::TransformationMode transformationMode READ transformationMode) + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + /// \endcond +public: + QCPItemPixmap(QCustomPlot *parentPlot); + virtual ~QCPItemPixmap(); + + // getters: + QPixmap pixmap() const { return mPixmap; } + bool scaled() const { return mScaled; } + Qt::AspectRatioMode aspectRatioMode() const { return mAspectRatioMode; } + Qt::TransformationMode transformationMode() const { return mTransformationMode; } + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + + // setters; + void setPixmap(const QPixmap &pixmap); + void setScaled(bool scaled, Qt::AspectRatioMode aspectRatioMode=Qt::KeepAspectRatio, Qt::TransformationMode transformationMode=Qt::SmoothTransformation); + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + QCPItemPosition * const topLeft; + QCPItemPosition * const bottomRight; + QCPItemAnchor * const top; + QCPItemAnchor * const topRight; + QCPItemAnchor * const right; + QCPItemAnchor * const bottom; + QCPItemAnchor * const bottomLeft; + QCPItemAnchor * const left; + +protected: + enum AnchorIndex {aiTop, aiTopRight, aiRight, aiBottom, aiBottomLeft, aiLeft}; + + // property members: + QPixmap mPixmap; + QPixmap mScaledPixmap; + bool mScaled; + bool mScaledPixmapInvalidated; + Qt::AspectRatioMode mAspectRatioMode; + Qt::TransformationMode mTransformationMode; + QPen mPen, mSelectedPen; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual QPointF anchorPixelPoint(int anchorId) const; + + // non-virtual methods: + void updateScaledPixmap(QRect finalRect=QRect(), bool flipHorz=false, bool flipVert=false); + QRect getFinalRect(bool *flippedHorz=0, bool *flippedVert=0) const; + QPen mainPen() const; +}; + + +class QCP_LIB_DECL QCPItemTracer : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(QBrush brush READ brush WRITE setBrush) + Q_PROPERTY(QBrush selectedBrush READ selectedBrush WRITE setSelectedBrush) + Q_PROPERTY(double size READ size WRITE setSize) + Q_PROPERTY(TracerStyle style READ style WRITE setStyle) + Q_PROPERTY(QCPGraph* graph READ graph WRITE setGraph) + Q_PROPERTY(double graphKey READ graphKey WRITE setGraphKey) + Q_PROPERTY(bool interpolating READ interpolating WRITE setInterpolating) + /// \endcond +public: + /*! + The different visual appearances a tracer item can have. Some styles size may be controlled with \ref setSize. + + \see setStyle + */ + enum TracerStyle { tsNone ///< The tracer is not visible + ,tsPlus ///< A plus shaped crosshair with limited size + ,tsCrosshair ///< A plus shaped crosshair which spans the complete axis rect + ,tsCircle ///< A circle + ,tsSquare ///< A square + }; + Q_ENUMS(TracerStyle) + + QCPItemTracer(QCustomPlot *parentPlot); + virtual ~QCPItemTracer(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + QBrush brush() const { return mBrush; } + QBrush selectedBrush() const { return mSelectedBrush; } + double size() const { return mSize; } + TracerStyle style() const { return mStyle; } + QCPGraph *graph() const { return mGraph; } + double graphKey() const { return mGraphKey; } + bool interpolating() const { return mInterpolating; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setBrush(const QBrush &brush); + void setSelectedBrush(const QBrush &brush); + void setSize(double size); + void setStyle(TracerStyle style); + void setGraph(QCPGraph *graph); + void setGraphKey(double key); + void setInterpolating(bool enabled); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + // non-virtual methods: + void updatePosition(); + + QCPItemPosition * const position; + +protected: + // property members: + QPen mPen, mSelectedPen; + QBrush mBrush, mSelectedBrush; + double mSize; + TracerStyle mStyle; + QCPGraph *mGraph; + double mGraphKey; + bool mInterpolating; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + + // non-virtual methods: + QPen mainPen() const; + QBrush mainBrush() const; +}; + + +class QCP_LIB_DECL QCPItemBracket : public QCPAbstractItem +{ + Q_OBJECT + /// \cond INCLUDE_QPROPERTIES + Q_PROPERTY(QPen pen READ pen WRITE setPen) + Q_PROPERTY(QPen selectedPen READ selectedPen WRITE setSelectedPen) + Q_PROPERTY(double length READ length WRITE setLength) + Q_PROPERTY(BracketStyle style READ style WRITE setStyle) + /// \endcond +public: + enum BracketStyle { bsSquare ///< A brace with angled edges + ,bsRound ///< A brace with round edges + ,bsCurly ///< A curly brace + ,bsCalligraphic ///< A curly brace with varying stroke width giving a calligraphic impression + }; + + QCPItemBracket(QCustomPlot *parentPlot); + virtual ~QCPItemBracket(); + + // getters: + QPen pen() const { return mPen; } + QPen selectedPen() const { return mSelectedPen; } + double length() const { return mLength; } + BracketStyle style() const { return mStyle; } + + // setters; + void setPen(const QPen &pen); + void setSelectedPen(const QPen &pen); + void setLength(double length); + void setStyle(BracketStyle style); + + // reimplemented virtual methods: + virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details=0) const; + + QCPItemPosition * const left; + QCPItemPosition * const right; + QCPItemAnchor * const center; + +protected: + // property members: + enum AnchorIndex {aiCenter}; + QPen mPen, mSelectedPen; + double mLength; + BracketStyle mStyle; + + // reimplemented virtual methods: + virtual void draw(QCPPainter *painter); + virtual QPointF anchorPixelPoint(int anchorId) const; + + // non-virtual methods: + QPen mainPen() const; +}; + +#endif // QCUSTOMPLOT_H +