qcustomplot.h
7219 lines
| 276.2 KiB
| text/x-c
|
CLexer
r59 | /*************************************************************************** | |||
** ** | ||||
** QCustomPlot, an easy to use, modern plotting widget for Qt ** | ||||
** Copyright (C) 2011-2016 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: 13.09.16 ** | ||||
** Version: 2.0.0-beta ** | ||||
****************************************************************************/ | ||||
#ifndef QCUSTOMPLOT_H | ||||
#define QCUSTOMPLOT_H | ||||
#include <QtCore/qglobal.h> | ||||
// some Qt version/configuration dependent macros to include or exclude certain code paths: | ||||
#ifdef QCUSTOMPLOT_USE_OPENGL | ||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) | ||||
#define QCP_OPENGL_PBUFFER | ||||
#else | ||||
#define QCP_OPENGL_FBO | ||||
#endif | ||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0) | ||||
#define QCP_OPENGL_OFFSCREENSURFACE | ||||
#endif | ||||
#endif | ||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0) | ||||
#define QCP_DEVICEPIXELRATIO_SUPPORTED | ||||
r610 | #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) | |||
#define QCP_DEVICEPIXELRATIO_FLOAT | ||||
#endif | ||||
r59 | #endif | |||
#include <QtCore/QCache> | ||||
#include <QtCore/QDateTime> | ||||
#include <QtCore/QDebug> | ||||
#include <QtCore/QFlags> | ||||
#include <QtCore/QMargins> | ||||
#include <QtCore/QMultiMap> | ||||
#include <QtCore/QObject> | ||||
#include <QtCore/QPointer> | ||||
#include <QtCore/QSharedPointer> | ||||
#include <QtCore/QStack> | ||||
#include <QtCore/QString> | ||||
#include <QtCore/QTimer> | ||||
#include <QtCore/QVector> | ||||
#include <QtGui/QMouseEvent> | ||||
#include <QtGui/QPaintEvent> | ||||
#include <QtGui/QPainter> | ||||
#include <QtGui/QPixmap> | ||||
#include <QtGui/QWheelEvent> | ||||
#include <algorithm> | ||||
#include <limits> | ||||
#include <qmath.h> | ||||
#ifdef QCP_OPENGL_FBO | ||||
#include <QtGui/QOpenGLContext> | ||||
#include <QtGui/QOpenGLFramebufferObject> | ||||
#ifdef QCP_OPENGL_OFFSCREENSURFACE | ||||
#include <QtGui/QOffscreenSurface> | ||||
#else | ||||
#include <QtGui/QWindow> | ||||
#endif | ||||
#endif | ||||
#ifdef QCP_OPENGL_PBUFFER | ||||
#include <QtOpenGL/QGLPixelBuffer> | ||||
#endif | ||||
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) | ||||
#include <QtGui/QPrintEngine> | ||||
#include <QtGui/QPrinter> | ||||
#include <QtGui/QWidget> | ||||
#include <qnumeric.h> | ||||
#else | ||||
#include <QtNumeric> | ||||
#include <QtPrintSupport/QtPrintSupport> | ||||
#include <QtWidgets/QWidget> | ||||
#endif | ||||
class QCPPainter; | ||||
class QCustomPlot; | ||||
class QCPLayerable; | ||||
class QCPLayoutElement; | ||||
class QCPLayout; | ||||
class QCPAxis; | ||||
class QCPAxisRect; | ||||
class QCPAxisPainterPrivate; | ||||
class QCPAbstractPlottable; | ||||
class QCPGraph; | ||||
class QCPAbstractItem; | ||||
class QCPPlottableInterface1D; | ||||
class QCPLegend; | ||||
class QCPItemPosition; | ||||
class QCPLayer; | ||||
class QCPAbstractLegendItem; | ||||
class QCPSelectionRect; | ||||
class QCPColorMap; | ||||
class QCPColorScale; | ||||
class QCPBars; | ||||
r610 | /* including file 'src/global.h', size 16225 */ | |||
/* commit e7c6a5540d344a96d107dce53f9d4414a09a7320 2017-07-25 00:52:29 +0200 */ | ||||
r59 | ||||
// decl definitions for shared library compilation/usage: | ||||
#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 | ||||
// define empty macro for Q_DECL_OVERRIDE if it doesn't exist (Qt < 5) | ||||
#ifndef Q_DECL_OVERRIDE | ||||
#define Q_DECL_OVERRIDE | ||||
#endif | ||||
/*! | ||||
The QCP Namespace contains general enums, QFlags and functions used throughout the QCustomPlot | ||||
library. | ||||
It provides QMetaObject-based reflection of its enums and flags via \a QCP::staticMetaObject. | ||||
*/ | ||||
#ifndef Q_MOC_RUN | ||||
namespace QCP { | ||||
#else | ||||
class QCP { // when in moc-run, make it look like a class, so we get Q_GADGET, Q_ENUMS/Q_FLAGS | ||||
// features in namespace | ||||
Q_GADGET | ||||
Q_ENUMS(ExportPen) | ||||
Q_ENUMS(ResolutionUnit) | ||||
Q_ENUMS(SignDomain) | ||||
Q_ENUMS(MarginSide) | ||||
Q_FLAGS(MarginSides) | ||||
Q_ENUMS(AntialiasedElement) | ||||
Q_FLAGS(AntialiasedElements) | ||||
Q_ENUMS(PlottingHint) | ||||
Q_FLAGS(PlottingHints) | ||||
Q_ENUMS(Interaction) | ||||
Q_FLAGS(Interactions) | ||||
Q_ENUMS(SelectionRectMode) | ||||
Q_ENUMS(SelectionType) | ||||
public: | ||||
#endif | ||||
/*! | ||||
Defines the different units in which the image resolution can be specified in the export | ||||
functions. | ||||
\see QCustomPlot::savePng, QCustomPlot::saveJpg, QCustomPlot::saveBmp, QCustomPlot::saveRastered | ||||
*/ | ||||
enum ResolutionUnit { | ||||
ruDotsPerMeter ///< Resolution is given in dots per meter (dpm) | ||||
, | ||||
ruDotsPerCentimeter ///< Resolution is given in dots per centimeter (dpcm) | ||||
, | ||||
ruDotsPerInch ///< Resolution is given in dots per inch (DPI/PPI) | ||||
}; | ||||
/*! | ||||
Defines how cosmetic pens (pens with numerical width 0) are handled during export. | ||||
\see QCustomPlot::savePdf | ||||
*/ | ||||
enum ExportPen { | ||||
epNoCosmetic ///< Cosmetic pens are converted to pens with pixel width 1 when exporting | ||||
, | ||||
epAllowCosmetic ///< Cosmetic pens are exported normally (e.g. in PDF exports, cosmetic pens | ||||
/// always appear as 1 pixel on screen, independent of viewer zoom level) | ||||
}; | ||||
/*! | ||||
Represents negative and positive sign domain, e.g. for passing to \ref | ||||
QCPAbstractPlottable::getKeyRange and \ref QCPAbstractPlottable::getValueRange. | ||||
This is primarily needed when working with logarithmic axis scales, since only one of the sign | ||||
domains can be visible at a time. | ||||
*/ | ||||
enum SignDomain { | ||||
sdNegative ///< The negative sign domain, i.e. numbers smaller than zero | ||||
, | ||||
sdBoth ///< Both sign domains, including zero, i.e. all numbers | ||||
, | ||||
sdPositive ///< The positive sign domain, i.e. numbers greater than zero | ||||
}; | ||||
/*! | ||||
Defines the sides of a rectangular entity to which margins can be applied. | ||||
\see QCPLayoutElement::setAutoMargins, QCPAxisRect::setAutoMargins | ||||
*/ | ||||
enum MarginSide { | ||||
msLeft = 0x01 ///< <tt>0x01</tt> left margin | ||||
, | ||||
msRight = 0x02 ///< <tt>0x02</tt> right margin | ||||
, | ||||
msTop = 0x04 ///< <tt>0x04</tt> top margin | ||||
, | ||||
msBottom = 0x08 ///< <tt>0x08</tt> bottom margin | ||||
, | ||||
msAll = 0xFF ///< <tt>0xFF</tt> all margins | ||||
, | ||||
msNone = 0x00 ///< <tt>0x00</tt> 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 ///< <tt>0x0001</tt> Axis base line and tick marks | ||||
, | ||||
aeGrid = 0x0002 ///< <tt>0x0002</tt> Grid lines | ||||
, | ||||
aeSubGrid = 0x0004 ///< <tt>0x0004</tt> Sub grid lines | ||||
, | ||||
aeLegend = 0x0008 ///< <tt>0x0008</tt> Legend box | ||||
, | ||||
aeLegendItems = 0x0010 ///< <tt>0x0010</tt> Legend items | ||||
, | ||||
aePlottables = 0x0020 ///< <tt>0x0020</tt> Main lines of plottables | ||||
, | ||||
aeItems = 0x0040 ///< <tt>0x0040</tt> Main lines of items | ||||
, | ||||
aeScatters = 0x0080 ///< <tt>0x0080</tt> Scatter symbols of plottables (excluding scatter | ||||
/// symbols of type ssPixmap) | ||||
, | ||||
aeFills = 0x0100 ///< <tt>0x0100</tt> Borders of fills (e.g. under or between graphs) | ||||
, | ||||
aeZeroLine = 0x0200 ///< <tt>0x0200</tt> Zero-lines, see \ref QCPGrid::setZeroLinePen | ||||
, | ||||
aeOther | ||||
= 0x8000 ///< <tt>0x8000</tt> Other elements that don't fit into any of the existing categories | ||||
, | ||||
aeAll = 0xFFFF ///< <tt>0xFFFF</tt> All elements | ||||
, | ||||
aeNone = 0x0000 ///< <tt>0x0000</tt> 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 ///< <tt>0x000</tt> No hints are set | ||||
, | ||||
phFastPolylines = 0x001 ///< <tt>0x001</tt> Graph/Curve lines are drawn with a faster method. | ||||
/// This reduces the quality especially of the line segment | ||||
///< joins, thus is most effective for pen sizes larger than 1. It is only used | ||||
/// for solid line pens. | ||||
, | ||||
phImmediateRefresh = 0x002 ///< <tt>0x002</tt> causes an immediate repaint() instead of a soft | ||||
/// update() when QCustomPlot::replot() is called with parameter \ref | ||||
/// QCustomPlot::rpRefreshHint. | ||||
///< This is set by default to prevent the plot from freezing on fast consecutive | ||||
/// replots (e.g. user drags ranges with mouse). | ||||
, | ||||
phCacheLabels = 0x004 ///< <tt>0x004</tt> 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 ///< <tt>0x001</tt> Axis ranges are draggable (see \ref | ||||
/// QCPAxisRect::setRangeDrag, \ref QCPAxisRect::setRangeDragAxes) | ||||
, | ||||
iRangeZoom = 0x002 ///< <tt>0x002</tt> Axis ranges are zoomable with the mouse wheel (see \ref | ||||
/// QCPAxisRect::setRangeZoom, \ref QCPAxisRect::setRangeZoomAxes) | ||||
, | ||||
iMultiSelect = 0x004 ///< <tt>0x004</tt> The user can select multiple objects by holding the | ||||
/// modifier set by \ref QCustomPlot::setMultiSelectModifier while clicking | ||||
, | ||||
iSelectPlottables = 0x008 ///< <tt>0x008</tt> Plottables are selectable (e.g. graphs, curves, | ||||
/// bars,... see QCPAbstractPlottable) | ||||
, | ||||
iSelectAxes = 0x010 ///< <tt>0x010</tt> Axes are selectable (or parts of them, see | ||||
/// QCPAxis::setSelectableParts) | ||||
, | ||||
iSelectLegend = 0x020 ///< <tt>0x020</tt> Legends are selectable (or their child items, see | ||||
/// QCPLegend::setSelectableParts) | ||||
, | ||||
iSelectItems = 0x040 ///< <tt>0x040</tt> Items are selectable (Rectangles, Arrows, Textitems, | ||||
/// etc. see \ref QCPAbstractItem) | ||||
, | ||||
iSelectOther = 0x080 ///< <tt>0x080</tt> All other objects are selectable (e.g. your own derived | ||||
/// layerables, other layout elements,...) | ||||
}; | ||||
Q_DECLARE_FLAGS(Interactions, Interaction) | ||||
/*! | ||||
Defines the behaviour of the selection rect. | ||||
\see QCustomPlot::setSelectionRectMode, QCustomPlot::selectionRect, QCPSelectionRect | ||||
*/ | ||||
enum SelectionRectMode { | ||||
srmNone ///< The selection rect is disabled, and all mouse events are forwarded to the | ||||
/// underlying objects, e.g. for axis range dragging | ||||
, | ||||
srmZoom ///< When dragging the mouse, a selection rect becomes active. Upon releasing, the axes | ||||
/// that are currently set as range zoom axes (\ref QCPAxisRect::setRangeZoomAxes) will | ||||
/// have their ranges zoomed accordingly. | ||||
, | ||||
srmSelect ///< When dragging the mouse, a selection rect becomes active. Upon releasing, | ||||
/// plottable data points that were within the selection rect are selected, if the | ||||
/// plottable's selectability setting permits. (See \ref dataselection "data selection | ||||
/// mechanism" for details.) | ||||
, | ||||
srmCustom ///< When dragging the mouse, a selection rect becomes active. It is the programmer's | ||||
/// responsibility to connect according slots to the selection rect's signals (e.g. | ||||
///\ref QCPSelectionRect::accepted) in order to process the user interaction. | ||||
}; | ||||
/*! | ||||
Defines the different ways a plottable can be selected. These images show the effect of the | ||||
different selection types, when the indicated selection rect was dragged: | ||||
<center> | ||||
<table> | ||||
<tr> | ||||
<td>\image html selectiontype-none.png stNone</td> | ||||
<td>\image html selectiontype-whole.png stWhole</td> | ||||
<td>\image html selectiontype-singledata.png stSingleData</td> | ||||
<td>\image html selectiontype-datarange.png stDataRange</td> | ||||
<td>\image html selectiontype-multipledataranges.png stMultipleDataRanges</td> | ||||
</tr> | ||||
</table> | ||||
</center> | ||||
\see QCPAbstractPlottable::setSelectable, QCPDataSelection::enforceType | ||||
*/ | ||||
enum SelectionType { | ||||
stNone ///< The plottable is not selectable | ||||
, | ||||
stWhole ///< Selection behaves like \ref stMultipleDataRanges, but if there are any data points | ||||
/// selected, the entire plottable is drawn as selected. | ||||
, | ||||
stSingleData ///< One individual data point can be selected at a time | ||||
, | ||||
stDataRange ///< Multiple contiguous data points (a data range) can be selected | ||||
, | ||||
stMultipleDataRanges ///< Any combination of data points/ranges can be selected | ||||
}; | ||||
/*! \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; | ||||
} | ||||
extern const QMetaObject staticMetaObject; // in moc-run we create a static meta object for QCP | ||||
// "fake" object. This line is the link to it via | ||||
// QCP::staticMetaObject in normal operation as namespace | ||||
} // 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) | ||||
Q_DECLARE_METATYPE(QCP::ExportPen) | ||||
Q_DECLARE_METATYPE(QCP::ResolutionUnit) | ||||
Q_DECLARE_METATYPE(QCP::SignDomain) | ||||
Q_DECLARE_METATYPE(QCP::MarginSide) | ||||
Q_DECLARE_METATYPE(QCP::AntialiasedElement) | ||||
Q_DECLARE_METATYPE(QCP::PlottingHint) | ||||
Q_DECLARE_METATYPE(QCP::Interaction) | ||||
Q_DECLARE_METATYPE(QCP::SelectionRectMode) | ||||
Q_DECLARE_METATYPE(QCP::SelectionType) | ||||
/* end of 'src/global.h' */ | ||||
/* including file 'src/vector2d.h', size 4928 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
class QCP_LIB_DECL QCPVector2D { | ||||
public: | ||||
QCPVector2D(); | ||||
QCPVector2D(double x, double y); | ||||
QCPVector2D(const QPoint &point); | ||||
QCPVector2D(const QPointF &point); | ||||
// getters: | ||||
double x() const { return mX; } | ||||
double y() const { return mY; } | ||||
double &rx() { return mX; } | ||||
double &ry() { return mY; } | ||||
// setters: | ||||
void setX(double x) { mX = x; } | ||||
void setY(double y) { mY = y; } | ||||
// non-virtual methods: | ||||
double length() const { return qSqrt(mX * mX + mY * mY); } | ||||
double lengthSquared() const { return mX * mX + mY * mY; } | ||||
QPoint toPoint() const { return QPoint(mX, mY); } | ||||
QPointF toPointF() const { return QPointF(mX, mY); } | ||||
bool isNull() const { return qIsNull(mX) && qIsNull(mY); } | ||||
void normalize(); | ||||
QCPVector2D normalized() const; | ||||
QCPVector2D perpendicular() const { return QCPVector2D(-mY, mX); } | ||||
double dot(const QCPVector2D &vec) const { return mX * vec.mX + mY * vec.mY; } | ||||
double distanceSquaredToLine(const QCPVector2D &start, const QCPVector2D &end) const; | ||||
double distanceSquaredToLine(const QLineF &line) const; | ||||
double distanceToStraightLine(const QCPVector2D &base, const QCPVector2D &direction) const; | ||||
QCPVector2D &operator*=(double factor); | ||||
QCPVector2D &operator/=(double divisor); | ||||
QCPVector2D &operator+=(const QCPVector2D &vector); | ||||
QCPVector2D &operator-=(const QCPVector2D &vector); | ||||
private: | ||||
// property members: | ||||
double mX, mY; | ||||
friend inline const QCPVector2D operator*(double factor, const QCPVector2D &vec); | ||||
friend inline const QCPVector2D operator*(const QCPVector2D &vec, double factor); | ||||
friend inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor); | ||||
friend inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2); | ||||
friend inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2); | ||||
friend inline const QCPVector2D operator-(const QCPVector2D &vec); | ||||
}; | ||||
Q_DECLARE_TYPEINFO(QCPVector2D, Q_MOVABLE_TYPE); | ||||
inline const QCPVector2D operator*(double factor, const QCPVector2D &vec) | ||||
{ | ||||
return QCPVector2D(vec.mX * factor, vec.mY * factor); | ||||
} | ||||
inline const QCPVector2D operator*(const QCPVector2D &vec, double factor) | ||||
{ | ||||
return QCPVector2D(vec.mX * factor, vec.mY * factor); | ||||
} | ||||
inline const QCPVector2D operator/(const QCPVector2D &vec, double divisor) | ||||
{ | ||||
return QCPVector2D(vec.mX / divisor, vec.mY / divisor); | ||||
} | ||||
inline const QCPVector2D operator+(const QCPVector2D &vec1, const QCPVector2D &vec2) | ||||
{ | ||||
return QCPVector2D(vec1.mX + vec2.mX, vec1.mY + vec2.mY); | ||||
} | ||||
inline const QCPVector2D operator-(const QCPVector2D &vec1, const QCPVector2D &vec2) | ||||
{ | ||||
return QCPVector2D(vec1.mX - vec2.mX, vec1.mY - vec2.mY); | ||||
} | ||||
inline const QCPVector2D operator-(const QCPVector2D &vec) | ||||
{ | ||||
return QCPVector2D(-vec.mX, -vec.mY); | ||||
} | ||||
/*! \relates QCPVector2D | ||||
Prints \a vec in a human readable format to the qDebug output. | ||||
*/ | ||||
inline QDebug operator<<(QDebug d, const QCPVector2D &vec) | ||||
{ | ||||
d.nospace() << "QCPVector2D(" << vec.x() << ", " << vec.y() << ")"; | ||||
return d.space(); | ||||
} | ||||
/* end of 'src/vector2d.h' */ | ||||
/* including file 'src/painter.h', size 4035 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
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 ///< <tt>0x00</tt> Default mode for painting on screen devices | ||||
, | ||||
pmVectorized = 0x01 ///< <tt>0x01</tt> Mode for vectorized painting (e.g. PDF export). For | ||||
/// example, this prevents some antialiasing fixes. | ||||
, | ||||
pmNoCaching = 0x02 ///< <tt>0x02</tt> Mode for all sorts of exports (e.g. PNG, PDF,...). For | ||||
/// example, this prevents using cached pixmap labels | ||||
, | ||||
pmNonCosmetic = 0x04 ///< <tt>0x04</tt> Turns pen widths 0 to 1, i.e. disables cosmetic | ||||
/// pens. (A cosmetic pen is always drawn with width 1 pixel in the | ||||
/// vector image/pdf viewer, independent of zoom.) | ||||
}; | ||||
Q_ENUMS(PainterMode) | ||||
Q_FLAGS(PainterModes) | ||||
Q_DECLARE_FLAGS(PainterModes, PainterMode) | ||||
QCPPainter(); | ||||
explicit QCPPainter(QPaintDevice *device); | ||||
// 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<bool> mAntialiasingStack; | ||||
}; | ||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QCPPainter::PainterModes) | ||||
Q_DECLARE_METATYPE(QCPPainter::PainterMode) | ||||
/* end of 'src/painter.h' */ | ||||
/* including file 'src/paintbuffer.h', size 4958 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
class QCP_LIB_DECL QCPAbstractPaintBuffer { | ||||
public: | ||||
explicit QCPAbstractPaintBuffer(const QSize &size, double devicePixelRatio); | ||||
virtual ~QCPAbstractPaintBuffer(); | ||||
// getters: | ||||
QSize size() const { return mSize; } | ||||
bool invalidated() const { return mInvalidated; } | ||||
double devicePixelRatio() const { return mDevicePixelRatio; } | ||||
// setters: | ||||
void setSize(const QSize &size); | ||||
void setInvalidated(bool invalidated = true); | ||||
void setDevicePixelRatio(double ratio); | ||||
// introduced virtual methods: | ||||
virtual QCPPainter *startPainting() = 0; | ||||
virtual void donePainting() {} | ||||
virtual void draw(QCPPainter *painter) const = 0; | ||||
virtual void clear(const QColor &color) = 0; | ||||
protected: | ||||
// property members: | ||||
QSize mSize; | ||||
double mDevicePixelRatio; | ||||
// non-property members: | ||||
bool mInvalidated; | ||||
// introduced virtual methods: | ||||
virtual void reallocateBuffer() = 0; | ||||
}; | ||||
class QCP_LIB_DECL QCPPaintBufferPixmap : public QCPAbstractPaintBuffer { | ||||
public: | ||||
explicit QCPPaintBufferPixmap(const QSize &size, double devicePixelRatio); | ||||
virtual ~QCPPaintBufferPixmap(); | ||||
// reimplemented virtual methods: | ||||
virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; | ||||
virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; | ||||
void clear(const QColor &color) Q_DECL_OVERRIDE; | ||||
protected: | ||||
// non-property members: | ||||
QPixmap mBuffer; | ||||
// reimplemented virtual methods: | ||||
virtual void reallocateBuffer() Q_DECL_OVERRIDE; | ||||
}; | ||||
#ifdef QCP_OPENGL_PBUFFER | ||||
class QCP_LIB_DECL QCPPaintBufferGlPbuffer : public QCPAbstractPaintBuffer { | ||||
public: | ||||
explicit QCPPaintBufferGlPbuffer(const QSize &size, double devicePixelRatio, int multisamples); | ||||
virtual ~QCPPaintBufferGlPbuffer(); | ||||
// reimplemented virtual methods: | ||||
virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; | ||||
virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; | ||||
void clear(const QColor &color) Q_DECL_OVERRIDE; | ||||
protected: | ||||
// non-property members: | ||||
QGLPixelBuffer *mGlPBuffer; | ||||
int mMultisamples; | ||||
// reimplemented virtual methods: | ||||
virtual void reallocateBuffer() Q_DECL_OVERRIDE; | ||||
}; | ||||
#endif // QCP_OPENGL_PBUFFER | ||||
#ifdef QCP_OPENGL_FBO | ||||
class QCP_LIB_DECL QCPPaintBufferGlFbo : public QCPAbstractPaintBuffer { | ||||
public: | ||||
explicit QCPPaintBufferGlFbo(const QSize &size, double devicePixelRatio, | ||||
QWeakPointer<QOpenGLContext> glContext, | ||||
QWeakPointer<QOpenGLPaintDevice> glPaintDevice); | ||||
virtual ~QCPPaintBufferGlFbo(); | ||||
// reimplemented virtual methods: | ||||
virtual QCPPainter *startPainting() Q_DECL_OVERRIDE; | ||||
virtual void donePainting() Q_DECL_OVERRIDE; | ||||
virtual void draw(QCPPainter *painter) const Q_DECL_OVERRIDE; | ||||
void clear(const QColor &color) Q_DECL_OVERRIDE; | ||||
protected: | ||||
// non-property members: | ||||
QWeakPointer<QOpenGLContext> mGlContext; | ||||
QWeakPointer<QOpenGLPaintDevice> mGlPaintDevice; | ||||
QOpenGLFramebufferObject *mGlFrameBuffer; | ||||
// reimplemented virtual methods: | ||||
virtual void reallocateBuffer() Q_DECL_OVERRIDE; | ||||
}; | ||||
#endif // QCP_OPENGL_FBO | ||||
/* end of 'src/paintbuffer.h' */ | ||||
/* including file 'src/layer.h', size 6885 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
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<QCPLayerable *> children READ children) | ||||
Q_PROPERTY(bool visible READ visible WRITE setVisible) | ||||
Q_PROPERTY(LayerMode mode READ mode WRITE setMode) | ||||
/// \endcond | ||||
public: | ||||
/*! | ||||
Defines the different rendering modes of a layer. Depending on the mode, certain layers can be | ||||
replotted individually, without the need to replot (possibly complex) layerables on other | ||||
layers. | ||||
\see setMode | ||||
*/ | ||||
enum LayerMode { | ||||
lmLogical ///< Layer is used only for rendering order, and shares paint buffer with all | ||||
/// other adjacent logical layers. | ||||
, | ||||
lmBuffered ///< Layer has its own paint buffer and may be replotted individually (see \ref | ||||
/// replot). | ||||
}; | ||||
Q_ENUMS(LayerMode) | ||||
QCPLayer(QCustomPlot *parentPlot, const QString &layerName); | ||||
virtual ~QCPLayer(); | ||||
// getters: | ||||
QCustomPlot *parentPlot() const { return mParentPlot; } | ||||
QString name() const { return mName; } | ||||
int index() const { return mIndex; } | ||||
QList<QCPLayerable *> children() const { return mChildren; } | ||||
bool visible() const { return mVisible; } | ||||
LayerMode mode() const { return mMode; } | ||||
// setters: | ||||
void setVisible(bool visible); | ||||
void setMode(LayerMode mode); | ||||
// non-virtual methods: | ||||
void replot(); | ||||
protected: | ||||
// property members: | ||||
QCustomPlot *mParentPlot; | ||||
QString mName; | ||||
int mIndex; | ||||
QList<QCPLayerable *> mChildren; | ||||
bool mVisible; | ||||
LayerMode mMode; | ||||
// non-property members: | ||||
QWeakPointer<QCPAbstractPaintBuffer> mPaintBuffer; | ||||
// non-virtual methods: | ||||
void draw(QCPPainter *painter); | ||||
void drawToPaintBuffer(); | ||||
void addChild(QCPLayerable *layerable, bool prepend); | ||||
void removeChild(QCPLayerable *layerable); | ||||
private: | ||||
Q_DISABLE_COPY(QCPLayer) | ||||
friend class QCustomPlot; | ||||
friend class QCPLayerable; | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPLayer::LayerMode) | ||||
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); | ||||
virtual ~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<QCPLayerable> 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; | ||||
// selection events: | ||||
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, | ||||
bool *selectionStateChanged); | ||||
virtual void deselectEvent(bool *selectionStateChanged); | ||||
// low-level mouse events: | ||||
virtual void mousePressEvent(QMouseEvent *event, const QVariant &details); | ||||
virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); | ||||
virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos); | ||||
virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details); | ||||
virtual void wheelEvent(QWheelEvent *event); | ||||
// 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 QCPLayer; | ||||
friend class QCPAxisRect; | ||||
}; | ||||
/* end of 'src/layer.h' */ | ||||
/* including file 'src/axis/range.h', size 5280 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
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 { return upper - lower; } | ||||
double center() const { return (upper + lower) * 0.5; } | ||||
void normalize() | ||||
{ | ||||
if (lower > upper) | ||||
qSwap(lower, upper); | ||||
} | ||||
void expand(const QCPRange &otherRange); | ||||
void expand(double includeCoord); | ||||
QCPRange expanded(const QCPRange &otherRange) const; | ||||
QCPRange expanded(double includeCoord) const; | ||||
QCPRange bounded(double lowerBound, double upperBound) const; | ||||
QCPRange sanitizedForLogScale() const; | ||||
QCPRange sanitizedForLinScale() const; | ||||
bool contains(double value) const { return value >= lower && value <= upper; } | ||||
static bool validRange(double lower, double upper); | ||||
static bool validRange(const QCPRange &range); | ||||
static const double minRange; | ||||
static const double maxRange; | ||||
}; | ||||
Q_DECLARE_TYPEINFO(QCPRange, Q_MOVABLE_TYPE); | ||||
/*! \relates QCPRange | ||||
Prints \a range in a human readable format to the qDebug output. | ||||
*/ | ||||
inline QDebug operator<<(QDebug d, const QCPRange &range) | ||||
{ | ||||
d.nospace() << "QCPRange(" << range.lower << ", " << range.upper << ")"; | ||||
return d.space(); | ||||
} | ||||
/*! | ||||
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; | ||||
} | ||||
/* end of 'src/axis/range.h' */ | ||||
/* including file 'src/selection.h', size 8579 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
class QCP_LIB_DECL QCPDataRange { | ||||
public: | ||||
QCPDataRange(); | ||||
QCPDataRange(int begin, int end); | ||||
bool operator==(const QCPDataRange &other) const | ||||
{ | ||||
return mBegin == other.mBegin && mEnd == other.mEnd; | ||||
} | ||||
bool operator!=(const QCPDataRange &other) const { return !(*this == other); } | ||||
// getters: | ||||
int begin() const { return mBegin; } | ||||
int end() const { return mEnd; } | ||||
int size() const { return mEnd - mBegin; } | ||||
int length() const { return size(); } | ||||
// setters: | ||||
void setBegin(int begin) { mBegin = begin; } | ||||
void setEnd(int end) { mEnd = end; } | ||||
// non-property methods: | ||||
bool isValid() const { return (mEnd >= mBegin) && (mBegin >= 0); } | ||||
bool isEmpty() const { return length() == 0; } | ||||
QCPDataRange bounded(const QCPDataRange &other) const; | ||||
QCPDataRange expanded(const QCPDataRange &other) const; | ||||
QCPDataRange intersection(const QCPDataRange &other) const; | ||||
QCPDataRange adjusted(int changeBegin, int changeEnd) const | ||||
{ | ||||
return QCPDataRange(mBegin + changeBegin, mEnd + changeEnd); | ||||
} | ||||
bool intersects(const QCPDataRange &other) const; | ||||
bool contains(const QCPDataRange &other) const; | ||||
private: | ||||
// property members: | ||||
int mBegin, mEnd; | ||||
}; | ||||
Q_DECLARE_TYPEINFO(QCPDataRange, Q_MOVABLE_TYPE); | ||||
class QCP_LIB_DECL QCPDataSelection { | ||||
public: | ||||
explicit QCPDataSelection(); | ||||
explicit QCPDataSelection(const QCPDataRange &range); | ||||
bool operator==(const QCPDataSelection &other) const; | ||||
bool operator!=(const QCPDataSelection &other) const { return !(*this == other); } | ||||
QCPDataSelection &operator+=(const QCPDataSelection &other); | ||||
QCPDataSelection &operator+=(const QCPDataRange &other); | ||||
QCPDataSelection &operator-=(const QCPDataSelection &other); | ||||
QCPDataSelection &operator-=(const QCPDataRange &other); | ||||
friend inline const QCPDataSelection operator+(const QCPDataSelection &a, | ||||
const QCPDataSelection &b); | ||||
friend inline const QCPDataSelection operator+(const QCPDataRange &a, | ||||
const QCPDataSelection &b); | ||||
friend inline const QCPDataSelection operator+(const QCPDataSelection &a, | ||||
const QCPDataRange &b); | ||||
friend inline const QCPDataSelection operator+(const QCPDataRange &a, const QCPDataRange &b); | ||||
friend inline const QCPDataSelection operator-(const QCPDataSelection &a, | ||||
const QCPDataSelection &b); | ||||
friend inline const QCPDataSelection operator-(const QCPDataRange &a, | ||||
const QCPDataSelection &b); | ||||
friend inline const QCPDataSelection operator-(const QCPDataSelection &a, | ||||
const QCPDataRange &b); | ||||
friend inline const QCPDataSelection operator-(const QCPDataRange &a, const QCPDataRange &b); | ||||
// getters: | ||||
int dataRangeCount() const { return mDataRanges.size(); } | ||||
int dataPointCount() const; | ||||
QCPDataRange dataRange(int index = 0) const; | ||||
QList<QCPDataRange> dataRanges() const { return mDataRanges; } | ||||
QCPDataRange span() const; | ||||
// non-property methods: | ||||
void addDataRange(const QCPDataRange &dataRange, bool simplify = true); | ||||
void clear(); | ||||
bool isEmpty() const { return mDataRanges.isEmpty(); } | ||||
void simplify(); | ||||
void enforceType(QCP::SelectionType type); | ||||
bool contains(const QCPDataSelection &other) const; | ||||
QCPDataSelection intersection(const QCPDataRange &other) const; | ||||
QCPDataSelection intersection(const QCPDataSelection &other) const; | ||||
QCPDataSelection inverse(const QCPDataRange &outerRange) const; | ||||
private: | ||||
// property members: | ||||
QList<QCPDataRange> mDataRanges; | ||||
inline static bool lessThanDataRangeBegin(const QCPDataRange &a, const QCPDataRange &b) | ||||
{ | ||||
return a.begin() < b.begin(); | ||||
} | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPDataSelection) | ||||
/*! | ||||
Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. | ||||
The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). | ||||
*/ | ||||
inline const QCPDataSelection operator+(const QCPDataSelection &a, const QCPDataSelection &b) | ||||
{ | ||||
QCPDataSelection result(a); | ||||
result += b; | ||||
return result; | ||||
} | ||||
/*! | ||||
Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. | ||||
The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). | ||||
*/ | ||||
inline const QCPDataSelection operator+(const QCPDataRange &a, const QCPDataSelection &b) | ||||
{ | ||||
QCPDataSelection result(a); | ||||
result += b; | ||||
return result; | ||||
} | ||||
/*! | ||||
Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. | ||||
The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). | ||||
*/ | ||||
inline const QCPDataSelection operator+(const QCPDataSelection &a, const QCPDataRange &b) | ||||
{ | ||||
QCPDataSelection result(a); | ||||
result += b; | ||||
return result; | ||||
} | ||||
/*! | ||||
Return a \ref QCPDataSelection with the data points in \a a joined with the data points in \a b. | ||||
The resulting data selection is already simplified (see \ref QCPDataSelection::simplify). | ||||
*/ | ||||
inline const QCPDataSelection operator+(const QCPDataRange &a, const QCPDataRange &b) | ||||
{ | ||||
QCPDataSelection result(a); | ||||
result += b; | ||||
return result; | ||||
} | ||||
/*! | ||||
Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. | ||||
*/ | ||||
inline const QCPDataSelection operator-(const QCPDataSelection &a, const QCPDataSelection &b) | ||||
{ | ||||
QCPDataSelection result(a); | ||||
result -= b; | ||||
return result; | ||||
} | ||||
/*! | ||||
Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. | ||||
*/ | ||||
inline const QCPDataSelection operator-(const QCPDataRange &a, const QCPDataSelection &b) | ||||
{ | ||||
QCPDataSelection result(a); | ||||
result -= b; | ||||
return result; | ||||
} | ||||
/*! | ||||
Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. | ||||
*/ | ||||
inline const QCPDataSelection operator-(const QCPDataSelection &a, const QCPDataRange &b) | ||||
{ | ||||
QCPDataSelection result(a); | ||||
result -= b; | ||||
return result; | ||||
} | ||||
/*! | ||||
Return a \ref QCPDataSelection with the data points which are in \a a but not in \a b. | ||||
*/ | ||||
inline const QCPDataSelection operator-(const QCPDataRange &a, const QCPDataRange &b) | ||||
{ | ||||
QCPDataSelection result(a); | ||||
result -= b; | ||||
return result; | ||||
} | ||||
/*! \relates QCPDataRange | ||||
Prints \a dataRange in a human readable format to the qDebug output. | ||||
*/ | ||||
inline QDebug operator<<(QDebug d, const QCPDataRange &dataRange) | ||||
{ | ||||
d.nospace() << "[" << dataRange.begin() << ".." << dataRange.end() - 1 << "]"; | ||||
return d.space(); | ||||
} | ||||
/*! \relates QCPDataSelection | ||||
Prints \a selection in a human readable format to the qDebug output. | ||||
*/ | ||||
inline QDebug operator<<(QDebug d, const QCPDataSelection &selection) | ||||
{ | ||||
d.nospace() << "QCPDataSelection("; | ||||
for (int i = 0; i < selection.dataRangeCount(); ++i) { | ||||
if (i != 0) | ||||
d << ", "; | ||||
d << selection.dataRange(i); | ||||
} | ||||
d << ")"; | ||||
return d.space(); | ||||
} | ||||
/* end of 'src/selection.h' */ | ||||
/* including file 'src/selectionrect.h', size 3338 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
class QCP_LIB_DECL QCPSelectionRect : public QCPLayerable { | ||||
Q_OBJECT | ||||
public: | ||||
explicit QCPSelectionRect(QCustomPlot *parentPlot); | ||||
virtual ~QCPSelectionRect(); | ||||
// getters: | ||||
QRect rect() const { return mRect; } | ||||
QCPRange range(const QCPAxis *axis) const; | ||||
QPen pen() const { return mPen; } | ||||
QBrush brush() const { return mBrush; } | ||||
bool isActive() const { return mActive; } | ||||
// setters: | ||||
void setPen(const QPen &pen); | ||||
void setBrush(const QBrush &brush); | ||||
// non-property methods: | ||||
Q_SLOT void cancel(); | ||||
signals: | ||||
void started(QMouseEvent *event); | ||||
void changed(const QRect &rect, QMouseEvent *event); | ||||
void canceled(const QRect &rect, QInputEvent *event); | ||||
void accepted(const QRect &rect, QMouseEvent *event); | ||||
protected: | ||||
// property members: | ||||
QRect mRect; | ||||
QPen mPen; | ||||
QBrush mBrush; | ||||
// non-property members: | ||||
bool mActive; | ||||
// introduced virtual methods: | ||||
virtual void startSelection(QMouseEvent *event); | ||||
virtual void moveSelection(QMouseEvent *event); | ||||
virtual void endSelection(QMouseEvent *event); | ||||
virtual void keyPressEvent(QKeyEvent *event); | ||||
// reimplemented virtual methods | ||||
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; | ||||
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; | ||||
friend class QCustomPlot; | ||||
}; | ||||
/* end of 'src/selectionrect.h' */ | ||||
/* including file 'src/layout.h', size 13128 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
class QCP_LIB_DECL QCPMarginGroup : public QObject { | ||||
Q_OBJECT | ||||
public: | ||||
explicit QCPMarginGroup(QCustomPlot *parentPlot); | ||||
virtual ~QCPMarginGroup(); | ||||
// non-virtual methods: | ||||
QList<QCPLayoutElement *> elements(QCP::MarginSide side) const { return mChildren.value(side); } | ||||
bool isEmpty() const; | ||||
void clear(); | ||||
protected: | ||||
// non-property members: | ||||
QCustomPlot *mParentPlot; | ||||
QHash<QCP::MarginSide, QList<QCPLayoutElement *> > mChildren; | ||||
// introduced virtual methods: | ||||
virtual int commonMargin(QCP::MarginSide side) const; | ||||
// non-virtual methods: | ||||
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<QCP::MarginSide, QCPMarginGroup *> 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<QCPLayoutElement *> elements(bool recursive) const; | ||||
// reimplemented virtual methods: | ||||
virtual double selectTest(const QPointF &pos, bool onlySelectable, | ||||
QVariant *details = 0) const Q_DECL_OVERRIDE; | ||||
protected: | ||||
// property members: | ||||
QCPLayout *mParentLayout; | ||||
QSize mMinimumSize, mMaximumSize; | ||||
QRect mRect, mOuterRect; | ||||
QMargins mMargins, mMinimumMargins; | ||||
QCP::MarginSides mAutoMargins; | ||||
QHash<QCP::MarginSide, QCPMarginGroup *> mMarginGroups; | ||||
// introduced virtual methods: | ||||
virtual int calculateAutoMargin(QCP::MarginSide side); | ||||
virtual void layoutChanged(); | ||||
// reimplemented virtual methods: | ||||
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE | ||||
{ | ||||
Q_UNUSED(painter) | ||||
} | ||||
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE { Q_UNUSED(painter) } | ||||
virtual void parentPlotInitialized(QCustomPlot *parentPlot) Q_DECL_OVERRIDE; | ||||
private: | ||||
Q_DISABLE_COPY(QCPLayoutElement) | ||||
friend class QCustomPlot; | ||||
friend class QCPLayout; | ||||
friend class QCPMarginGroup; | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPLayoutElement::UpdatePhase) | ||||
class QCP_LIB_DECL QCPLayout : public QCPLayoutElement { | ||||
Q_OBJECT | ||||
public: | ||||
explicit QCPLayout(); | ||||
// reimplemented virtual methods: | ||||
virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; | ||||
virtual QList<QCPLayoutElement *> elements(bool recursive) const Q_DECL_OVERRIDE; | ||||
// 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<int> getSectionSizes(QVector<int> maxSizes, QVector<int> minSizes, | ||||
QVector<double> 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<double> columnStretchFactors READ columnStretchFactors WRITE setColumnStretchFactors) | ||||
Q_PROPERTY(QList<double> rowStretchFactors READ rowStretchFactors WRITE setRowStretchFactors) | ||||
Q_PROPERTY(int columnSpacing READ columnSpacing WRITE setColumnSpacing) | ||||
Q_PROPERTY(int rowSpacing READ rowSpacing WRITE setRowSpacing) | ||||
Q_PROPERTY(FillOrder fillOrder READ fillOrder WRITE setFillOrder) | ||||
Q_PROPERTY(int wrap READ wrap WRITE setWrap) | ||||
/// \endcond | ||||
public: | ||||
/*! | ||||
Defines in which direction the grid is filled when using \ref addElement(QCPLayoutElement*). | ||||
The column/row at which wrapping into the next row/column occurs can be specified with \ref | ||||
setWrap. | ||||
\see setFillOrder | ||||
*/ | ||||
enum FillOrder { | ||||
foRowsFirst ///< Rows are filled first, and a new element is wrapped to the next column if | ||||
/// the row count would exceed \ref setWrap. | ||||
, | ||||
foColumnsFirst ///< Columns are filled first, and a new element is wrapped to the next row | ||||
/// if the column count would exceed \ref setWrap. | ||||
}; | ||||
Q_ENUMS(FillOrder) | ||||
explicit QCPLayoutGrid(); | ||||
virtual ~QCPLayoutGrid(); | ||||
// getters: | ||||
int rowCount() const { return mElements.size(); } | ||||
int columnCount() const { return mElements.size() > 0 ? mElements.first().size() : 0; } | ||||
QList<double> columnStretchFactors() const { return mColumnStretchFactors; } | ||||
QList<double> rowStretchFactors() const { return mRowStretchFactors; } | ||||
int columnSpacing() const { return mColumnSpacing; } | ||||
int rowSpacing() const { return mRowSpacing; } | ||||
int wrap() const { return mWrap; } | ||||
FillOrder fillOrder() const { return mFillOrder; } | ||||
// setters: | ||||
void setColumnStretchFactor(int column, double factor); | ||||
void setColumnStretchFactors(const QList<double> &factors); | ||||
void setRowStretchFactor(int row, double factor); | ||||
void setRowStretchFactors(const QList<double> &factors); | ||||
void setColumnSpacing(int pixels); | ||||
void setRowSpacing(int pixels); | ||||
void setWrap(int count); | ||||
void setFillOrder(FillOrder order, bool rearrange = true); | ||||
// reimplemented virtual methods: | ||||
virtual void updateLayout() Q_DECL_OVERRIDE; | ||||
virtual int elementCount() const Q_DECL_OVERRIDE { return rowCount() * columnCount(); } | ||||
virtual QCPLayoutElement *elementAt(int index) const Q_DECL_OVERRIDE; | ||||
virtual QCPLayoutElement *takeAt(int index) Q_DECL_OVERRIDE; | ||||
virtual bool take(QCPLayoutElement *element) Q_DECL_OVERRIDE; | ||||
virtual QList<QCPLayoutElement *> elements(bool recursive) const Q_DECL_OVERRIDE; | ||||
virtual void simplify() Q_DECL_OVERRIDE; | ||||
virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; | ||||
virtual QSize maximumSizeHint() const Q_DECL_OVERRIDE; | ||||
// non-virtual methods: | ||||
QCPLayoutElement *element(int row, int column) const; | ||||
bool addElement(int row, int column, QCPLayoutElement *element); | ||||
bool addElement(QCPLayoutElement *element); | ||||
bool hasElement(int row, int column); | ||||
void expandTo(int newRowCount, int newColumnCount); | ||||
void insertRow(int newIndex); | ||||
void insertColumn(int newIndex); | ||||
int rowColToIndex(int row, int column) const; | ||||
void indexToRowCol(int index, int &row, int &column) const; | ||||
protected: | ||||
// property members: | ||||
QList<QList<QCPLayoutElement *> > mElements; | ||||
QList<double> mColumnStretchFactors; | ||||
QList<double> mRowStretchFactors; | ||||
int mColumnSpacing, mRowSpacing; | ||||
int mWrap; | ||||
FillOrder mFillOrder; | ||||
// non-virtual methods: | ||||
void getMinimumRowColSizes(QVector<int> *minColWidths, QVector<int> *minRowHeights) const; | ||||
void getMaximumRowColSizes(QVector<int> *maxColWidths, QVector<int> *maxRowHeights) const; | ||||
private: | ||||
Q_DISABLE_COPY(QCPLayoutGrid) | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPLayoutGrid::FillOrder) | ||||
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 | ||||
}; | ||||
Q_ENUMS(InsetPlacement) | ||||
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() Q_DECL_OVERRIDE; | ||||
virtual int elementCount() const Q_DECL_OVERRIDE; | ||||
virtual QCPLayoutElement *elementAt(int index) const Q_DECL_OVERRIDE; | ||||
virtual QCPLayoutElement *takeAt(int index) Q_DECL_OVERRIDE; | ||||
virtual bool take(QCPLayoutElement *element) Q_DECL_OVERRIDE; | ||||
virtual void simplify() Q_DECL_OVERRIDE {} | ||||
virtual double selectTest(const QPointF &pos, bool onlySelectable, | ||||
QVariant *details = 0) const Q_DECL_OVERRIDE; | ||||
// non-virtual methods: | ||||
void addElement(QCPLayoutElement *element, Qt::Alignment alignment); | ||||
void addElement(QCPLayoutElement *element, const QRectF &rect); | ||||
protected: | ||||
// property members: | ||||
QList<QCPLayoutElement *> mElements; | ||||
QList<InsetPlacement> mInsetPlacement; | ||||
QList<Qt::Alignment> mInsetAlignment; | ||||
QList<QRectF> mInsetRect; | ||||
private: | ||||
Q_DISABLE_COPY(QCPLayoutInset) | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPLayoutInset::InsetPlacement) | ||||
/* end of 'src/layout.h' */ | ||||
/* including file 'src/lineending.h', size 4426 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
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 | ||||
*/ | ||||
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 degrees 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) | ||||
}; | ||||
Q_ENUMS(EndingStyle) | ||||
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 QCPVector2D &pos, const QCPVector2D &dir) const; | ||||
void draw(QCPPainter *painter, const QCPVector2D &pos, double angle) const; | ||||
protected: | ||||
// property members: | ||||
EndingStyle mStyle; | ||||
double mWidth, mLength; | ||||
bool mInverted; | ||||
}; | ||||
Q_DECLARE_TYPEINFO(QCPLineEnding, Q_MOVABLE_TYPE); | ||||
Q_DECLARE_METATYPE(QCPLineEnding::EndingStyle) | ||||
/* end of 'src/lineending.h' */ | ||||
/* including file 'src/axis/axisticker.h', size 4177 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
class QCP_LIB_DECL QCPAxisTicker { | ||||
Q_GADGET | ||||
public: | ||||
/*! | ||||
Defines the strategies that the axis ticker may follow when choosing the size of the tick | ||||
step. | ||||
\see setTickStepStrategy | ||||
*/ | ||||
enum TickStepStrategy { | ||||
tssReadability ///< A nicely readable tick step is prioritized over matching the requested | ||||
/// number of ticks (see \ref setTickCount) | ||||
, | ||||
tssMeetTickCount ///< Less readable tick steps are allowed which in turn facilitates getting | ||||
/// closer to the requested tick count | ||||
}; | ||||
Q_ENUMS(TickStepStrategy) | ||||
QCPAxisTicker(); | ||||
virtual ~QCPAxisTicker(); | ||||
// getters: | ||||
TickStepStrategy tickStepStrategy() const { return mTickStepStrategy; } | ||||
int tickCount() const { return mTickCount; } | ||||
double tickOrigin() const { return mTickOrigin; } | ||||
// setters: | ||||
void setTickStepStrategy(TickStepStrategy strategy); | ||||
void setTickCount(int count); | ||||
void setTickOrigin(double origin); | ||||
// introduced virtual methods: | ||||
virtual void generate(const QCPRange &range, const QLocale &locale, QChar formatChar, | ||||
int precision, QVector<double> &ticks, QVector<double> *subTicks, | ||||
QVector<QString> *tickLabels); | ||||
protected: | ||||
// property members: | ||||
TickStepStrategy mTickStepStrategy; | ||||
int mTickCount; | ||||
double mTickOrigin; | ||||
// introduced virtual methods: | ||||
virtual double getTickStep(const QCPRange &range); | ||||
virtual int getSubTickCount(double tickStep); | ||||
virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, | ||||
int precision); | ||||
virtual QVector<double> createTickVector(double tickStep, const QCPRange &range); | ||||
virtual QVector<double> createSubTickVector(int subTickCount, const QVector<double> &ticks); | ||||
virtual QVector<QString> createLabelVector(const QVector<double> &ticks, const QLocale &locale, | ||||
QChar formatChar, int precision); | ||||
// non-virtual methods: | ||||
void trimTicks(const QCPRange &range, QVector<double> &ticks, bool keepOneOutlier) const; | ||||
double pickClosest(double target, const QVector<double> &candidates) const; | ||||
double getMantissa(double input, double *magnitude = 0) const; | ||||
double cleanMantissa(double input) const; | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPAxisTicker::TickStepStrategy) | ||||
Q_DECLARE_METATYPE(QSharedPointer<QCPAxisTicker>) | ||||
/* end of 'src/axis/axisticker.h' */ | ||||
/* including file 'src/axis/axistickerdatetime.h', size 3289 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
class QCP_LIB_DECL QCPAxisTickerDateTime : public QCPAxisTicker { | ||||
public: | ||||
QCPAxisTickerDateTime(); | ||||
// getters: | ||||
QString dateTimeFormat() const { return mDateTimeFormat; } | ||||
Qt::TimeSpec dateTimeSpec() const { return mDateTimeSpec; } | ||||
// setters: | ||||
void setDateTimeFormat(const QString &format); | ||||
void setDateTimeSpec(Qt::TimeSpec spec); | ||||
void setTickOrigin(double origin); // hides base class method but calls baseclass implementation | ||||
// ("using" throws off IDEs and doxygen) | ||||
void setTickOrigin(const QDateTime &origin); | ||||
// static methods: | ||||
static QDateTime keyToDateTime(double key); | ||||
static double dateTimeToKey(const QDateTime dateTime); | ||||
static double dateTimeToKey(const QDate date); | ||||
protected: | ||||
// property members: | ||||
QString mDateTimeFormat; | ||||
Qt::TimeSpec mDateTimeSpec; | ||||
// non-property members: | ||||
enum DateStrategy { dsNone, dsUniformTimeInDay, dsUniformDayInMonth } mDateStrategy; | ||||
// reimplemented virtual methods: | ||||
virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; | ||||
virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; | ||||
virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, | ||||
int precision) Q_DECL_OVERRIDE; | ||||
virtual QVector<double> createTickVector(double tickStep, | ||||
const QCPRange &range) Q_DECL_OVERRIDE; | ||||
}; | ||||
/* end of 'src/axis/axistickerdatetime.h' */ | ||||
r610 | /* including file 'src/axis/axistickertime.h', size 3542 */ | |||
/* commit c38adb94d83c6a752597a5d43d45c0561fbe1d4d 2017-08-13 17:37:53 +0200 */ | ||||
r59 | ||||
class QCP_LIB_DECL QCPAxisTickerTime : public QCPAxisTicker { | ||||
Q_GADGET | ||||
public: | ||||
/*! | ||||
Defines the logical units in which fractions of time spans can be expressed. | ||||
\see setFieldWidth, setTimeFormat | ||||
*/ | ||||
r610 | enum TimeUnit { | |||
tuMilliseconds ///< Milliseconds, one thousandth of a second (%%z in \ref setTimeFormat) | ||||
, | ||||
tuSeconds ///< Seconds (%%s in \ref setTimeFormat) | ||||
, | ||||
tuMinutes ///< Minutes (%%m in \ref setTimeFormat) | ||||
, | ||||
tuHours ///< Hours (%%h in \ref setTimeFormat) | ||||
, | ||||
tuDays ///< Days (%%d in \ref setTimeFormat) | ||||
}; | ||||
r59 | Q_ENUMS(TimeUnit) | |||
QCPAxisTickerTime(); | ||||
// getters: | ||||
QString timeFormat() const { return mTimeFormat; } | ||||
int fieldWidth(TimeUnit unit) const { return mFieldWidth.value(unit); } | ||||
// setters: | ||||
void setTimeFormat(const QString &format); | ||||
void setFieldWidth(TimeUnit unit, int width); | ||||
protected: | ||||
// property members: | ||||
QString mTimeFormat; | ||||
QHash<TimeUnit, int> mFieldWidth; | ||||
// non-property members: | ||||
TimeUnit mSmallestUnit, mBiggestUnit; | ||||
QHash<TimeUnit, QString> mFormatPattern; | ||||
// reimplemented virtual methods: | ||||
virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; | ||||
virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; | ||||
virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, | ||||
int precision) Q_DECL_OVERRIDE; | ||||
// non-virtual methods: | ||||
void replaceUnit(QString &text, TimeUnit unit, int value) const; | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPAxisTickerTime::TimeUnit) | ||||
/* end of 'src/axis/axistickertime.h' */ | ||||
/* including file 'src/axis/axistickerfixed.h', size 3308 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
class QCP_LIB_DECL QCPAxisTickerFixed : public QCPAxisTicker { | ||||
Q_GADGET | ||||
public: | ||||
/*! | ||||
Defines how the axis ticker may modify the specified tick step (\ref setTickStep) in order to | ||||
control the number of ticks in the axis range. | ||||
\see setScaleStrategy | ||||
*/ | ||||
enum ScaleStrategy { | ||||
ssNone ///< Modifications are not allowed, the specified tick step is absolutely fixed. This | ||||
/// might cause a high tick density and overlapping labels if the axis range is zoomed | ||||
/// out. | ||||
, | ||||
ssMultiples ///< An integer multiple of the specified tick step is allowed. The used factor | ||||
/// follows the base class properties of \ref setTickStepStrategy and \ref | ||||
/// setTickCount. | ||||
, | ||||
ssPowers ///< An integer power of the specified tick step is allowed. | ||||
}; | ||||
Q_ENUMS(ScaleStrategy) | ||||
QCPAxisTickerFixed(); | ||||
// getters: | ||||
double tickStep() const { return mTickStep; } | ||||
ScaleStrategy scaleStrategy() const { return mScaleStrategy; } | ||||
// setters: | ||||
void setTickStep(double step); | ||||
void setScaleStrategy(ScaleStrategy strategy); | ||||
protected: | ||||
// property members: | ||||
double mTickStep; | ||||
ScaleStrategy mScaleStrategy; | ||||
// reimplemented virtual methods: | ||||
virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPAxisTickerFixed::ScaleStrategy) | ||||
/* end of 'src/axis/axistickerfixed.h' */ | ||||
/* including file 'src/axis/axistickertext.h', size 3085 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
class QCP_LIB_DECL QCPAxisTickerText : public QCPAxisTicker { | ||||
public: | ||||
QCPAxisTickerText(); | ||||
// getters: | ||||
QMap<double, QString> &ticks() { return mTicks; } | ||||
int subTickCount() const { return mSubTickCount; } | ||||
// setters: | ||||
void setTicks(const QMap<double, QString> &ticks); | ||||
void setTicks(const QVector<double> &positions, const QVector<QString> labels); | ||||
void setSubTickCount(int subTicks); | ||||
// non-virtual methods: | ||||
void clear(); | ||||
void addTick(double position, QString label); | ||||
void addTicks(const QMap<double, QString> &ticks); | ||||
void addTicks(const QVector<double> &positions, const QVector<QString> &labels); | ||||
protected: | ||||
// property members: | ||||
QMap<double, QString> mTicks; | ||||
int mSubTickCount; | ||||
// reimplemented virtual methods: | ||||
virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; | ||||
virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; | ||||
virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, | ||||
int precision) Q_DECL_OVERRIDE; | ||||
virtual QVector<double> createTickVector(double tickStep, | ||||
const QCPRange &range) Q_DECL_OVERRIDE; | ||||
}; | ||||
/* end of 'src/axis/axistickertext.h' */ | ||||
/* including file 'src/axis/axistickerpi.h', size 3911 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
class QCP_LIB_DECL QCPAxisTickerPi : public QCPAxisTicker { | ||||
Q_GADGET | ||||
public: | ||||
/*! | ||||
Defines how fractions should be displayed in tick labels. | ||||
\see setFractionStyle | ||||
*/ | ||||
enum FractionStyle { | ||||
fsFloatingPoint ///< Fractions are displayed as regular decimal floating point numbers, e.g. | ||||
///"0.25" or "0.125". | ||||
, | ||||
fsAsciiFractions ///< Fractions are written as rationals using ASCII characters only, e.g. | ||||
///"1/4" or "1/8" | ||||
, | ||||
fsUnicodeFractions ///< Fractions are written using sub- and superscript UTF-8 digits and | ||||
/// the fraction symbol. | ||||
}; | ||||
Q_ENUMS(FractionStyle) | ||||
QCPAxisTickerPi(); | ||||
// getters: | ||||
QString piSymbol() const { return mPiSymbol; } | ||||
double piValue() const { return mPiValue; } | ||||
bool periodicity() const { return mPeriodicity; } | ||||
FractionStyle fractionStyle() const { return mFractionStyle; } | ||||
// setters: | ||||
void setPiSymbol(QString symbol); | ||||
void setPiValue(double pi); | ||||
void setPeriodicity(int multiplesOfPi); | ||||
void setFractionStyle(FractionStyle style); | ||||
protected: | ||||
// property members: | ||||
QString mPiSymbol; | ||||
double mPiValue; | ||||
int mPeriodicity; | ||||
FractionStyle mFractionStyle; | ||||
// non-property members: | ||||
double mPiTickStep; // size of one tick step in units of mPiValue | ||||
// reimplemented virtual methods: | ||||
virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; | ||||
virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; | ||||
virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, | ||||
int precision) Q_DECL_OVERRIDE; | ||||
// non-virtual methods: | ||||
void simplifyFraction(int &numerator, int &denominator) const; | ||||
QString fractionToString(int numerator, int denominator) const; | ||||
QString unicodeFraction(int numerator, int denominator) const; | ||||
QString unicodeSuperscript(int number) const; | ||||
QString unicodeSubscript(int number) const; | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPAxisTickerPi::FractionStyle) | ||||
/* end of 'src/axis/axistickerpi.h' */ | ||||
/* including file 'src/axis/axistickerlog.h', size 2663 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
class QCP_LIB_DECL QCPAxisTickerLog : public QCPAxisTicker { | ||||
public: | ||||
QCPAxisTickerLog(); | ||||
// getters: | ||||
double logBase() const { return mLogBase; } | ||||
int subTickCount() const { return mSubTickCount; } | ||||
// setters: | ||||
void setLogBase(double base); | ||||
void setSubTickCount(int subTicks); | ||||
protected: | ||||
// property members: | ||||
double mLogBase; | ||||
int mSubTickCount; | ||||
// non-property members: | ||||
double mLogBaseLnInv; | ||||
// reimplemented virtual methods: | ||||
virtual double getTickStep(const QCPRange &range) Q_DECL_OVERRIDE; | ||||
virtual int getSubTickCount(double tickStep) Q_DECL_OVERRIDE; | ||||
virtual QVector<double> createTickVector(double tickStep, | ||||
const QCPRange &range) Q_DECL_OVERRIDE; | ||||
}; | ||||
/* end of 'src/axis/axistickerlog.h' */ | ||||
r610 | /* including file 'src/axis/axis.h', size 20634 */ | |||
/* commit 0cc4d9f61f7bf45321a88fec89d909b020ffa26f 2017-08-14 00:43:29 +0200 */ | ||||
r59 | ||||
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: | ||||
explicit 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 Q_DECL_OVERRIDE; | ||||
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; | ||||
// 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(QCPRange range READ range WRITE setRange NOTIFY rangeChanged) | ||||
Q_PROPERTY(bool rangeReversed READ rangeReversed WRITE setRangeReversed) | ||||
Q_PROPERTY(QSharedPointer<QCPAxisTicker> ticker READ ticker WRITE setTicker) | ||||
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(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 numberFormat READ numberFormat WRITE setNumberFormat) | ||||
Q_PROPERTY(int numberPrecision READ numberPrecision WRITE setNumberPrecision) | ||||
Q_PROPERTY(QVector<double> tickVector READ tickVector) | ||||
Q_PROPERTY(QVector<QString> tickVectorLabels READ tickVectorLabels) | ||||
Q_PROPERTY(int tickLengthIn READ tickLengthIn WRITE setTickLengthIn) | ||||
Q_PROPERTY(int tickLengthOut READ tickLengthOut WRITE setTickLengthOut) | ||||
Q_PROPERTY(bool subTicks READ subTicks WRITE setSubTicks) | ||||
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 ///< <tt>0x01</tt> Axis is vertical and on the left side of the axis rect | ||||
, | ||||
atRight = 0x02 ///< <tt>0x02</tt> Axis is vertical and on the right side of the axis rect | ||||
, | ||||
atTop = 0x04 ///< <tt>0x04</tt> Axis is horizontal and on the top side of the axis rect | ||||
, | ||||
atBottom | ||||
= 0x08 ///< <tt>0x08</tt> Axis is horizontal and on the bottom side of the axis rect | ||||
}; | ||||
Q_ENUMS(AxisType) | ||||
Q_FLAGS(AxisTypes) | ||||
Q_DECLARE_FLAGS(AxisTypes, AxisType) | ||||
/*! | ||||
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 axis coordinates | ||||
///(possibly also \ref setTicker to a \ref QCPAxisTickerLog instance). | ||||
}; | ||||
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_ENUMS(SelectablePart) | ||||
Q_FLAGS(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; } | ||||
const QCPRange range() const { return mRange; } | ||||
bool rangeReversed() const { return mRangeReversed; } | ||||
QSharedPointer<QCPAxisTicker> ticker() const { return mTicker; } | ||||
bool ticks() const { return mTicks; } | ||||
bool tickLabels() const { return mTickLabels; } | ||||
int tickLabelPadding() const; | ||||
QFont tickLabelFont() const { return mTickLabelFont; } | ||||
QColor tickLabelColor() const { return mTickLabelColor; } | ||||
double tickLabelRotation() const; | ||||
LabelSide tickLabelSide() const; | ||||
QString numberFormat() const; | ||||
int numberPrecision() const { return mNumberPrecision; } | ||||
QVector<double> tickVector() const { return mTickVector; } | ||||
QVector<QString> tickVectorLabels() const { return mTickVectorLabels; } | ||||
int tickLengthIn() const; | ||||
int tickLengthOut() const; | ||||
bool subTicks() const { return mSubTicks; } | ||||
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); | ||||
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 setTicker(QSharedPointer<QCPAxisTicker> ticker); | ||||
void setTicks(bool show); | ||||
void setTickLabels(bool show); | ||||
void setTickLabelPadding(int padding); | ||||
void setTickLabelFont(const QFont &font); | ||||
void setTickLabelColor(const QColor &color); | ||||
void setTickLabelRotation(double degrees); | ||||
void setTickLabelSide(LabelSide side); | ||||
void setNumberFormat(const QString &formatCode); | ||||
void setNumberPrecision(int precision); | ||||
void setTickLength(int inside, int outside = 0); | ||||
void setTickLengthIn(int inside); | ||||
void setTickLengthOut(int outside); | ||||
void setSubTicks(bool show); | ||||
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 Q_DECL_OVERRIDE; | ||||
// non-property methods: | ||||
Qt::Orientation orientation() const { return mOrientation; } | ||||
int pixelOrientation() const | ||||
{ | ||||
return rangeReversed() != (orientation() == Qt::Vertical) ? -1 : 1; | ||||
} | ||||
void moveRange(double diff); | ||||
void scaleRange(double factor); | ||||
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<QCPAbstractPlottable *> plottables() const; | ||||
QList<QCPGraph *> graphs() const; | ||||
QList<QCPAbstractItem *> 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 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; | ||||
// double mTickLabelRotation; // in QCPAxisPainter | ||||
QFont mTickLabelFont, mSelectedTickLabelFont; | ||||
QColor mTickLabelColor, mSelectedTickLabelColor; | ||||
int mNumberPrecision; | ||||
QLatin1Char mNumberFormatChar; | ||||
bool mNumberBeautifulPowers; | ||||
// bool mNumberMultiplyCross; // QCPAxisPainter | ||||
// ticks and subticks: | ||||
bool mTicks; | ||||
bool mSubTicks; | ||||
// int mTickLengthIn, mTickLengthOut, mSubTickLengthIn, mSubTickLengthOut; // QCPAxisPainter | ||||
QPen mTickPen, mSelectedTickPen; | ||||
QPen mSubTickPen, mSelectedSubTickPen; | ||||
// scale and range: | ||||
QCPRange mRange; | ||||
bool mRangeReversed; | ||||
ScaleType mScaleType; | ||||
// non-property members: | ||||
QCPGrid *mGrid; | ||||
QCPAxisPainterPrivate *mAxisPainter; | ||||
QSharedPointer<QCPAxisTicker> mTicker; | ||||
QVector<double> mTickVector; | ||||
QVector<QString> mTickVectorLabels; | ||||
QVector<double> mSubTickVector; | ||||
bool mCachedMarginValid; | ||||
int mCachedMargin; | ||||
r610 | bool mDragging; | |||
QCPRange mDragStartRange; | ||||
QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; | ||||
r59 | ||||
// introduced virtual methods: | ||||
virtual int calculateMargin(); | ||||
// reimplemented virtual methods: | ||||
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; | ||||
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; | ||||
virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; | ||||
// events: | ||||
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, | ||||
bool *selectionStateChanged) Q_DECL_OVERRIDE; | ||||
virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; | ||||
r610 | // mouse events: | |||
virtual void mousePressEvent(QMouseEvent *event, const QVariant &details); | ||||
virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos); | ||||
virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos); | ||||
virtual void wheelEvent(QWheelEvent *event); | ||||
r59 | ||||
// non-virtual methods: | ||||
void setupTickVectors(); | ||||
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::AxisType) | ||||
Q_DECLARE_METATYPE(QCPAxis::LabelSide) | ||||
Q_DECLARE_METATYPE(QCPAxis::ScaleType) | ||||
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<double> subTickPositions; | ||||
QVector<double> tickPositions; | ||||
QVector<QString> tickLabels; | ||||
protected: | ||||
struct CachedLabel { | ||||
QPointF offset; | ||||
QPixmap pixmap; | ||||
}; | ||||
struct TickLabelData { | ||||
QString basePart, expPart, suffixPart; | ||||
QRect baseBounds, expBounds, suffixBounds, totalBounds, rotatedTotalBounds; | ||||
QFont baseFont, expFont; | ||||
}; | ||||
QCustomPlot *mParentPlot; | ||||
QByteArray mLabelParameterHash; // to determine whether mLabelCache needs to be cleared due to | ||||
// changed parameters | ||||
QCache<QString, CachedLabel> 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; | ||||
}; | ||||
/* end of 'src/axis/axis.h' */ | ||||
/* including file 'src/scatterstyle.h', size 7275 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
class QCP_LIB_DECL QCPScatterStyle { | ||||
Q_GADGET | ||||
public: | ||||
/*! | ||||
Represents the various properties of a scatter style instance. For example, this enum is used | ||||
to specify which properties of \ref QCPSelectionDecorator::setScatterStyle will be used when | ||||
highlighting selected data points. | ||||
Specific scatter properties can be transferred between \ref QCPScatterStyle instances via \ref | ||||
setFromOther. | ||||
*/ | ||||
enum ScatterProperty { | ||||
spNone = 0x00 ///< <tt>0x00</tt> None | ||||
, | ||||
spPen = 0x01 ///< <tt>0x01</tt> The pen property, see \ref setPen | ||||
, | ||||
spBrush = 0x02 ///< <tt>0x02</tt> The brush property, see \ref setBrush | ||||
, | ||||
spSize = 0x04 ///< <tt>0x04</tt> The size property, see \ref setSize | ||||
, | ||||
spShape = 0x08 ///< <tt>0x08</tt> The shape property, see \ref setShape | ||||
, | ||||
spAll = 0xFF ///< <tt>0xFF</tt> All properties | ||||
}; | ||||
Q_ENUMS(ScatterProperty) | ||||
Q_FLAGS(ScatterProperties) | ||||
Q_DECLARE_FLAGS(ScatterProperties, ScatterProperty) | ||||
/*! | ||||
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. | ||||
*/ | ||||
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) | ||||
}; | ||||
Q_ENUMS(ScatterShape) | ||||
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 setFromOther(const QCPScatterStyle &other, ScatterProperties properties); | ||||
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 undefinePen(); | ||||
void applyTo(QCPPainter *painter, const QPen &defaultPen) const; | ||||
void drawShape(QCPPainter *painter, const 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); | ||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QCPScatterStyle::ScatterProperties) | ||||
Q_DECLARE_METATYPE(QCPScatterStyle::ScatterProperty) | ||||
Q_DECLARE_METATYPE(QCPScatterStyle::ScatterShape) | ||||
/* end of 'src/scatterstyle.h' */ | ||||
r610 | /* including file 'src/datacontainer.h', size 4596 */ | |||
/* commit bee82298bd87b91a50093fb0b81cd7c734724a6f 2017-08-13 16:10:24 +0200 */ | ||||
r59 | ||||
/*! \relates QCPDataContainer | ||||
Returns whether the sort key of \a a is less than the sort key of \a b. | ||||
\see QCPDataContainer::sort | ||||
*/ | ||||
template <class DataType> | ||||
inline bool qcpLessThanSortKey(const DataType &a, const DataType &b) | ||||
{ | ||||
return a.sortKey() < b.sortKey(); | ||||
} | ||||
template <class DataType> | ||||
r610 | class QCPDataContainer // no QCP_LIB_DECL, template class ends up in header (cpp included below) | |||
{ | ||||
r59 | public: | |||
typedef typename QVector<DataType>::const_iterator const_iterator; | ||||
typedef typename QVector<DataType>::iterator iterator; | ||||
QCPDataContainer(); | ||||
// getters: | ||||
int size() const { return mData.size() - mPreallocSize; } | ||||
bool isEmpty() const { return size() == 0; } | ||||
bool autoSqueeze() const { return mAutoSqueeze; } | ||||
// setters: | ||||
void setAutoSqueeze(bool enabled); | ||||
// non-virtual methods: | ||||
void set(const QCPDataContainer<DataType> &data); | ||||
void set(const QVector<DataType> &data, bool alreadySorted = false); | ||||
void add(const QCPDataContainer<DataType> &data); | ||||
void add(const QVector<DataType> &data, bool alreadySorted = false); | ||||
void add(const DataType &data); | ||||
void removeBefore(double sortKey); | ||||
void removeAfter(double sortKey); | ||||
void remove(double sortKeyFrom, double sortKeyTo); | ||||
void remove(double sortKey); | ||||
void clear(); | ||||
void sort(); | ||||
void squeeze(bool preAllocation = true, bool postAllocation = true); | ||||
const_iterator constBegin() const { return mData.constBegin() + mPreallocSize; } | ||||
const_iterator constEnd() const { return mData.constEnd(); } | ||||
iterator begin() { return mData.begin() + mPreallocSize; } | ||||
iterator end() { return mData.end(); } | ||||
const_iterator findBegin(double sortKey, bool expandedRange = true) const; | ||||
const_iterator findEnd(double sortKey, bool expandedRange = true) const; | ||||
const_iterator at(int index) const { return constBegin() + qBound(0, index, size()); } | ||||
QCPRange keyRange(bool &foundRange, QCP::SignDomain signDomain = QCP::sdBoth); | ||||
QCPRange valueRange(bool &foundRange, QCP::SignDomain signDomain = QCP::sdBoth, | ||||
const QCPRange &inKeyRange = QCPRange()); | ||||
QCPDataRange dataRange() const { return QCPDataRange(0, size()); } | ||||
void limitIteratorsToDataRange(const_iterator &begin, const_iterator &end, | ||||
const QCPDataRange &dataRange) const; | ||||
protected: | ||||
// property members: | ||||
bool mAutoSqueeze; | ||||
// non-property memebers: | ||||
QVector<DataType> mData; | ||||
int mPreallocSize; | ||||
int mPreallocIteration; | ||||
// non-virtual methods: | ||||
void preallocateGrow(int minimumPreallocSize); | ||||
void performAutoSqueeze(); | ||||
}; | ||||
// include implementation in header since it is a class template: | ||||
r610 | /* including file 'src/datacontainer.cpp', size 31349 */ | |||
/* commit 820d2282db70144c358c13433cd74b4175f9252b 2017-07-24 00:24:17 +0200 */ | ||||
r59 | ||||
//////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
//////////////////// QCPDataContainer | ||||
//////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
/*! \class QCPDataContainer | ||||
\brief The generic data container for one-dimensional plottables | ||||
This class template provides a fast container for data storage of one-dimensional data. The data | ||||
type is specified as template parameter (called \a DataType in the following) and must provide | ||||
some methods as described in the \ref qcpdatacontainer-datatype "next section". | ||||
The data is stored in a sorted fashion, which allows very quick lookups by the sorted key as well | ||||
as retrieval of ranges (see \ref findBegin, \ref findEnd, \ref keyRange) using binary search. The | ||||
container uses a preallocation and a postallocation scheme, such that appending and prepending | ||||
data (with respect to the sort key) is very fast and minimizes reallocations. If data is added | ||||
which needs to be inserted between existing keys, the merge usually can be done quickly too, | ||||
using the fact that existing data is always sorted. The user can further improve performance by | ||||
specifying that added data is already itself sorted by key, if he can guarantee that this is the | ||||
case (see for example \ref add(const QVector<DataType> &data, bool alreadySorted)). | ||||
The data can be accessed with the provided const iterators (\ref constBegin, \ref constEnd). If | ||||
it is necessary to alter existing data in-place, the non-const iterators can be used (\ref begin, | ||||
\ref end). Changing data members that are not the sort key (for most data types called \a key) is | ||||
safe from the container's perspective. | ||||
Great care must be taken however if the sort key is modified through the non-const iterators. For | ||||
performance reasons, the iterators don't automatically cause a re-sorting upon their | ||||
manipulation. It is thus the responsibility of the user to leave the container in a sorted state | ||||
when finished with the data manipulation, before calling any other methods on the container. A | ||||
complete re-sort (e.g. after finishing all sort key manipulation) can be done by calling \ref | ||||
sort. Failing to do so can not be detected by the container efficiently and will cause both | ||||
rendering artifacts and potential data loss. | ||||
Implementing one-dimensional plottables that make use of a \ref QCPDataContainer<T> is usually | ||||
done by subclassing from \ref QCPAbstractPlottable1D "QCPAbstractPlottable1D<T>", which | ||||
introduces an according \a mDataContainer member and some convenience methods. | ||||
\section qcpdatacontainer-datatype Requirements for the DataType template parameter | ||||
The template parameter <tt>DataType</tt> is the type of the stored data points. It must be | ||||
trivially copyable and have the following public methods, preferably inline: | ||||
\li <tt>double sortKey() const</tt>\n Returns the member variable of this data point that is the | ||||
sort key, defining the ordering in the container. Often this variable is simply called \a key. | ||||
\li <tt>static DataType fromSortKey(double sortKey)</tt>\n Returns a new instance of the data | ||||
type initialized with its sort key set to \a sortKey. | ||||
\li <tt>static bool sortKeyIsMainKey()</tt>\n Returns true if the sort key is equal to the main | ||||
key (see method \c mainKey below). For most plottables this is the case. It is not the case for | ||||
example for \ref QCPCurve, which uses \a t as sort key and \a key as main key. This is the reason | ||||
why QCPCurve unlike QCPGraph can display parametric curves with loops. | ||||
\li <tt>double mainKey() const</tt>\n Returns the variable of this data point considered the main | ||||
key. This is commonly the variable that is used as the coordinate of this data point on the key | ||||
axis of the plottable. This method is used for example when determining the automatic axis | ||||
rescaling of key axes (\ref QCPAxis::rescale). | ||||
\li <tt>double mainValue() const</tt>\n Returns the variable of this data point considered the | ||||
main value. This is commonly the variable that is used as the coordinate of this data point on | ||||
the value axis of the plottable. | ||||
\li <tt>QCPRange valueRange() const</tt>\n Returns the range this data point spans in the value | ||||
axis coordinate. If the data is single-valued (e.g. QCPGraphData), this is simply a range with | ||||
both lower and upper set to the main data point value. However if the data points can represent | ||||
multiple values at once (e.g QCPFinancialData with its \a high, \a low, \a open and \a close | ||||
values at each \a key) this method should return the range those values span. This method is used | ||||
for example when determining the automatic axis rescaling of value axes (\ref | ||||
QCPAxis::rescale). | ||||
*/ | ||||
/* start documentation of inline functions */ | ||||
/*! \fn int QCPDataContainer<DataType>::size() const | ||||
Returns the number of data points in the container. | ||||
*/ | ||||
/*! \fn bool QCPDataContainer<DataType>::isEmpty() const | ||||
Returns whether this container holds no data points. | ||||
*/ | ||||
/*! \fn QCPDataContainer::const_iterator QCPDataContainer<DataType>::constBegin() const | ||||
Returns a const iterator to the first data point in this container. | ||||
*/ | ||||
/*! \fn QCPDataContainer::const_iterator QCPDataContainer<DataType>::constEnd() const | ||||
Returns a const iterator to the element past the last data point in this container. | ||||
*/ | ||||
/*! \fn QCPDataContainer::iterator QCPDataContainer<DataType>::begin() const | ||||
Returns a non-const iterator to the first data point in this container. | ||||
You can manipulate the data points in-place through the non-const iterators, but great care must | ||||
be taken when manipulating the sort key of a data point, see \ref sort, or the detailed | ||||
description of this class. | ||||
*/ | ||||
/*! \fn QCPDataContainer::iterator QCPDataContainer<DataType>::end() const | ||||
Returns a non-const iterator to the element past the last data point in this container. | ||||
You can manipulate the data points in-place through the non-const iterators, but great care must | ||||
be taken when manipulating the sort key of a data point, see \ref sort, or the detailed | ||||
description of this class. | ||||
*/ | ||||
/*! \fn QCPDataContainer::const_iterator QCPDataContainer<DataType>::at(int index) const | ||||
Returns a const iterator to the element with the specified \a index. If \a index points beyond | ||||
the available elements in this container, returns \ref constEnd, i.e. an iterator past the last | ||||
valid element. | ||||
You can use this method to easily obtain iterators from a \ref QCPDataRange, see the \ref | ||||
dataselection-accessing "data selection page" for an example. | ||||
*/ | ||||
/*! \fn QCPDataRange QCPDataContainer::dataRange() const | ||||
Returns a \ref QCPDataRange encompassing the entire data set of this container. This means the | ||||
begin index of the returned range is 0, and the end index is \ref size. | ||||
*/ | ||||
/* end documentation of inline functions */ | ||||
/*! | ||||
Constructs a QCPDataContainer used for plottable classes that represent a series of key-sorted | ||||
data | ||||
*/ | ||||
template <class DataType> | ||||
QCPDataContainer<DataType>::QCPDataContainer() | ||||
: mAutoSqueeze(true), mPreallocSize(0), mPreallocIteration(0) | ||||
{ | ||||
} | ||||
/*! | ||||
Sets whether the container automatically decides when to release memory from its post- and | ||||
preallocation pools when data points are removed. By default this is enabled and for typical | ||||
applications shouldn't be changed. | ||||
If auto squeeze is disabled, you can manually decide when to release pre-/postallocation with | ||||
\ref squeeze. | ||||
*/ | ||||
template <class DataType> | ||||
void QCPDataContainer<DataType>::setAutoSqueeze(bool enabled) | ||||
{ | ||||
if (mAutoSqueeze != enabled) { | ||||
mAutoSqueeze = enabled; | ||||
if (mAutoSqueeze) | ||||
performAutoSqueeze(); | ||||
} | ||||
} | ||||
/*! \overload | ||||
Replaces the current data in this container with the provided \a data. | ||||
\see add, remove | ||||
*/ | ||||
template <class DataType> | ||||
void QCPDataContainer<DataType>::set(const QCPDataContainer<DataType> &data) | ||||
{ | ||||
clear(); | ||||
add(data); | ||||
} | ||||
/*! \overload | ||||
Replaces the current data in this container with the provided \a data | ||||
If you can guarantee that the data points in \a data have ascending order with respect to the | ||||
DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run. | ||||
\see add, remove | ||||
*/ | ||||
template <class DataType> | ||||
void QCPDataContainer<DataType>::set(const QVector<DataType> &data, bool alreadySorted) | ||||
{ | ||||
mData = data; | ||||
mPreallocSize = 0; | ||||
mPreallocIteration = 0; | ||||
if (!alreadySorted) | ||||
sort(); | ||||
} | ||||
/*! \overload | ||||
Adds the provided \a data to the current data in this container. | ||||
\see set, remove | ||||
*/ | ||||
template <class DataType> | ||||
void QCPDataContainer<DataType>::add(const QCPDataContainer<DataType> &data) | ||||
{ | ||||
if (data.isEmpty()) | ||||
return; | ||||
const int n = data.size(); | ||||
const int oldSize = size(); | ||||
if (oldSize > 0 | ||||
&& !qcpLessThanSortKey<DataType>( | ||||
*constBegin(), | ||||
*(data.constEnd() | ||||
- 1))) // prepend if new data keys are all smaller than or equal to existing ones | ||||
{ | ||||
if (mPreallocSize < n) | ||||
preallocateGrow(n); | ||||
mPreallocSize -= n; | ||||
std::copy(data.constBegin(), data.constEnd(), begin()); | ||||
} | ||||
else // don't need to prepend, so append and merge if necessary | ||||
{ | ||||
mData.resize(mData.size() + n); | ||||
std::copy(data.constBegin(), data.constEnd(), end() - n); | ||||
if (oldSize > 0 | ||||
&& !qcpLessThanSortKey<DataType>(*(constEnd() - n - 1), | ||||
*(constEnd() - n))) // if appended range keys aren't | ||||
// all greater than existing ones, | ||||
// merge the two partitions | ||||
std::inplace_merge(begin(), end() - n, end(), qcpLessThanSortKey<DataType>); | ||||
} | ||||
} | ||||
/*! | ||||
Adds the provided data points in \a data to the current data. | ||||
If you can guarantee that the data points in \a data have ascending order with respect to the | ||||
DataType's sort key, set \a alreadySorted to true to avoid an unnecessary sorting run. | ||||
\see set, remove | ||||
*/ | ||||
template <class DataType> | ||||
void QCPDataContainer<DataType>::add(const QVector<DataType> &data, bool alreadySorted) | ||||
{ | ||||
if (data.isEmpty()) | ||||
return; | ||||
if (isEmpty()) { | ||||
set(data, alreadySorted); | ||||
return; | ||||
} | ||||
const int n = data.size(); | ||||
const int oldSize = size(); | ||||
if (alreadySorted && oldSize > 0 | ||||
&& !qcpLessThanSortKey<DataType>(*constBegin(), *(data.constEnd() - 1))) // prepend if new | ||||
// data is sorted | ||||
// and keys are all | ||||
// smaller than or | ||||
// equal to | ||||
// existing ones | ||||
{ | ||||
if (mPreallocSize < n) | ||||
preallocateGrow(n); | ||||
mPreallocSize -= n; | ||||
std::copy(data.constBegin(), data.constEnd(), begin()); | ||||
} | ||||
else // don't need to prepend, so append and then sort and merge if necessary | ||||
{ | ||||
mData.resize(mData.size() + n); | ||||
std::copy(data.constBegin(), data.constEnd(), end() - n); | ||||
if (!alreadySorted) // sort appended subrange if it wasn't already sorted | ||||
std::sort(end() - n, end(), qcpLessThanSortKey<DataType>); | ||||
if (oldSize > 0 | ||||
&& !qcpLessThanSortKey<DataType>(*(constEnd() - n - 1), | ||||
*(constEnd() - n))) // if appended range keys aren't | ||||
// all greater than existing ones, | ||||
// merge the two partitions | ||||
std::inplace_merge(begin(), end() - n, end(), qcpLessThanSortKey<DataType>); | ||||
} | ||||
} | ||||
/*! \overload | ||||
Adds the provided single data point to the current data. | ||||
\see remove | ||||
*/ | ||||
template <class DataType> | ||||
void QCPDataContainer<DataType>::add(const DataType &data) | ||||
{ | ||||
if (isEmpty() || !qcpLessThanSortKey<DataType>(data, *(constEnd() - 1))) // quickly handle | ||||
// appends if new data | ||||
// key is greater or | ||||
// equal to existing | ||||
// ones | ||||
{ | ||||
mData.append(data); | ||||
} | ||||
else if (qcpLessThanSortKey<DataType>( | ||||
data, *constBegin())) // quickly handle prepends using preallocated space | ||||
{ | ||||
if (mPreallocSize < 1) | ||||
preallocateGrow(1); | ||||
--mPreallocSize; | ||||
*begin() = data; | ||||
} | ||||
else // handle inserts, maintaining sorted keys | ||||
{ | ||||
QCPDataContainer<DataType>::iterator insertionPoint | ||||
= std::lower_bound(begin(), end(), data, qcpLessThanSortKey<DataType>); | ||||
mData.insert(insertionPoint, data); | ||||
} | ||||
} | ||||
/*! | ||||
Removes all data points with (sort-)keys smaller than or equal to \a sortKey. | ||||
\see removeAfter, remove, clear | ||||
*/ | ||||
template <class DataType> | ||||
void QCPDataContainer<DataType>::removeBefore(double sortKey) | ||||
{ | ||||
QCPDataContainer<DataType>::iterator it = begin(); | ||||
QCPDataContainer<DataType>::iterator itEnd = std::lower_bound( | ||||
begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>); | ||||
mPreallocSize += itEnd - it; // don't actually delete, just add it to the preallocated block (if | ||||
// it gets too large, squeeze will take care of it) | ||||
if (mAutoSqueeze) | ||||
performAutoSqueeze(); | ||||
} | ||||
/*! | ||||
Removes all data points with (sort-)keys greater than or equal to \a sortKey. | ||||
\see removeBefore, remove, clear | ||||
*/ | ||||
template <class DataType> | ||||
void QCPDataContainer<DataType>::removeAfter(double sortKey) | ||||
{ | ||||
QCPDataContainer<DataType>::iterator it = std::upper_bound( | ||||
begin(), end(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>); | ||||
QCPDataContainer<DataType>::iterator itEnd = end(); | ||||
mData.erase(it, itEnd); // typically adds it to the postallocated block | ||||
if (mAutoSqueeze) | ||||
performAutoSqueeze(); | ||||
} | ||||
/*! | ||||
Removes all data points with (sort-)keys between \a sortKeyFrom and \a sortKeyTo. if \a | ||||
sortKeyFrom is greater or equal to \a sortKeyTo, the function does nothing. To remove a single | ||||
data point with known (sort-)key, use \ref remove(double sortKey). | ||||
\see removeBefore, removeAfter, clear | ||||
*/ | ||||
template <class DataType> | ||||
void QCPDataContainer<DataType>::remove(double sortKeyFrom, double sortKeyTo) | ||||
{ | ||||
if (sortKeyFrom >= sortKeyTo || isEmpty()) | ||||
return; | ||||
QCPDataContainer<DataType>::iterator it = std::lower_bound( | ||||
begin(), end(), DataType::fromSortKey(sortKeyFrom), qcpLessThanSortKey<DataType>); | ||||
QCPDataContainer<DataType>::iterator itEnd = std::upper_bound( | ||||
it, end(), DataType::fromSortKey(sortKeyTo), qcpLessThanSortKey<DataType>); | ||||
mData.erase(it, itEnd); | ||||
if (mAutoSqueeze) | ||||
performAutoSqueeze(); | ||||
} | ||||
/*! \overload | ||||
Removes a single data point at \a sortKey. If the position is not known with absolute (binary) | ||||
precision, consider using \ref remove(double sortKeyFrom, double sortKeyTo) with a small | ||||
fuzziness interval around the suspected position, depeding on the precision with which the | ||||
(sort-)key is known. | ||||
\see removeBefore, removeAfter, clear | ||||
*/ | ||||
template <class DataType> | ||||
void QCPDataContainer<DataType>::remove(double sortKey) | ||||
{ | ||||
QCPDataContainer::iterator it = std::lower_bound(begin(), end(), DataType::fromSortKey(sortKey), | ||||
qcpLessThanSortKey<DataType>); | ||||
if (it != end() && it->sortKey() == sortKey) { | ||||
if (it == begin()) | ||||
++mPreallocSize; // don't actually delete, just add it to the preallocated block (if it | ||||
// gets too large, squeeze will take care of it) | ||||
else | ||||
mData.erase(it); | ||||
} | ||||
if (mAutoSqueeze) | ||||
performAutoSqueeze(); | ||||
} | ||||
/*! | ||||
Removes all data points. | ||||
\see remove, removeAfter, removeBefore | ||||
*/ | ||||
template <class DataType> | ||||
void QCPDataContainer<DataType>::clear() | ||||
{ | ||||
mData.clear(); | ||||
mPreallocIteration = 0; | ||||
mPreallocSize = 0; | ||||
} | ||||
/*! | ||||
Re-sorts all data points in the container by their sort key. | ||||
When setting, adding or removing points using the QCPDataContainer interface (\ref set, \ref add, | ||||
\ref remove, etc.), the container makes sure to always stay in a sorted state such that a full | ||||
resort is never necessary. However, if you choose to directly manipulate the sort key on data | ||||
points by accessing and modifying it through the non-const iterators (\ref begin, \ref end), it | ||||
is your responsibility to bring the container back into a sorted state before any other methods | ||||
are called on it. This can be achieved by calling this method immediately after finishing the | ||||
sort key manipulation. | ||||
*/ | ||||
template <class DataType> | ||||
void QCPDataContainer<DataType>::sort() | ||||
{ | ||||
std::sort(begin(), end(), qcpLessThanSortKey<DataType>); | ||||
} | ||||
/*! | ||||
Frees all unused memory that is currently in the preallocation and postallocation pools. | ||||
Note that QCPDataContainer automatically decides whether squeezing is necessary, if \ref | ||||
setAutoSqueeze is left enabled. It should thus not be necessary to use this method for typical | ||||
applications. | ||||
The parameters \a preAllocation and \a postAllocation control whether pre- and/or post allocation | ||||
should be freed, respectively. | ||||
*/ | ||||
template <class DataType> | ||||
void QCPDataContainer<DataType>::squeeze(bool preAllocation, bool postAllocation) | ||||
{ | ||||
if (preAllocation) { | ||||
if (mPreallocSize > 0) { | ||||
std::copy(begin(), end(), mData.begin()); | ||||
mData.resize(size()); | ||||
mPreallocSize = 0; | ||||
} | ||||
mPreallocIteration = 0; | ||||
} | ||||
if (postAllocation) | ||||
mData.squeeze(); | ||||
} | ||||
/*! | ||||
Returns an iterator to the data point with a (sort-)key that is equal to, just below, or just | ||||
above \a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be | ||||
considered, otherwise the one just above. | ||||
This can be used in conjunction with \ref findEnd to iterate over data points within a given key | ||||
range, including or excluding the bounding data points that are just beyond the specified range. | ||||
If \a expandedRange is true but there are no data points below \a sortKey, \ref constBegin is | ||||
returned. | ||||
If the container is empty, returns \ref constEnd. | ||||
\see findEnd, QCPPlottableInterface1D::findBegin | ||||
*/ | ||||
template <class DataType> | ||||
typename QCPDataContainer<DataType>::const_iterator | ||||
QCPDataContainer<DataType>::findBegin(double sortKey, bool expandedRange) const | ||||
{ | ||||
if (isEmpty()) | ||||
return constEnd(); | ||||
QCPDataContainer<DataType>::const_iterator it = std::lower_bound( | ||||
constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>); | ||||
if (expandedRange && it != constBegin()) // also covers it == constEnd case, and we know | ||||
// --constEnd is valid because mData isn't empty | ||||
--it; | ||||
return it; | ||||
} | ||||
/*! | ||||
Returns an iterator to the element after the data point with a (sort-)key that is equal to, just | ||||
above or just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey | ||||
will be considered, otherwise the one just below. | ||||
This can be used in conjunction with \ref findBegin to iterate over data points within a given | ||||
key range, including the bounding data points that are just below and above the specified range. | ||||
If \a expandedRange is true but there are no data points above \a sortKey, \ref constEnd is | ||||
returned. | ||||
If the container is empty, \ref constEnd is returned. | ||||
\see findBegin, QCPPlottableInterface1D::findEnd | ||||
*/ | ||||
template <class DataType> | ||||
typename QCPDataContainer<DataType>::const_iterator | ||||
QCPDataContainer<DataType>::findEnd(double sortKey, bool expandedRange) const | ||||
{ | ||||
if (isEmpty()) | ||||
return constEnd(); | ||||
QCPDataContainer<DataType>::const_iterator it = std::upper_bound( | ||||
constBegin(), constEnd(), DataType::fromSortKey(sortKey), qcpLessThanSortKey<DataType>); | ||||
if (expandedRange && it != constEnd()) | ||||
++it; | ||||
return it; | ||||
} | ||||
/*! | ||||
Returns the range encompassed by the (main-)key coordinate of all data points. The output | ||||
parameter \a foundRange indicates whether a sensible range was found. If this is false, you | ||||
should not use the returned QCPRange (e.g. the data container is empty or all points have the | ||||
same key). | ||||
Use \a signDomain to control which sign of the key coordinates should be considered. This is | ||||
relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a | ||||
time. | ||||
If the DataType reports that its main key is equal to the sort key (\a sortKeyIsMainKey), as is | ||||
the case for most plottables, this method uses this fact and finds the range very quickly. | ||||
\see valueRange | ||||
*/ | ||||
template <class DataType> | ||||
QCPRange QCPDataContainer<DataType>::keyRange(bool &foundRange, QCP::SignDomain signDomain) | ||||
{ | ||||
if (isEmpty()) { | ||||
foundRange = false; | ||||
return QCPRange(); | ||||
} | ||||
QCPRange range; | ||||
bool haveLower = false; | ||||
bool haveUpper = false; | ||||
double current; | ||||
QCPDataContainer<DataType>::const_iterator it = constBegin(); | ||||
QCPDataContainer<DataType>::const_iterator itEnd = constEnd(); | ||||
if (signDomain == QCP::sdBoth) // range may be anywhere | ||||
{ | ||||
if (DataType::sortKeyIsMainKey()) // if DataType is sorted by main key (e.g. QCPGraph, but | ||||
// not QCPCurve), use faster algorithm by finding just | ||||
// first and last key with non-NaN value | ||||
{ | ||||
while (it != itEnd) // find first non-nan going up from left | ||||
{ | ||||
if (!qIsNaN(it->mainValue())) { | ||||
range.lower = it->mainKey(); | ||||
haveLower = true; | ||||
break; | ||||
} | ||||
++it; | ||||
} | ||||
it = itEnd; | ||||
while (it != constBegin()) // find first non-nan going down from right | ||||
{ | ||||
--it; | ||||
if (!qIsNaN(it->mainValue())) { | ||||
range.upper = it->mainKey(); | ||||
haveUpper = true; | ||||
break; | ||||
} | ||||
} | ||||
} | ||||
else // DataType is not sorted by main key, go through all data points and accordingly | ||||
// expand range | ||||
{ | ||||
while (it != itEnd) { | ||||
if (!qIsNaN(it->mainValue())) { | ||||
current = it->mainKey(); | ||||
if (current < range.lower || !haveLower) { | ||||
range.lower = current; | ||||
haveLower = true; | ||||
} | ||||
if (current > range.upper || !haveUpper) { | ||||
range.upper = current; | ||||
haveUpper = true; | ||||
} | ||||
} | ||||
++it; | ||||
} | ||||
} | ||||
} | ||||
else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain | ||||
{ | ||||
while (it != itEnd) { | ||||
if (!qIsNaN(it->mainValue())) { | ||||
current = it->mainKey(); | ||||
if ((current < range.lower || !haveLower) && current < 0) { | ||||
range.lower = current; | ||||
haveLower = true; | ||||
} | ||||
if ((current > range.upper || !haveUpper) && current < 0) { | ||||
range.upper = current; | ||||
haveUpper = true; | ||||
} | ||||
} | ||||
++it; | ||||
} | ||||
} | ||||
else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain | ||||
{ | ||||
while (it != itEnd) { | ||||
if (!qIsNaN(it->mainValue())) { | ||||
current = it->mainKey(); | ||||
if ((current < range.lower || !haveLower) && current > 0) { | ||||
range.lower = current; | ||||
haveLower = true; | ||||
} | ||||
if ((current > range.upper || !haveUpper) && current > 0) { | ||||
range.upper = current; | ||||
haveUpper = true; | ||||
} | ||||
} | ||||
++it; | ||||
} | ||||
} | ||||
foundRange = haveLower && haveUpper; | ||||
return range; | ||||
} | ||||
/*! | ||||
Returns the range encompassed by the value coordinates of the data points in the specified key | ||||
range (\a inKeyRange), using the full \a DataType::valueRange reported by the data points. The | ||||
output parameter \a foundRange indicates whether a sensible range was found. If this is false, | ||||
you should not use the returned QCPRange (e.g. the data container is empty or all points have the | ||||
same value). | ||||
If \a inKeyRange has both lower and upper bound set to zero (is equal to <tt>QCPRange()</tt>), | ||||
all data points are considered, without any restriction on the keys. | ||||
Use \a signDomain to control which sign of the value coordinates should be considered. This is | ||||
relevant e.g. for logarithmic plots which can mathematically only display one sign domain at a | ||||
time. | ||||
\see keyRange | ||||
*/ | ||||
template <class DataType> | ||||
QCPRange QCPDataContainer<DataType>::valueRange(bool &foundRange, QCP::SignDomain signDomain, | ||||
const QCPRange &inKeyRange) | ||||
{ | ||||
if (isEmpty()) { | ||||
foundRange = false; | ||||
return QCPRange(); | ||||
} | ||||
QCPRange range; | ||||
const bool restrictKeyRange = inKeyRange != QCPRange(); | ||||
bool haveLower = false; | ||||
bool haveUpper = false; | ||||
QCPRange current; | ||||
QCPDataContainer<DataType>::const_iterator itBegin = constBegin(); | ||||
QCPDataContainer<DataType>::const_iterator itEnd = constEnd(); | ||||
if (DataType::sortKeyIsMainKey() && restrictKeyRange) { | ||||
itBegin = findBegin(inKeyRange.lower); | ||||
itEnd = findEnd(inKeyRange.upper); | ||||
} | ||||
if (signDomain == QCP::sdBoth) // range may be anywhere | ||||
{ | ||||
for (QCPDataContainer<DataType>::const_iterator it = itBegin; it != itEnd; ++it) { | ||||
if (restrictKeyRange | ||||
&& (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) | ||||
continue; | ||||
current = it->valueRange(); | ||||
if ((current.lower < range.lower || !haveLower) && !qIsNaN(current.lower)) { | ||||
range.lower = current.lower; | ||||
haveLower = true; | ||||
} | ||||
if ((current.upper > range.upper || !haveUpper) && !qIsNaN(current.upper)) { | ||||
range.upper = current.upper; | ||||
haveUpper = true; | ||||
} | ||||
} | ||||
} | ||||
else if (signDomain == QCP::sdNegative) // range may only be in the negative sign domain | ||||
{ | ||||
for (QCPDataContainer<DataType>::const_iterator it = itBegin; it != itEnd; ++it) { | ||||
if (restrictKeyRange | ||||
&& (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) | ||||
continue; | ||||
current = it->valueRange(); | ||||
if ((current.lower < range.lower || !haveLower) && current.lower < 0 | ||||
&& !qIsNaN(current.lower)) { | ||||
range.lower = current.lower; | ||||
haveLower = true; | ||||
} | ||||
if ((current.upper > range.upper || !haveUpper) && current.upper < 0 | ||||
&& !qIsNaN(current.upper)) { | ||||
range.upper = current.upper; | ||||
haveUpper = true; | ||||
} | ||||
} | ||||
} | ||||
else if (signDomain == QCP::sdPositive) // range may only be in the positive sign domain | ||||
{ | ||||
for (QCPDataContainer<DataType>::const_iterator it = itBegin; it != itEnd; ++it) { | ||||
if (restrictKeyRange | ||||
&& (it->mainKey() < inKeyRange.lower || it->mainKey() > inKeyRange.upper)) | ||||
continue; | ||||
current = it->valueRange(); | ||||
if ((current.lower < range.lower || !haveLower) && current.lower > 0 | ||||
&& !qIsNaN(current.lower)) { | ||||
range.lower = current.lower; | ||||
haveLower = true; | ||||
} | ||||
if ((current.upper > range.upper || !haveUpper) && current.upper > 0 | ||||
&& !qIsNaN(current.upper)) { | ||||
range.upper = current.upper; | ||||
haveUpper = true; | ||||
} | ||||
} | ||||
} | ||||
foundRange = haveLower && haveUpper; | ||||
return range; | ||||
} | ||||
/*! | ||||
Makes sure \a begin and \a end mark a data range that is both within the bounds of this data | ||||
r610 | container's data, as well as within the specified \a dataRange. The initial range described by | |||
the passed iterators \a begin and \a end is never expanded, only contracted if necessary. | ||||
r59 | ||||
This function doesn't require for \a dataRange to be within the bounds of this data container's | ||||
valid range. | ||||
*/ | ||||
template <class DataType> | ||||
void QCPDataContainer<DataType>::limitIteratorsToDataRange(const_iterator &begin, | ||||
const_iterator &end, | ||||
const QCPDataRange &dataRange) const | ||||
{ | ||||
QCPDataRange iteratorRange(begin - constBegin(), end - constBegin()); | ||||
iteratorRange = iteratorRange.bounded(dataRange.bounded(this->dataRange())); | ||||
begin = constBegin() + iteratorRange.begin(); | ||||
end = constBegin() + iteratorRange.end(); | ||||
} | ||||
/*! \internal | ||||
Increases the preallocation pool to have a size of at least \a minimumPreallocSize. Depending on | ||||
the preallocation history, the container will grow by more than requested, to speed up future | ||||
consecutive size increases. | ||||
if \a minimumPreallocSize is smaller than or equal to the current preallocation pool size, this | ||||
method does nothing. | ||||
*/ | ||||
template <class DataType> | ||||
void QCPDataContainer<DataType>::preallocateGrow(int minimumPreallocSize) | ||||
{ | ||||
if (minimumPreallocSize <= mPreallocSize) | ||||
return; | ||||
int newPreallocSize = minimumPreallocSize; | ||||
newPreallocSize | ||||
+= (1u << qBound(4, mPreallocIteration + 4, 15)) | ||||
- 12; // do 4 up to 32768-12 preallocation, doubling in each intermediate iteration | ||||
++mPreallocIteration; | ||||
int sizeDifference = newPreallocSize - mPreallocSize; | ||||
mData.resize(mData.size() + sizeDifference); | ||||
std::copy_backward(mData.begin() + mPreallocSize, mData.end() - sizeDifference, mData.end()); | ||||
mPreallocSize = newPreallocSize; | ||||
} | ||||
/*! \internal | ||||
This method decides, depending on the total allocation size and the size of the unused pre- and | ||||
postallocation pools, whether it is sensible to reduce the pools in order to free up unused | ||||
memory. It then possibly calls \ref squeeze to do the deallocation. | ||||
If \ref setAutoSqueeze is enabled, this method is called automatically each time data points are | ||||
removed from the container (e.g. \ref remove). | ||||
\note when changing the decision parameters, care must be taken not to cause a back-and-forth | ||||
between squeezing and reallocation due to the growth strategy of the internal QVector and \ref | ||||
preallocateGrow. The hysteresis between allocation and deallocation should be made high enough | ||||
(at the expense of possibly larger unused memory from time to time). | ||||
*/ | ||||
template <class DataType> | ||||
void QCPDataContainer<DataType>::performAutoSqueeze() | ||||
{ | ||||
const int totalAlloc = mData.capacity(); | ||||
const int postAllocSize = totalAlloc - mData.size(); | ||||
const int usedSize = size(); | ||||
bool shrinkPostAllocation = false; | ||||
bool shrinkPreAllocation = false; | ||||
if (totalAlloc | ||||
> 650000) // if allocation is larger, shrink earlier with respect to total used size | ||||
{ | ||||
shrinkPostAllocation = postAllocSize > usedSize * 1.5; // QVector grow strategy is 2^n for | ||||
// static data. Watch out not to | ||||
// oscillate! | ||||
shrinkPreAllocation = mPreallocSize * 10 > usedSize; | ||||
} | ||||
else if (totalAlloc > 1000) // below 10 MiB raw data be generous with preallocated memory, below | ||||
// 1k points don't even bother | ||||
{ | ||||
shrinkPostAllocation = postAllocSize > usedSize * 5; | ||||
shrinkPreAllocation | ||||
= mPreallocSize | ||||
> usedSize * 1.5; // preallocation can grow into postallocation, so can be smaller | ||||
} | ||||
if (shrinkPreAllocation || shrinkPostAllocation) | ||||
squeeze(shrinkPreAllocation, shrinkPostAllocation); | ||||
} | ||||
/* end of 'src/datacontainer.cpp' */ | ||||
/* end of 'src/datacontainer.h' */ | ||||
/* including file 'src/plottable.h', size 8312 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
class QCP_LIB_DECL QCPSelectionDecorator { | ||||
Q_GADGET | ||||
public: | ||||
QCPSelectionDecorator(); | ||||
virtual ~QCPSelectionDecorator(); | ||||
// getters: | ||||
QPen pen() const { return mPen; } | ||||
QBrush brush() const { return mBrush; } | ||||
QCPScatterStyle scatterStyle() const { return mScatterStyle; } | ||||
QCPScatterStyle::ScatterProperties usedScatterProperties() const | ||||
{ | ||||
return mUsedScatterProperties; | ||||
} | ||||
// setters: | ||||
void setPen(const QPen &pen); | ||||
void setBrush(const QBrush &brush); | ||||
void setScatterStyle(const QCPScatterStyle &scatterStyle, | ||||
QCPScatterStyle::ScatterProperties usedProperties | ||||
= QCPScatterStyle::spPen); | ||||
void setUsedScatterProperties(const QCPScatterStyle::ScatterProperties &properties); | ||||
// non-virtual methods: | ||||
void applyPen(QCPPainter *painter) const; | ||||
void applyBrush(QCPPainter *painter) const; | ||||
QCPScatterStyle getFinalScatterStyle(const QCPScatterStyle &unselectedStyle) const; | ||||
// introduced virtual methods: | ||||
virtual void copyFrom(const QCPSelectionDecorator *other); | ||||
virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection); | ||||
protected: | ||||
// property members: | ||||
QPen mPen; | ||||
QBrush mBrush; | ||||
QCPScatterStyle mScatterStyle; | ||||
QCPScatterStyle::ScatterProperties mUsedScatterProperties; | ||||
// non-property members: | ||||
QCPAbstractPlottable *mPlottable; | ||||
// introduced virtual methods: | ||||
virtual bool registerWithPlottable(QCPAbstractPlottable *plottable); | ||||
private: | ||||
Q_DISABLE_COPY(QCPSelectionDecorator) | ||||
friend class QCPAbstractPlottable; | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPSelectionDecorator *) | ||||
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(QPen pen READ pen WRITE setPen) | ||||
Q_PROPERTY(QBrush brush READ brush WRITE setBrush) | ||||
Q_PROPERTY(QCPAxis *keyAxis READ keyAxis WRITE setKeyAxis) | ||||
Q_PROPERTY(QCPAxis *valueAxis READ valueAxis WRITE setValueAxis) | ||||
Q_PROPERTY( | ||||
QCP::SelectionType selectable READ selectable WRITE setSelectable NOTIFY selectableChanged) | ||||
Q_PROPERTY(QCPDataSelection selection READ selection WRITE setSelection NOTIFY selectionChanged) | ||||
Q_PROPERTY(QCPSelectionDecorator *selectionDecorator READ selectionDecorator WRITE | ||||
setSelectionDecorator) | ||||
/// \endcond | ||||
public: | ||||
QCPAbstractPlottable(QCPAxis *keyAxis, QCPAxis *valueAxis); | ||||
virtual ~QCPAbstractPlottable(); | ||||
// getters: | ||||
QString name() const { return mName; } | ||||
bool antialiasedFill() const { return mAntialiasedFill; } | ||||
bool antialiasedScatters() const { return mAntialiasedScatters; } | ||||
QPen pen() const { return mPen; } | ||||
QBrush brush() const { return mBrush; } | ||||
QCPAxis *keyAxis() const { return mKeyAxis.data(); } | ||||
QCPAxis *valueAxis() const { return mValueAxis.data(); } | ||||
QCP::SelectionType selectable() const { return mSelectable; } | ||||
bool selected() const { return !mSelection.isEmpty(); } | ||||
QCPDataSelection selection() const { return mSelection; } | ||||
QCPSelectionDecorator *selectionDecorator() const { return mSelectionDecorator; } | ||||
// setters: | ||||
void setName(const QString &name); | ||||
void setAntialiasedFill(bool enabled); | ||||
void setAntialiasedScatters(bool enabled); | ||||
void setPen(const QPen &pen); | ||||
void setBrush(const QBrush &brush); | ||||
void setKeyAxis(QCPAxis *axis); | ||||
void setValueAxis(QCPAxis *axis); | ||||
Q_SLOT void setSelectable(QCP::SelectionType selectable); | ||||
Q_SLOT void setSelection(QCPDataSelection selection); | ||||
void setSelectionDecorator(QCPSelectionDecorator *decorator); | ||||
// introduced virtual methods: | ||||
virtual double selectTest(const QPointF &pos, bool onlySelectable, | ||||
QVariant *details = 0) const = 0; | ||||
virtual QCPPlottableInterface1D *interface1D() { return 0; } | ||||
virtual QCPRange getKeyRange(bool &foundRange, | ||||
QCP::SignDomain inSignDomain = QCP::sdBoth) const = 0; | ||||
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain = QCP::sdBoth, | ||||
const QCPRange &inKeyRange = QCPRange()) const = 0; | ||||
// non-property 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; | ||||
void rescaleAxes(bool onlyEnlarge = false) const; | ||||
void rescaleKeyAxis(bool onlyEnlarge = false) const; | ||||
void rescaleValueAxis(bool onlyEnlarge = false, bool inKeyRange = false) const; | ||||
bool addToLegend(QCPLegend *legend); | ||||
bool addToLegend(); | ||||
bool removeFromLegend(QCPLegend *legend) const; | ||||
bool removeFromLegend() const; | ||||
signals: | ||||
void selectionChanged(bool selected); | ||||
void selectionChanged(const QCPDataSelection &selection); | ||||
void selectableChanged(QCP::SelectionType selectable); | ||||
protected: | ||||
// property members: | ||||
QString mName; | ||||
bool mAntialiasedFill, mAntialiasedScatters; | ||||
QPen mPen; | ||||
QBrush mBrush; | ||||
QPointer<QCPAxis> mKeyAxis, mValueAxis; | ||||
QCP::SelectionType mSelectable; | ||||
QCPDataSelection mSelection; | ||||
QCPSelectionDecorator *mSelectionDecorator; | ||||
// reimplemented virtual methods: | ||||
virtual QRect clipRect() const Q_DECL_OVERRIDE; | ||||
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; | ||||
virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; | ||||
void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; | ||||
// events: | ||||
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, | ||||
bool *selectionStateChanged) Q_DECL_OVERRIDE; | ||||
virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; | ||||
// introduced virtual methods: | ||||
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const = 0; | ||||
// non-virtual methods: | ||||
void applyFillAntialiasingHint(QCPPainter *painter) const; | ||||
void applyScattersAntialiasingHint(QCPPainter *painter) const; | ||||
private: | ||||
Q_DISABLE_COPY(QCPAbstractPlottable) | ||||
friend class QCustomPlot; | ||||
friend class QCPAxis; | ||||
friend class QCPPlottableLegendItem; | ||||
}; | ||||
/* end of 'src/plottable.h' */ | ||||
r610 | /* including file 'src/item.h', size 9384 */ | |||
/* commit 681a87c5e5365a5c7187d20b4077031003c48449 2017-07-23 23:46:48 +0200 */ | ||||
r59 | ||||
class QCP_LIB_DECL QCPItemAnchor { | ||||
Q_GADGET | ||||
public: | ||||
QCPItemAnchor(QCustomPlot *parentPlot, QCPAbstractItem *parentItem, const QString &name, | ||||
int anchorId = -1); | ||||
virtual ~QCPItemAnchor(); | ||||
// getters: | ||||
QString name() const { return mName; } | ||||
virtual QPointF pixelPosition() const; | ||||
protected: | ||||
// property members: | ||||
QString mName; | ||||
// non-property members: | ||||
QCustomPlot *mParentPlot; | ||||
QCPAbstractItem *mParentItem; | ||||
int mAnchorId; | ||||
QSet<QCPItemPosition *> 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 { | ||||
Q_GADGET | ||||
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). | ||||
}; | ||||
Q_ENUMS(PositionType) | ||||
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; | ||||
r610 | virtual QPointF pixelPosition() const Q_DECL_OVERRIDE; | |||
r59 | ||||
// 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 setPixelPosition(const QPointF &pixelPosition); | ||||
protected: | ||||
// property members: | ||||
PositionType mPositionTypeX, mPositionTypeY; | ||||
QPointer<QCPAxis> mKeyAxis, mValueAxis; | ||||
QPointer<QCPAxisRect> mAxisRect; | ||||
double mKey, mValue; | ||||
QCPItemAnchor *mParentAnchorX, *mParentAnchorY; | ||||
// reimplemented virtual methods: | ||||
virtual QCPItemPosition *toQCPItemPosition() Q_DECL_OVERRIDE { return this; } | ||||
private: | ||||
Q_DISABLE_COPY(QCPItemPosition) | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPItemPosition::PositionType) | ||||
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: | ||||
explicit 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 Q_DECL_OVERRIDE = 0; | ||||
// non-virtual methods: | ||||
QList<QCPItemPosition *> positions() const { return mPositions; } | ||||
QList<QCPItemAnchor *> 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<QCPAxisRect> mClipAxisRect; | ||||
QList<QCPItemPosition *> mPositions; | ||||
QList<QCPItemAnchor *> mAnchors; | ||||
bool mSelectable, mSelected; | ||||
// reimplemented virtual methods: | ||||
virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; | ||||
virtual QRect clipRect() const Q_DECL_OVERRIDE; | ||||
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; | ||||
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; | ||||
// events: | ||||
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, | ||||
bool *selectionStateChanged) Q_DECL_OVERRIDE; | ||||
virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; | ||||
// introduced virtual methods: | ||||
virtual QPointF anchorPixelPosition(int anchorId) const; | ||||
// non-virtual methods: | ||||
double rectDistance(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; | ||||
}; | ||||
/* end of 'src/item.h' */ | ||||
r610 | /* including file 'src/core.h', size 14886 */ | |||
/* commit 29aafbce469a36d175d4fb32cbfd1f50a6072890 2016-10-12 19:21:24 +0200 */ | ||||
r59 | ||||
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) | ||||
Q_PROPERTY(bool openGl READ openGl WRITE setOpenGl) | ||||
/// \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 { | ||||
rpImmediateRefresh ///< Replots immediately and repaints the widget immediately by calling | ||||
/// QWidget::repaint() after the replot | ||||
, | ||||
rpQueuedRefresh ///< Replots immediately, but queues the widget repaint, by calling | ||||
/// QWidget::update() after the replot. This way multiple redundant widget | ||||
/// repaints can be avoided. | ||||
, | ||||
rpRefreshHint ///< Whether to use immediate or queued refresh depends on whether the | ||||
/// plotting hint \ref QCP::phImmediateRefresh is set, see \ref | ||||
/// setPlottingHints. | ||||
, | ||||
rpQueuedReplot ///< Queues the entire replot for the next event loop iteration. This way | ||||
/// multiple redundant replots can be avoided. The actual replot is then done | ||||
/// with \ref rpRefreshHint priority. | ||||
}; | ||||
Q_ENUMS(RefreshPriority) | ||||
explicit QCustomPlot(QWidget *parent = 0); | ||||
virtual ~QCustomPlot(); | ||||
// getters: | ||||
QRect viewport() const { return mViewport; } | ||||
double bufferDevicePixelRatio() const { return mBufferDevicePixelRatio; } | ||||
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; } | ||||
QCP::SelectionRectMode selectionRectMode() const { return mSelectionRectMode; } | ||||
QCPSelectionRect *selectionRect() const { return mSelectionRect; } | ||||
bool openGl() const { return mOpenGl; } | ||||
// setters: | ||||
void setViewport(const QRect &rect); | ||||
void setBufferDevicePixelRatio(double ratio); | ||||
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); | ||||
void setSelectionRectMode(QCP::SelectionRectMode mode); | ||||
void setSelectionRect(QCPSelectionRect *selectionRect); | ||||
void setOpenGl(bool enabled, int multisampling = 16); | ||||
// non-property methods: | ||||
// plottable interface: | ||||
QCPAbstractPlottable *plottable(int index); | ||||
QCPAbstractPlottable *plottable(); | ||||
bool removePlottable(QCPAbstractPlottable *plottable); | ||||
bool removePlottable(int index); | ||||
int clearPlottables(); | ||||
int plottableCount() const; | ||||
QList<QCPAbstractPlottable *> 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<QCPGraph *> selectedGraphs() const; | ||||
// item interface: | ||||
QCPAbstractItem *item(int index) const; | ||||
QCPAbstractItem *item() const; | ||||
bool removeItem(QCPAbstractItem *item); | ||||
bool removeItem(int index); | ||||
int clearItems(); | ||||
int itemCount() const; | ||||
QList<QCPAbstractItem *> 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<QCPAxisRect *> axisRects() const; | ||||
QCPLayoutElement *layoutElementAt(const QPointF &pos) const; | ||||
QCPAxisRect *axisRectAt(const QPointF &pos) const; | ||||
Q_SLOT void rescaleAxes(bool onlyVisiblePlottables = false); | ||||
QList<QCPAxis *> selectedAxes() const; | ||||
QList<QCPLegend *> selectedLegends() const; | ||||
Q_SLOT void deselectAll(); | ||||
bool savePdf(const QString &fileName, int width = 0, int height = 0, | ||||
QCP::ExportPen exportPen = QCP::epAllowCosmetic, | ||||
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, int resolution = 96, | ||||
QCP::ResolutionUnit resolutionUnit = QCP::ruDotsPerInch); | ||||
bool saveJpg(const QString &fileName, int width = 0, int height = 0, double scale = 1.0, | ||||
int quality = -1, int resolution = 96, | ||||
QCP::ResolutionUnit resolutionUnit = QCP::ruDotsPerInch); | ||||
bool saveBmp(const QString &fileName, int width = 0, int height = 0, double scale = 1.0, | ||||
int resolution = 96, QCP::ResolutionUnit resolutionUnit = QCP::ruDotsPerInch); | ||||
bool saveRastered(const QString &fileName, int width, int height, double scale, | ||||
const char *format, int quality = -1, int resolution = 96, | ||||
QCP::ResolutionUnit resolutionUnit = QCP::ruDotsPerInch); | ||||
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::rpRefreshHint); | ||||
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, int dataIndex, QMouseEvent *event); | ||||
void plottableDoubleClick(QCPAbstractPlottable *plottable, int dataIndex, 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 selectionChangedByUser(); | ||||
void beforeReplot(); | ||||
void afterReplot(); | ||||
protected: | ||||
// property members: | ||||
QRect mViewport; | ||||
double mBufferDevicePixelRatio; | ||||
QCPLayoutGrid *mPlotLayout; | ||||
bool mAutoAddPlottableToLegend; | ||||
QList<QCPAbstractPlottable *> mPlottables; | ||||
QList<QCPGraph *> | ||||
mGraphs; // extra list of plottables also in mPlottables that are of type QCPGraph | ||||
QList<QCPAbstractItem *> mItems; | ||||
QList<QCPLayer *> 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; | ||||
QCP::SelectionRectMode mSelectionRectMode; | ||||
QCPSelectionRect *mSelectionRect; | ||||
bool mOpenGl; | ||||
// non-property members: | ||||
QList<QSharedPointer<QCPAbstractPaintBuffer> > mPaintBuffers; | ||||
QPoint mMousePressPos; | ||||
bool mMouseHasMoved; | ||||
QPointer<QCPLayerable> mMouseEventLayerable; | ||||
r610 | QPointer<QCPLayerable> mMouseSignalLayerable; | |||
r59 | QVariant mMouseEventLayerableDetails; | |||
r610 | QVariant mMouseSignalLayerableDetails; | |||
r59 | bool mReplotting; | |||
bool mReplotQueued; | ||||
int mOpenGlMultisamples; | ||||
QCP::AntialiasedElements mOpenGlAntialiasedElementsBackup; | ||||
bool mOpenGlCacheLabelsBackup; | ||||
#ifdef QCP_OPENGL_FBO | ||||
QSharedPointer<QOpenGLContext> mGlContext; | ||||
QSharedPointer<QSurface> mGlSurface; | ||||
QSharedPointer<QOpenGLPaintDevice> mGlPaintDevice; | ||||
#endif | ||||
// reimplemented virtual methods: | ||||
virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; | ||||
virtual QSize sizeHint() const Q_DECL_OVERRIDE; | ||||
virtual void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; | ||||
virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; | ||||
virtual void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE; | ||||
virtual void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; | ||||
virtual void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; | ||||
virtual void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; | ||||
virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; | ||||
// introduced virtual methods: | ||||
virtual void draw(QCPPainter *painter); | ||||
virtual void updateLayout(); | ||||
virtual void axisRemoved(QCPAxis *axis); | ||||
virtual void legendRemoved(QCPLegend *legend); | ||||
Q_SLOT virtual void processRectSelection(QRect rect, QMouseEvent *event); | ||||
Q_SLOT virtual void processRectZoom(QRect rect, QMouseEvent *event); | ||||
Q_SLOT virtual void processPointSelection(QMouseEvent *event); | ||||
// non-virtual methods: | ||||
bool registerPlottable(QCPAbstractPlottable *plottable); | ||||
bool registerGraph(QCPGraph *graph); | ||||
bool registerItem(QCPAbstractItem *item); | ||||
void updateLayerIndices() const; | ||||
QCPLayerable *layerableAt(const QPointF &pos, bool onlySelectable, | ||||
QVariant *selectionDetails = 0) const; | ||||
QList<QCPLayerable *> layerableListAt(const QPointF &pos, bool onlySelectable, | ||||
QList<QVariant> *selectionDetails = 0) const; | ||||
void drawBackground(QCPPainter *painter); | ||||
void setupPaintBuffers(); | ||||
QCPAbstractPaintBuffer *createPaintBuffer(); | ||||
bool hasInvalidatedPaintBuffers(); | ||||
bool setupOpenGl(); | ||||
void freeOpenGl(); | ||||
friend class QCPLegend; | ||||
friend class QCPAxis; | ||||
friend class QCPLayer; | ||||
friend class QCPAxisRect; | ||||
friend class QCPAbstractPlottable; | ||||
friend class QCPGraph; | ||||
friend class QCPAbstractItem; | ||||
}; | ||||
Q_DECLARE_METATYPE(QCustomPlot::LayerInsertMode) | ||||
Q_DECLARE_METATYPE(QCustomPlot::RefreshPriority) | ||||
/* end of 'src/core.h' */ | ||||
r610 | /* including file 'src/plottable1d.h', size 4544 */ | |||
/* commit bee82298bd87b91a50093fb0b81cd7c734724a6f 2017-08-13 16:10:24 +0200 */ | ||||
r59 | ||||
r610 | class QCPPlottableInterface1D { | |||
r59 | public: | |||
r610 | virtual ~QCPPlottableInterface1D() {} | |||
r59 | // introduced pure virtual methods: | |||
virtual int dataCount() const = 0; | ||||
virtual double dataMainKey(int index) const = 0; | ||||
virtual double dataSortKey(int index) const = 0; | ||||
virtual double dataMainValue(int index) const = 0; | ||||
virtual QCPRange dataValueRange(int index) const = 0; | ||||
virtual QPointF dataPixelPosition(int index) const = 0; | ||||
virtual bool sortKeyIsMainKey() const = 0; | ||||
virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const = 0; | ||||
virtual int findBegin(double sortKey, bool expandedRange = true) const = 0; | ||||
virtual int findEnd(double sortKey, bool expandedRange = true) const = 0; | ||||
}; | ||||
template <class DataType> | ||||
r610 | class QCPAbstractPlottable1D : public QCPAbstractPlottable, | |||
public QCPPlottableInterface1D // no QCP_LIB_DECL, template class | ||||
// ends up in header (cpp included | ||||
// below) | ||||
{ | ||||
r59 | // No Q_OBJECT macro due to template class | |||
public: | ||||
QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis); | ||||
virtual ~QCPAbstractPlottable1D(); | ||||
// virtual methods of 1d plottable interface: | ||||
r610 | virtual int dataCount() const Q_DECL_OVERRIDE; | |||
virtual double dataMainKey(int index) const Q_DECL_OVERRIDE; | ||||
virtual double dataSortKey(int index) const Q_DECL_OVERRIDE; | ||||
virtual double dataMainValue(int index) const Q_DECL_OVERRIDE; | ||||
virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE; | ||||
virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; | ||||
virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE; | ||||
virtual QCPDataSelection selectTestRect(const QRectF &rect, | ||||
bool onlySelectable) const Q_DECL_OVERRIDE; | ||||
virtual int findBegin(double sortKey, bool expandedRange = true) const Q_DECL_OVERRIDE; | ||||
virtual int findEnd(double sortKey, bool expandedRange = true) const Q_DECL_OVERRIDE; | ||||
r59 | ||||
r610 | // reimplemented virtual methods: | |||
virtual double selectTest(const QPointF &pos, bool onlySelectable, | ||||
QVariant *details = 0) const Q_DECL_OVERRIDE; | ||||
virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; } | ||||
r59 | ||||
protected: | ||||
// property members: | ||||
QSharedPointer<QCPDataContainer<DataType> > mDataContainer; | ||||
// helpers for subclasses: | ||||
void getDataSegments(QList<QCPDataRange> &selectedSegments, | ||||
QList<QCPDataRange> &unselectedSegments) const; | ||||
void drawPolyline(QCPPainter *painter, const QVector<QPointF> &lineData) const; | ||||
private: | ||||
Q_DISABLE_COPY(QCPAbstractPlottable1D) | ||||
}; | ||||
// include implementation in header since it is a class template: | ||||
/* including file 'src/plottable1d.cpp', size 22240 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
//////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
//////////////////// QCPPlottableInterface1D | ||||
//////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
/*! \class QCPPlottableInterface1D | ||||
\brief Defines an abstract interface for one-dimensional plottables | ||||
This class contains only pure virtual methods which define a common interface to the data | ||||
of one-dimensional plottables. | ||||
For example, it is implemented by the template class \ref QCPAbstractPlottable1D (the preferred | ||||
base class for one-dimensional plottables). So if you use that template class as base class of | ||||
your one-dimensional plottable, you won't have to care about implementing the 1d interface | ||||
yourself. | ||||
If your plottable doesn't derive from \ref QCPAbstractPlottable1D but still wants to provide a 1d | ||||
interface (e.g. like \ref QCPErrorBars does), you should inherit from both \ref | ||||
QCPAbstractPlottable and \ref QCPPlottableInterface1D and accordingly reimplement the pure | ||||
virtual methods of the 1d interface, matching your data container. Also, reimplement \ref | ||||
QCPAbstractPlottable::interface1D to return the \c this pointer. | ||||
If you have a \ref QCPAbstractPlottable pointer, you can check whether it implements this | ||||
interface by calling \ref QCPAbstractPlottable::interface1D and testing it for a non-zero return | ||||
value. If it indeed implements this interface, you may use it to access the plottable's data | ||||
without needing to know the exact type of the plottable or its data point type. | ||||
*/ | ||||
/* start documentation of pure virtual functions */ | ||||
/*! \fn virtual int QCPPlottableInterface1D::dataCount() const = 0; | ||||
Returns the number of data points of the plottable. | ||||
*/ | ||||
/*! \fn virtual QCPDataSelection QCPPlottableInterface1D::selectTestRect(const QRectF &rect, bool | ||||
onlySelectable) const = 0; | ||||
Returns a data selection containing all the data points of this plottable which are contained (or | ||||
hit by) \a rect. This is used mainly in the selection rect interaction for data selection (\ref | ||||
dataselection "data selection mechanism"). | ||||
If \a onlySelectable is true, an empty QCPDataSelection is returned if this plottable is not | ||||
selectable (i.e. if \ref QCPAbstractPlottable::setSelectable is \ref QCP::stNone). | ||||
\note \a rect must be a normalized rect (positive or zero width and height). This is especially | ||||
important when using the rect of \ref QCPSelectionRect::accepted, which is not necessarily | ||||
normalized. Use <tt>QRect::normalized()</tt> when passing a rect which might not be normalized. | ||||
*/ | ||||
/*! \fn virtual double QCPPlottableInterface1D::dataMainKey(int index) const = 0 | ||||
Returns the main key of the data point at the given \a index. | ||||
What the main key is, is defined by the plottable's data type. See the \ref | ||||
qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming | ||||
convention. | ||||
*/ | ||||
/*! \fn virtual double QCPPlottableInterface1D::dataSortKey(int index) const = 0 | ||||
Returns the sort key of the data point at the given \a index. | ||||
What the sort key is, is defined by the plottable's data type. See the \ref | ||||
qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming | ||||
convention. | ||||
*/ | ||||
/*! \fn virtual double QCPPlottableInterface1D::dataMainValue(int index) const = 0 | ||||
Returns the main value of the data point at the given \a index. | ||||
What the main value is, is defined by the plottable's data type. See the \ref | ||||
qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming | ||||
convention. | ||||
*/ | ||||
/*! \fn virtual QCPRange QCPPlottableInterface1D::dataValueRange(int index) const = 0 | ||||
Returns the value range of the data point at the given \a index. | ||||
What the value range is, is defined by the plottable's data type. See the \ref | ||||
qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming | ||||
convention. | ||||
*/ | ||||
/*! \fn virtual QPointF QCPPlottableInterface1D::dataPixelPosition(int index) const = 0 | ||||
Returns the pixel position on the widget surface at which the data point at the given \a index | ||||
appears. | ||||
Usually this corresponds to the point of \ref dataMainKey/\ref dataMainValue, in pixel | ||||
coordinates. However, depending on the plottable, this might be a different apparent position | ||||
than just a coord-to-pixel transform of those values. For example, \ref QCPBars apparent data | ||||
values can be shifted depending on their stacking, bar grouping or configured base value. | ||||
*/ | ||||
/*! \fn virtual bool QCPPlottableInterface1D::sortKeyIsMainKey() const = 0 | ||||
Returns whether the sort key (\ref dataSortKey) is identical to the main key (\ref dataMainKey). | ||||
What the sort and main keys are, is defined by the plottable's data type. See the \ref | ||||
qcpdatacontainer-datatype "QCPDataContainer DataType" documentation for details about this naming | ||||
convention. | ||||
*/ | ||||
/*! \fn virtual int QCPPlottableInterface1D::findBegin(double sortKey, bool expandedRange) const = 0 | ||||
Returns the index of the data point with a (sort-)key that is equal to, just below, or just above | ||||
\a sortKey. If \a expandedRange is true, the data point just below \a sortKey will be considered, | ||||
otherwise the one just above. | ||||
This can be used in conjunction with \ref findEnd to iterate over data points within a given key | ||||
range, including or excluding the bounding data points that are just beyond the specified range. | ||||
If \a expandedRange is true but there are no data points below \a sortKey, 0 is returned. | ||||
If the container is empty, returns 0 (in that case, \ref findEnd will also return 0, so a loop | ||||
using these methods will not iterate over the index 0). | ||||
\see findEnd, QCPDataContainer::findBegin | ||||
*/ | ||||
/*! \fn virtual int QCPPlottableInterface1D::findEnd(double sortKey, bool expandedRange) const = 0 | ||||
Returns the index one after the data point with a (sort-)key that is equal to, just above, or | ||||
just below \a sortKey. If \a expandedRange is true, the data point just above \a sortKey will be | ||||
considered, otherwise the one just below. | ||||
This can be used in conjunction with \ref findBegin to iterate over data points within a given | ||||
key range, including the bounding data points that are just below and above the specified range. | ||||
If \a expandedRange is true but there are no data points above \a sortKey, the index just above | ||||
the | ||||
highest data point is returned. | ||||
If the container is empty, returns 0. | ||||
\see findBegin, QCPDataContainer::findEnd | ||||
*/ | ||||
/* end documentation of pure virtual functions */ | ||||
//////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
//////////////////// QCPAbstractPlottable1D | ||||
//////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
/*! \class QCPAbstractPlottable1D | ||||
\brief A template base class for plottables with one-dimensional data | ||||
This template class derives from \ref QCPAbstractPlottable and from the abstract interface \ref | ||||
QCPPlottableInterface1D. It serves as a base class for all one-dimensional data (i.e. data with | ||||
one key dimension), such as \ref QCPGraph and QCPCurve. | ||||
The template parameter \a DataType is the type of the data points of this plottable (e.g. \ref | ||||
QCPGraphData or \ref QCPCurveData). The main purpose of this base class is to provide the member | ||||
\a mDataContainer (a shared pointer to a \ref QCPDataContainer "QCPDataContainer<DataType>") and | ||||
implement the according virtual methods of the \ref QCPPlottableInterface1D, such that most | ||||
subclassed plottables don't need to worry about this anymore. | ||||
Further, it provides a convenience method for retrieving selected/unselected data segments via | ||||
\ref getDataSegments. This is useful when subclasses implement their \ref draw method and need to | ||||
draw selected segments with a different pen/brush than unselected segments (also see \ref | ||||
QCPSelectionDecorator). | ||||
This class implements basic functionality of \ref QCPAbstractPlottable::selectTest and \ref | ||||
QCPPlottableInterface1D::selectTestRect, assuming point-like data points, based on the 1D data | ||||
interface. In spite of that, most plottable subclasses will want to reimplement those methods | ||||
again, to provide a more accurate hit test based on their specific data visualization geometry. | ||||
*/ | ||||
/* start documentation of inline functions */ | ||||
/*! \fn QCPPlottableInterface1D *QCPAbstractPlottable1D::interface1D() | ||||
Returns a \ref QCPPlottableInterface1D pointer to this plottable, providing access to its 1D | ||||
interface. | ||||
\seebaseclassmethod | ||||
*/ | ||||
/* end documentation of inline functions */ | ||||
/*! | ||||
Forwards \a keyAxis and \a valueAxis to the \ref QCPAbstractPlottable::QCPAbstractPlottable | ||||
"QCPAbstractPlottable" constructor and allocates the \a mDataContainer. | ||||
*/ | ||||
template <class DataType> | ||||
QCPAbstractPlottable1D<DataType>::QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis) | ||||
: QCPAbstractPlottable(keyAxis, valueAxis), mDataContainer(new QCPDataContainer<DataType>) | ||||
{ | ||||
} | ||||
template <class DataType> | ||||
QCPAbstractPlottable1D<DataType>::~QCPAbstractPlottable1D() | ||||
{ | ||||
} | ||||
/*! | ||||
\copydoc QCPPlottableInterface1D::dataCount | ||||
*/ | ||||
template <class DataType> | ||||
int QCPAbstractPlottable1D<DataType>::dataCount() const | ||||
{ | ||||
return mDataContainer->size(); | ||||
} | ||||
/*! | ||||
\copydoc QCPPlottableInterface1D::dataMainKey | ||||
*/ | ||||
template <class DataType> | ||||
double QCPAbstractPlottable1D<DataType>::dataMainKey(int index) const | ||||
{ | ||||
if (index >= 0 && index < mDataContainer->size()) { | ||||
return (mDataContainer->constBegin() + index)->mainKey(); | ||||
} | ||||
else { | ||||
qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; | ||||
return 0; | ||||
} | ||||
} | ||||
/*! | ||||
\copydoc QCPPlottableInterface1D::dataSortKey | ||||
*/ | ||||
template <class DataType> | ||||
double QCPAbstractPlottable1D<DataType>::dataSortKey(int index) const | ||||
{ | ||||
if (index >= 0 && index < mDataContainer->size()) { | ||||
return (mDataContainer->constBegin() + index)->sortKey(); | ||||
} | ||||
else { | ||||
qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; | ||||
return 0; | ||||
} | ||||
} | ||||
/*! | ||||
\copydoc QCPPlottableInterface1D::dataMainValue | ||||
*/ | ||||
template <class DataType> | ||||
double QCPAbstractPlottable1D<DataType>::dataMainValue(int index) const | ||||
{ | ||||
if (index >= 0 && index < mDataContainer->size()) { | ||||
return (mDataContainer->constBegin() + index)->mainValue(); | ||||
} | ||||
else { | ||||
qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; | ||||
return 0; | ||||
} | ||||
} | ||||
/*! | ||||
\copydoc QCPPlottableInterface1D::dataValueRange | ||||
*/ | ||||
template <class DataType> | ||||
QCPRange QCPAbstractPlottable1D<DataType>::dataValueRange(int index) const | ||||
{ | ||||
if (index >= 0 && index < mDataContainer->size()) { | ||||
return (mDataContainer->constBegin() + index)->valueRange(); | ||||
} | ||||
else { | ||||
qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; | ||||
return QCPRange(0, 0); | ||||
} | ||||
} | ||||
/*! | ||||
\copydoc QCPPlottableInterface1D::dataPixelPosition | ||||
*/ | ||||
template <class DataType> | ||||
QPointF QCPAbstractPlottable1D<DataType>::dataPixelPosition(int index) const | ||||
{ | ||||
if (index >= 0 && index < mDataContainer->size()) { | ||||
const typename QCPDataContainer<DataType>::const_iterator it | ||||
= mDataContainer->constBegin() + index; | ||||
return coordsToPixels(it->mainKey(), it->mainValue()); | ||||
} | ||||
else { | ||||
qDebug() << Q_FUNC_INFO << "Index out of bounds" << index; | ||||
return QPointF(); | ||||
} | ||||
} | ||||
/*! | ||||
\copydoc QCPPlottableInterface1D::sortKeyIsMainKey | ||||
*/ | ||||
template <class DataType> | ||||
bool QCPAbstractPlottable1D<DataType>::sortKeyIsMainKey() const | ||||
{ | ||||
return DataType::sortKeyIsMainKey(); | ||||
} | ||||
/*! | ||||
Implements a rect-selection algorithm assuming the data (accessed via the 1D data interface) is | ||||
point-like. Most subclasses will want to reimplement this method again, to provide a more | ||||
accurate hit test based on the true data visualization geometry. | ||||
\seebaseclassmethod | ||||
*/ | ||||
template <class DataType> | ||||
QCPDataSelection QCPAbstractPlottable1D<DataType>::selectTestRect(const QRectF &rect, | ||||
bool onlySelectable) const | ||||
{ | ||||
QCPDataSelection result; | ||||
if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) | ||||
return result; | ||||
if (!mKeyAxis || !mValueAxis) | ||||
return result; | ||||
// convert rect given in pixels to ranges given in plot coordinates: | ||||
double key1, value1, key2, value2; | ||||
pixelsToCoords(rect.topLeft(), key1, value1); | ||||
pixelsToCoords(rect.bottomRight(), key2, value2); | ||||
QCPRange keyRange( | ||||
key1, | ||||
key2); // QCPRange normalizes internally so we don't have to care about whether key1 < key2 | ||||
QCPRange valueRange(value1, value2); | ||||
typename QCPDataContainer<DataType>::const_iterator begin = mDataContainer->constBegin(); | ||||
typename QCPDataContainer<DataType>::const_iterator end = mDataContainer->constEnd(); | ||||
if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can | ||||
// reduce the searched key interval: | ||||
{ | ||||
begin = mDataContainer->findBegin(keyRange.lower, false); | ||||
end = mDataContainer->findEnd(keyRange.upper, false); | ||||
} | ||||
if (begin == end) | ||||
return result; | ||||
int currentSegmentBegin | ||||
= -1; // -1 means we're currently not in a segment that's contained in rect | ||||
for (typename QCPDataContainer<DataType>::const_iterator it = begin; it != end; ++it) { | ||||
if (currentSegmentBegin == -1) { | ||||
if (valueRange.contains(it->mainValue()) | ||||
&& keyRange.contains(it->mainKey())) // start segment | ||||
currentSegmentBegin = it - mDataContainer->constBegin(); | ||||
} | ||||
else if (!valueRange.contains(it->mainValue()) | ||||
|| !keyRange.contains(it->mainKey())) // segment just ended | ||||
{ | ||||
result.addDataRange( | ||||
QCPDataRange(currentSegmentBegin, it - mDataContainer->constBegin()), false); | ||||
currentSegmentBegin = -1; | ||||
} | ||||
} | ||||
// process potential last segment: | ||||
if (currentSegmentBegin != -1) | ||||
result.addDataRange(QCPDataRange(currentSegmentBegin, end - mDataContainer->constBegin()), | ||||
false); | ||||
result.simplify(); | ||||
return result; | ||||
} | ||||
/*! | ||||
\copydoc QCPPlottableInterface1D::findBegin | ||||
*/ | ||||
template <class DataType> | ||||
int QCPAbstractPlottable1D<DataType>::findBegin(double sortKey, bool expandedRange) const | ||||
{ | ||||
return mDataContainer->findBegin(sortKey, expandedRange) - mDataContainer->constBegin(); | ||||
} | ||||
/*! | ||||
\copydoc QCPPlottableInterface1D::findEnd | ||||
*/ | ||||
template <class DataType> | ||||
int QCPAbstractPlottable1D<DataType>::findEnd(double sortKey, bool expandedRange) const | ||||
{ | ||||
return mDataContainer->findEnd(sortKey, expandedRange) - mDataContainer->constBegin(); | ||||
} | ||||
/*! | ||||
Implements a point-selection algorithm assuming the data (accessed via the 1D data interface) is | ||||
point-like. Most subclasses will want to reimplement this method again, to provide a more | ||||
accurate hit test based on the true data visualization geometry. | ||||
\seebaseclassmethod | ||||
*/ | ||||
template <class DataType> | ||||
double QCPAbstractPlottable1D<DataType>::selectTest(const QPointF &pos, bool onlySelectable, | ||||
QVariant *details) const | ||||
{ | ||||
if ((onlySelectable && mSelectable == QCP::stNone) || mDataContainer->isEmpty()) | ||||
return -1; | ||||
if (!mKeyAxis || !mValueAxis) | ||||
return -1; | ||||
QCPDataSelection selectionResult; | ||||
double minDistSqr = std::numeric_limits<double>::max(); | ||||
int minDistIndex = mDataContainer->size(); | ||||
typename QCPDataContainer<DataType>::const_iterator begin = mDataContainer->constBegin(); | ||||
typename QCPDataContainer<DataType>::const_iterator end = mDataContainer->constEnd(); | ||||
if (DataType::sortKeyIsMainKey()) // we can assume that data is sorted by main key, so can | ||||
// reduce the searched key interval: | ||||
{ | ||||
// determine which key range comes into question, taking selection tolerance around pos into | ||||
// account: | ||||
double posKeyMin, posKeyMax, dummy; | ||||
pixelsToCoords( | ||||
pos - QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), | ||||
posKeyMin, dummy); | ||||
pixelsToCoords( | ||||
pos + QPointF(mParentPlot->selectionTolerance(), mParentPlot->selectionTolerance()), | ||||
posKeyMax, dummy); | ||||
if (posKeyMin > posKeyMax) | ||||
qSwap(posKeyMin, posKeyMax); | ||||
begin = mDataContainer->findBegin(posKeyMin, true); | ||||
end = mDataContainer->findEnd(posKeyMax, true); | ||||
} | ||||
if (begin == end) | ||||
return -1; | ||||
QCPRange keyRange(mKeyAxis->range()); | ||||
QCPRange valueRange(mValueAxis->range()); | ||||
for (typename QCPDataContainer<DataType>::const_iterator it = begin; it != end; ++it) { | ||||
const double mainKey = it->mainKey(); | ||||
const double mainValue = it->mainValue(); | ||||
if (keyRange.contains(mainKey) | ||||
&& valueRange.contains(mainValue)) // make sure data point is inside visible range, for | ||||
// speedup in cases where sort key isn't main key and | ||||
// we iterate over all points | ||||
{ | ||||
const double currentDistSqr | ||||
= QCPVector2D(coordsToPixels(mainKey, mainValue) - pos).lengthSquared(); | ||||
if (currentDistSqr < minDistSqr) { | ||||
minDistSqr = currentDistSqr; | ||||
minDistIndex = it - mDataContainer->constBegin(); | ||||
} | ||||
} | ||||
} | ||||
if (minDistIndex != mDataContainer->size()) | ||||
selectionResult.addDataRange(QCPDataRange(minDistIndex, minDistIndex + 1), false); | ||||
selectionResult.simplify(); | ||||
if (details) | ||||
details->setValue(selectionResult); | ||||
return qSqrt(minDistSqr); | ||||
} | ||||
/*! | ||||
Splits all data into selected and unselected segments and outputs them via \a selectedSegments | ||||
and \a unselectedSegments, respectively. | ||||
This is useful when subclasses implement their \ref draw method and need to draw selected | ||||
segments with a different pen/brush than unselected segments (also see \ref | ||||
QCPSelectionDecorator). | ||||
\see setSelection | ||||
*/ | ||||
template <class DataType> | ||||
void QCPAbstractPlottable1D<DataType>::getDataSegments( | ||||
QList<QCPDataRange> &selectedSegments, QList<QCPDataRange> &unselectedSegments) const | ||||
{ | ||||
selectedSegments.clear(); | ||||
unselectedSegments.clear(); | ||||
if (mSelectable == QCP::stWhole) // stWhole selection type draws the entire plottable with | ||||
// selected style if mSelection isn't empty | ||||
{ | ||||
if (selected()) | ||||
selectedSegments << QCPDataRange(0, dataCount()); | ||||
else | ||||
unselectedSegments << QCPDataRange(0, dataCount()); | ||||
} | ||||
else { | ||||
QCPDataSelection sel(selection()); | ||||
sel.simplify(); | ||||
selectedSegments = sel.dataRanges(); | ||||
unselectedSegments = sel.inverse(QCPDataRange(0, dataCount())).dataRanges(); | ||||
} | ||||
} | ||||
/*! | ||||
A helper method which draws a line with the passed \a painter, according to the pixel data in \a | ||||
lineData. NaN points create gaps in the line, as expected from QCustomPlot's plottables (this is | ||||
the main difference to QPainter's regular drawPolyline, which handles NaNs by lagging or | ||||
crashing). | ||||
Further it uses a faster line drawing technique based on \ref QCPPainter::drawLine rather than \c | ||||
QPainter::drawPolyline if the configured \ref QCustomPlot::setPlottingHints() and \a painter | ||||
style allows. | ||||
*/ | ||||
template <class DataType> | ||||
void QCPAbstractPlottable1D<DataType>::drawPolyline(QCPPainter *painter, | ||||
const QVector<QPointF> &lineData) const | ||||
{ | ||||
// if drawing solid line and not in PDF, use much faster line drawing instead of polyline: | ||||
if (mParentPlot->plottingHints().testFlag(QCP::phFastPolylines) | ||||
&& painter->pen().style() == Qt::SolidLine | ||||
&& !painter->modes().testFlag(QCPPainter::pmVectorized) | ||||
&& !painter->modes().testFlag(QCPPainter::pmNoCaching)) { | ||||
int i = 0; | ||||
bool lastIsNan = false; | ||||
const int lineDataSize = lineData.size(); | ||||
while (i < lineDataSize | ||||
&& (qIsNaN(lineData.at(i).y()) | ||||
|| qIsNaN(lineData.at(i).x()))) // make sure first point is not NaN | ||||
++i; | ||||
++i; // because drawing works in 1 point retrospect | ||||
while (i < lineDataSize) { | ||||
if (!qIsNaN(lineData.at(i).y()) | ||||
&& !qIsNaN(lineData.at(i).x())) // NaNs create a gap in the line | ||||
{ | ||||
if (!lastIsNan) | ||||
painter->drawLine(lineData.at(i - 1), lineData.at(i)); | ||||
else | ||||
lastIsNan = false; | ||||
} | ||||
else | ||||
lastIsNan = true; | ||||
++i; | ||||
} | ||||
} | ||||
else { | ||||
int segmentStart = 0; | ||||
int i = 0; | ||||
const int lineDataSize = lineData.size(); | ||||
while (i < lineDataSize) { | ||||
if (qIsNaN(lineData.at(i).y()) || qIsNaN(lineData.at(i).x()) | ||||
|| qIsInf(lineData.at(i).y())) // NaNs create a gap in the line. Also filter Infs | ||||
// which make drawPolyline block | ||||
{ | ||||
painter->drawPolyline( | ||||
lineData.constData() + segmentStart, | ||||
i - segmentStart); // i, because we don't want to include the current NaN point | ||||
segmentStart = i + 1; | ||||
} | ||||
++i; | ||||
} | ||||
// draw last segment: | ||||
painter->drawPolyline(lineData.constData() + segmentStart, lineDataSize - segmentStart); | ||||
} | ||||
} | ||||
/* end of 'src/plottable1d.cpp' */ | ||||
/* end of 'src/plottable1d.h' */ | ||||
/* including file 'src/colorgradient.h', size 6243 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
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(); | ||||
QCPColorGradient(GradientPreset preset); | ||||
bool operator==(const QCPColorGradient &other) const; | ||||
bool operator!=(const QCPColorGradient &other) const { return !(*this == other); } | ||||
// getters: | ||||
int levelCount() const { return mLevelCount; } | ||||
QMap<double, QColor> colorStops() const { return mColorStops; } | ||||
ColorInterpolation colorInterpolation() const { return mColorInterpolation; } | ||||
bool periodic() const { return mPeriodic; } | ||||
// setters: | ||||
void setLevelCount(int n); | ||||
void setColorStops(const QMap<double, QColor> &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); | ||||
void colorize(const double *data, const unsigned char *alpha, 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: | ||||
// property members: | ||||
int mLevelCount; | ||||
QMap<double, QColor> mColorStops; | ||||
ColorInterpolation mColorInterpolation; | ||||
bool mPeriodic; | ||||
// non-property members: | ||||
QVector<QRgb> mColorBuffer; // have colors premultiplied with alpha (for usage with | ||||
// QImage::Format_ARGB32_Premultiplied) | ||||
bool mColorBufferInvalidated; | ||||
// non-virtual methods: | ||||
bool stopsUseAlpha() const; | ||||
void updateColorBuffer(); | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPColorGradient::ColorInterpolation) | ||||
Q_DECLARE_METATYPE(QCPColorGradient::GradientPreset) | ||||
/* end of 'src/colorgradient.h' */ | ||||
r610 | /* including file 'src/selectiondecorator-bracket.h', size 4442 */ | |||
/* commit 681a87c5e5365a5c7187d20b4077031003c48449 2017-07-23 23:46:48 +0200 */ | ||||
r59 | ||||
class QCP_LIB_DECL QCPSelectionDecoratorBracket : public QCPSelectionDecorator { | ||||
Q_GADGET | ||||
public: | ||||
/*! | ||||
Defines which shape is drawn at the boundaries of selected data ranges. | ||||
Some of the bracket styles further allow specifying a height and/or width, see \ref | ||||
setBracketHeight and \ref setBracketWidth. | ||||
*/ | ||||
enum BracketStyle { | ||||
bsSquareBracket ///< A square bracket is drawn. | ||||
, | ||||
bsHalfEllipse ///< A half ellipse is drawn. The size of the ellipse is given by the bracket | ||||
/// width/height properties. | ||||
, | ||||
bsEllipse ///< An ellipse is drawn. The size of the ellipse is given by the bracket | ||||
/// width/height properties. | ||||
, | ||||
bsPlus ///< A plus is drawn. | ||||
, | ||||
bsUserStyle ///< Start custom bracket styles at this index when subclassing and | ||||
/// reimplementing \ref drawBracket. | ||||
}; | ||||
Q_ENUMS(BracketStyle) | ||||
QCPSelectionDecoratorBracket(); | ||||
virtual ~QCPSelectionDecoratorBracket(); | ||||
// getters: | ||||
QPen bracketPen() const { return mBracketPen; } | ||||
QBrush bracketBrush() const { return mBracketBrush; } | ||||
int bracketWidth() const { return mBracketWidth; } | ||||
int bracketHeight() const { return mBracketHeight; } | ||||
BracketStyle bracketStyle() const { return mBracketStyle; } | ||||
bool tangentToData() const { return mTangentToData; } | ||||
int tangentAverage() const { return mTangentAverage; } | ||||
// setters: | ||||
void setBracketPen(const QPen &pen); | ||||
void setBracketBrush(const QBrush &brush); | ||||
void setBracketWidth(int width); | ||||
void setBracketHeight(int height); | ||||
void setBracketStyle(BracketStyle style); | ||||
void setTangentToData(bool enabled); | ||||
void setTangentAverage(int pointCount); | ||||
// introduced virtual methods: | ||||
virtual void drawBracket(QCPPainter *painter, int direction) const; | ||||
// virtual methods: | ||||
r610 | virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection) Q_DECL_OVERRIDE; | |||
r59 | ||||
protected: | ||||
// property members: | ||||
QPen mBracketPen; | ||||
QBrush mBracketBrush; | ||||
int mBracketWidth; | ||||
int mBracketHeight; | ||||
BracketStyle mBracketStyle; | ||||
bool mTangentToData; | ||||
int mTangentAverage; | ||||
// non-virtual methods: | ||||
double getTangentAngle(const QCPPlottableInterface1D *interface1d, int dataIndex, | ||||
int direction) const; | ||||
QPointF getPixelCoordinates(const QCPPlottableInterface1D *interface1d, int dataIndex) const; | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPSelectionDecoratorBracket::BracketStyle) | ||||
/* end of 'src/selectiondecorator-bracket.h' */ | ||||
r610 | /* including file 'src/layoutelements/layoutelement-axisrect.h', size 7507 */ | |||
/* commit 77ba168312f935543fc31d1ae9b4cdcf34aae4f9 2017-08-13 18:29:48 +0200 */ | ||||
r59 | ||||
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; } | ||||
QBrush backgroundBrush() const { return mBackgroundBrush; } | ||||
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); | ||||
QList<QCPAxis *> rangeDragAxes(Qt::Orientation orientation); | ||||
QList<QCPAxis *> rangeZoomAxes(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 setRangeDragAxes(QList<QCPAxis *> axes); | ||||
void setRangeDragAxes(QList<QCPAxis *> horizontal, QList<QCPAxis *> vertical); | ||||
void setRangeZoomAxes(QCPAxis *horizontal, QCPAxis *vertical); | ||||
void setRangeZoomAxes(QList<QCPAxis *> axes); | ||||
void setRangeZoomAxes(QList<QCPAxis *> horizontal, QList<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<QCPAxis *> axes(QCPAxis::AxisTypes types) const; | ||||
QList<QCPAxis *> axes() const; | ||||
QCPAxis *addAxis(QCPAxis::AxisType type, QCPAxis *axis = 0); | ||||
QList<QCPAxis *> addAxes(QCPAxis::AxisTypes types); | ||||
bool removeAxis(QCPAxis *axis); | ||||
QCPLayoutInset *insetLayout() const { return mInsetLayout; } | ||||
void zoom(const QRectF &pixelRect); | ||||
void zoom(const QRectF &pixelRect, const QList<QCPAxis *> &affectedAxes); | ||||
void setupFullAxesBox(bool connectRanges = false); | ||||
QList<QCPAbstractPlottable *> plottables() const; | ||||
QList<QCPGraph *> graphs() const; | ||||
QList<QCPAbstractItem *> 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) Q_DECL_OVERRIDE; | ||||
virtual QList<QCPLayoutElement *> elements(bool recursive) const Q_DECL_OVERRIDE; | ||||
protected: | ||||
// property members: | ||||
QBrush mBackgroundBrush; | ||||
QPixmap mBackgroundPixmap; | ||||
QPixmap mScaledBackgroundPixmap; | ||||
bool mBackgroundScaled; | ||||
Qt::AspectRatioMode mBackgroundScaledMode; | ||||
QCPLayoutInset *mInsetLayout; | ||||
Qt::Orientations mRangeDrag, mRangeZoom; | ||||
QList<QPointer<QCPAxis> > mRangeDragHorzAxis, mRangeDragVertAxis; | ||||
QList<QPointer<QCPAxis> > mRangeZoomHorzAxis, mRangeZoomVertAxis; | ||||
double mRangeZoomFactorHorz, mRangeZoomFactorVert; | ||||
// non-property members: | ||||
QList<QCPRange> mDragStartHorzRange, mDragStartVertRange; | ||||
QCP::AntialiasedElements mAADragBackup, mNotAADragBackup; | ||||
bool mDragging; | ||||
QHash<QCPAxis::AxisType, QList<QCPAxis *> > mAxes; | ||||
// reimplemented virtual methods: | ||||
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; | ||||
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; | ||||
virtual int calculateAutoMargin(QCP::MarginSide side) Q_DECL_OVERRIDE; | ||||
virtual void layoutChanged() Q_DECL_OVERRIDE; | ||||
// events: | ||||
virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; | ||||
virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; | ||||
virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; | ||||
virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; | ||||
// non-property methods: | ||||
void drawBackground(QCPPainter *painter); | ||||
void updateAxesOffset(QCPAxis::AxisType type); | ||||
private: | ||||
Q_DISABLE_COPY(QCPAxisRect) | ||||
friend class QCustomPlot; | ||||
}; | ||||
/* end of 'src/layoutelements/layoutelement-axisrect.h' */ | ||||
/* including file 'src/layoutelements/layoutelement-legend.h', size 10392 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
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 Q_DECL_OVERRIDE; | ||||
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 Q_DECL_OVERRIDE; | ||||
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; | ||||
virtual QRect clipRect() const Q_DECL_OVERRIDE; | ||||
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE = 0; | ||||
// events: | ||||
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, | ||||
bool *selectionStateChanged) Q_DECL_OVERRIDE; | ||||
virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; | ||||
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) Q_DECL_OVERRIDE; | ||||
virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; | ||||
// 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 ///< <tt>0x000</tt> None | ||||
, | ||||
spLegendBox = 0x001 ///< <tt>0x001</tt> The legend box (frame) | ||||
, | ||||
spItems = 0x002 ///< <tt>0x002</tt> Legend items individually (see \ref selectedItems) | ||||
}; | ||||
Q_ENUMS(SelectablePart) | ||||
Q_FLAGS(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 Q_DECL_OVERRIDE; | ||||
// 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<QCPAbstractLegendItem *> 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) Q_DECL_OVERRIDE; | ||||
virtual QCP::Interaction selectionCategory() const Q_DECL_OVERRIDE; | ||||
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; | ||||
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; | ||||
// events: | ||||
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, | ||||
bool *selectionStateChanged) Q_DECL_OVERRIDE; | ||||
virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; | ||||
// 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) | ||||
/* end of 'src/layoutelements/layoutelement-legend.h' */ | ||||
/* including file 'src/layoutelements/layoutelement-textelement.h', size 5343 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
class QCP_LIB_DECL QCPTextElement : 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 QCPTextElement(QCustomPlot *parentPlot); | ||||
QCPTextElement(QCustomPlot *parentPlot, const QString &text); | ||||
QCPTextElement(QCustomPlot *parentPlot, const QString &text, double pointSize); | ||||
QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QString &fontFamily, | ||||
double pointSize); | ||||
QCPTextElement(QCustomPlot *parentPlot, const QString &text, const QFont &font); | ||||
// getters: | ||||
QString text() const { return mText; } | ||||
int textFlags() const { return mTextFlags; } | ||||
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 setTextFlags(int flags); | ||||
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 Q_DECL_OVERRIDE; | ||||
virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; | ||||
virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; | ||||
virtual void mouseDoubleClickEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; | ||||
signals: | ||||
void selectionChanged(bool selected); | ||||
void selectableChanged(bool selectable); | ||||
void clicked(QMouseEvent *event); | ||||
void doubleClicked(QMouseEvent *event); | ||||
protected: | ||||
// property members: | ||||
QString mText; | ||||
int mTextFlags; | ||||
QFont mFont; | ||||
QColor mTextColor; | ||||
QFont mSelectedFont; | ||||
QColor mSelectedTextColor; | ||||
QRect mTextBoundingRect; | ||||
bool mSelectable, mSelected; | ||||
// reimplemented virtual methods: | ||||
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; | ||||
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; | ||||
virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE; | ||||
virtual QSize maximumSizeHint() const Q_DECL_OVERRIDE; | ||||
// events: | ||||
virtual void selectEvent(QMouseEvent *event, bool additive, const QVariant &details, | ||||
bool *selectionStateChanged) Q_DECL_OVERRIDE; | ||||
virtual void deselectEvent(bool *selectionStateChanged) Q_DECL_OVERRIDE; | ||||
// non-virtual methods: | ||||
QFont mainFont() const; | ||||
QColor mainTextColor() const; | ||||
private: | ||||
Q_DISABLE_COPY(QCPTextElement) | ||||
}; | ||||
/* end of 'src/layoutelements/layoutelement-textelement.h' */ | ||||
r610 | /* including file 'src/layoutelements/layoutelement-colorscale.h', size 5923 */ | |||
/* commit 681a87c5e5365a5c7187d20b4077031003c48449 2017-07-23 23:46:48 +0200 */ | ||||
r59 | ||||
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; | ||||
r610 | virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; | |||
r59 | 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<QCPColorMap *> colorMaps() const; | ||||
void rescaleDataRange(bool onlyVisibleMaps); | ||||
// reimplemented virtual methods: | ||||
virtual void update(UpdatePhase phase) Q_DECL_OVERRIDE; | ||||
signals: | ||||
void dataRangeChanged(const QCPRange &newRange); | ||||
void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); | ||||
void gradientChanged(const QCPColorGradient &newGradient); | ||||
protected: | ||||
// property members: | ||||
QCPAxis::AxisType mType; | ||||
QCPRange mDataRange; | ||||
QCPAxis::ScaleType mDataScaleType; | ||||
QCPColorGradient mGradient; | ||||
int mBarWidth; | ||||
// non-property members: | ||||
QPointer<QCPColorScaleAxisRectPrivate> mAxisRect; | ||||
QPointer<QCPAxis> mColorAxis; | ||||
// reimplemented virtual methods: | ||||
virtual void applyDefaultAntialiasingHint(QCPPainter *painter) const Q_DECL_OVERRIDE; | ||||
// events: | ||||
virtual void mousePressEvent(QMouseEvent *event, const QVariant &details) Q_DECL_OVERRIDE; | ||||
virtual void mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; | ||||
virtual void mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) Q_DECL_OVERRIDE; | ||||
virtual void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; | ||||
private: | ||||
Q_DISABLE_COPY(QCPColorScale) | ||||
friend class QCPColorScaleAxisRectPrivate; | ||||
}; | ||||
/* end of 'src/layoutelements/layoutelement-colorscale.h' */ | ||||
r610 | /* including file 'src/plottables/plottable-graph.h', size 9294 */ | |||
/* commit f3881770eaf7366171012ad01cad2aaf5f61dd27 2017-06-23 02:48:21 +0200 */ | ||||
r59 | ||||
class QCP_LIB_DECL QCPGraphData { | ||||
public: | ||||
QCPGraphData(); | ||||
QCPGraphData(double key, double value); | ||||
inline double sortKey() const { return key; } | ||||
inline static QCPGraphData fromSortKey(double sortKey) { return QCPGraphData(sortKey, 0); } | ||||
inline static bool sortKeyIsMainKey() { return true; } | ||||
inline double mainKey() const { return key; } | ||||
inline double mainValue() const { return value; } | ||||
inline QCPRange valueRange() const { return QCPRange(value, value); } | ||||
double key, value; | ||||
}; | ||||
Q_DECLARE_TYPEINFO(QCPGraphData, Q_PRIMITIVE_TYPE); | ||||
/*! \typedef QCPGraphDataContainer | ||||
Container for storing \ref QCPGraphData points. The data is stored sorted by \a key. | ||||
This template instantiation is the container in which QCPGraph holds its data. For details about | ||||
the generic container, see the documentation of the class template \ref QCPDataContainer. | ||||
\see QCPGraphData, QCPGraph::setData | ||||
*/ | ||||
typedef QCPDataContainer<QCPGraphData> QCPGraphDataContainer; | ||||
class QCP_LIB_DECL QCPGraph : public QCPAbstractPlottable1D<QCPGraphData> { | ||||
Q_OBJECT | ||||
/// \cond INCLUDE_QPROPERTIES | ||||
Q_PROPERTY(LineStyle lineStyle READ lineStyle WRITE setLineStyle) | ||||
Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) | ||||
Q_PROPERTY(int scatterSkip READ scatterSkip WRITE setScatterSkip) | ||||
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) | ||||
explicit QCPGraph(QCPAxis *keyAxis, QCPAxis *valueAxis); | ||||
virtual ~QCPGraph(); | ||||
// getters: | ||||
QSharedPointer<QCPGraphDataContainer> data() const { return mDataContainer; } | ||||
LineStyle lineStyle() const { return mLineStyle; } | ||||
QCPScatterStyle scatterStyle() const { return mScatterStyle; } | ||||
int scatterSkip() const { return mScatterSkip; } | ||||
QCPGraph *channelFillGraph() const { return mChannelFillGraph.data(); } | ||||
bool adaptiveSampling() const { return mAdaptiveSampling; } | ||||
// setters: | ||||
void setData(QSharedPointer<QCPGraphDataContainer> data); | ||||
void setData(const QVector<double> &keys, const QVector<double> &values, | ||||
bool alreadySorted = false); | ||||
void setLineStyle(LineStyle ls); | ||||
void setScatterStyle(const QCPScatterStyle &style); | ||||
void setScatterSkip(int skip); | ||||
void setChannelFillGraph(QCPGraph *targetGraph); | ||||
void setAdaptiveSampling(bool enabled); | ||||
// non-property methods: | ||||
void addData(const QVector<double> &keys, const QVector<double> &values, | ||||
bool alreadySorted = false); | ||||
void addData(double key, double value); | ||||
// reimplemented virtual methods: | ||||
virtual double selectTest(const QPointF &pos, bool onlySelectable, | ||||
QVariant *details = 0) const Q_DECL_OVERRIDE; | ||||
virtual QCPRange getKeyRange(bool &foundRange, | ||||
QCP::SignDomain inSignDomain = QCP::sdBoth) const Q_DECL_OVERRIDE; | ||||
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain = QCP::sdBoth, | ||||
const QCPRange &inKeyRange = QCPRange()) const Q_DECL_OVERRIDE; | ||||
protected: | ||||
// property members: | ||||
LineStyle mLineStyle; | ||||
QCPScatterStyle mScatterStyle; | ||||
int mScatterSkip; | ||||
QPointer<QCPGraph> mChannelFillGraph; | ||||
bool mAdaptiveSampling; | ||||
// reimplemented virtual methods: | ||||
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; | ||||
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; | ||||
// introduced virtual methods: | ||||
virtual void drawFill(QCPPainter *painter, QVector<QPointF> *lines) const; | ||||
virtual void drawScatterPlot(QCPPainter *painter, const QVector<QPointF> &scatters, | ||||
const QCPScatterStyle &style) const; | ||||
virtual void drawLinePlot(QCPPainter *painter, const QVector<QPointF> &lines) const; | ||||
virtual void drawImpulsePlot(QCPPainter *painter, const QVector<QPointF> &lines) const; | ||||
virtual void getOptimizedLineData(QVector<QCPGraphData> *lineData, | ||||
const QCPGraphDataContainer::const_iterator &begin, | ||||
const QCPGraphDataContainer::const_iterator &end) const; | ||||
virtual void getOptimizedScatterData(QVector<QCPGraphData> *scatterData, | ||||
QCPGraphDataContainer::const_iterator begin, | ||||
QCPGraphDataContainer::const_iterator end) const; | ||||
// non-virtual methods: | ||||
void getVisibleDataBounds(QCPGraphDataContainer::const_iterator &begin, | ||||
QCPGraphDataContainer::const_iterator &end, | ||||
const QCPDataRange &rangeRestriction) const; | ||||
void getLines(QVector<QPointF> *lines, const QCPDataRange &dataRange) const; | ||||
void getScatters(QVector<QPointF> *scatters, const QCPDataRange &dataRange) const; | ||||
QVector<QPointF> dataToLines(const QVector<QCPGraphData> &data) const; | ||||
QVector<QPointF> dataToStepLeftLines(const QVector<QCPGraphData> &data) const; | ||||
QVector<QPointF> dataToStepRightLines(const QVector<QCPGraphData> &data) const; | ||||
QVector<QPointF> dataToStepCenterLines(const QVector<QCPGraphData> &data) const; | ||||
QVector<QPointF> dataToImpulseLines(const QVector<QCPGraphData> &data) const; | ||||
r610 | QVector<QCPDataRange> getNonNanSegments(const QVector<QPointF> *lineData, | |||
Qt::Orientation keyOrientation) const; | ||||
QVector<QPair<QCPDataRange, QCPDataRange> > | ||||
getOverlappingSegments(QVector<QCPDataRange> thisSegments, const QVector<QPointF> *thisData, | ||||
QVector<QCPDataRange> otherSegments, | ||||
const QVector<QPointF> *otherData) const; | ||||
bool segmentsIntersect(double aLower, double aUpper, double bLower, double bUpper, | ||||
int &bPrecedence) const; | ||||
QPointF getFillBasePoint(QPointF matchingDataPoint) const; | ||||
const QPolygonF getFillPolygon(const QVector<QPointF> *lineData, QCPDataRange segment) const; | ||||
const QPolygonF getChannelFillPolygon(const QVector<QPointF> *lineData, | ||||
QCPDataRange thisSegment, | ||||
const QVector<QPointF> *otherData, | ||||
QCPDataRange otherSegment) const; | ||||
r59 | int findIndexBelowX(const QVector<QPointF> *data, double x) const; | |||
int findIndexAboveX(const QVector<QPointF> *data, double x) const; | ||||
int findIndexBelowY(const QVector<QPointF> *data, double y) const; | ||||
int findIndexAboveY(const QVector<QPointF> *data, double y) const; | ||||
double pointDistance(const QPointF &pixelPoint, | ||||
QCPGraphDataContainer::const_iterator &closestData) const; | ||||
friend class QCustomPlot; | ||||
friend class QCPLegend; | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPGraph::LineStyle) | ||||
/* end of 'src/plottables/plottable-graph.h' */ | ||||
/* including file 'src/plottables/plottable-curve.h', size 7409 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
class QCP_LIB_DECL QCPCurveData { | ||||
public: | ||||
QCPCurveData(); | ||||
QCPCurveData(double t, double key, double value); | ||||
inline double sortKey() const { return t; } | ||||
inline static QCPCurveData fromSortKey(double sortKey) { return QCPCurveData(sortKey, 0, 0); } | ||||
inline static bool sortKeyIsMainKey() { return false; } | ||||
inline double mainKey() const { return key; } | ||||
inline double mainValue() const { return value; } | ||||
inline QCPRange valueRange() const { return QCPRange(value, value); } | ||||
double t, key, value; | ||||
}; | ||||
Q_DECLARE_TYPEINFO(QCPCurveData, Q_PRIMITIVE_TYPE); | ||||
/*! \typedef QCPCurveDataContainer | ||||
Container for storing \ref QCPCurveData points. The data is stored sorted by \a t, so the \a | ||||
sortKey() (returning \a t) is different from \a mainKey() (returning \a key). | ||||
This template instantiation is the container in which QCPCurve holds its data. For details about | ||||
the generic container, see the documentation of the class template \ref QCPDataContainer. | ||||
\see QCPCurveData, QCPCurve::setData | ||||
*/ | ||||
typedef QCPDataContainer<QCPCurveData> QCPCurveDataContainer; | ||||
class QCP_LIB_DECL QCPCurve : public QCPAbstractPlottable1D<QCPCurveData> { | ||||
Q_OBJECT | ||||
/// \cond INCLUDE_QPROPERTIES | ||||
Q_PROPERTY(QCPScatterStyle scatterStyle READ scatterStyle WRITE setScatterStyle) | ||||
Q_PROPERTY(int scatterSkip READ scatterSkip WRITE setScatterSkip) | ||||
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 | ||||
}; | ||||
Q_ENUMS(LineStyle) | ||||
explicit QCPCurve(QCPAxis *keyAxis, QCPAxis *valueAxis); | ||||
virtual ~QCPCurve(); | ||||
// getters: | ||||
QSharedPointer<QCPCurveDataContainer> data() const { return mDataContainer; } | ||||
QCPScatterStyle scatterStyle() const { return mScatterStyle; } | ||||
int scatterSkip() const { return mScatterSkip; } | ||||
LineStyle lineStyle() const { return mLineStyle; } | ||||
// setters: | ||||
void setData(QSharedPointer<QCPCurveDataContainer> data); | ||||
void setData(const QVector<double> &t, const QVector<double> &keys, | ||||
const QVector<double> &values, bool alreadySorted = false); | ||||
void setData(const QVector<double> &keys, const QVector<double> &values); | ||||
void setScatterStyle(const QCPScatterStyle &style); | ||||
void setScatterSkip(int skip); | ||||
void setLineStyle(LineStyle style); | ||||
// non-property methods: | ||||
void addData(const QVector<double> &t, const QVector<double> &keys, | ||||
const QVector<double> &values, bool alreadySorted = false); | ||||
void addData(const QVector<double> &keys, const QVector<double> &values); | ||||
void addData(double t, double key, double value); | ||||
void addData(double key, double value); | ||||
// reimplemented virtual methods: | ||||
virtual double selectTest(const QPointF &pos, bool onlySelectable, | ||||
QVariant *details = 0) const Q_DECL_OVERRIDE; | ||||
virtual QCPRange getKeyRange(bool &foundRange, | ||||
QCP::SignDomain inSignDomain = QCP::sdBoth) const Q_DECL_OVERRIDE; | ||||
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain = QCP::sdBoth, | ||||
const QCPRange &inKeyRange = QCPRange()) const Q_DECL_OVERRIDE; | ||||
protected: | ||||
// property members: | ||||
QCPScatterStyle mScatterStyle; | ||||
int mScatterSkip; | ||||
LineStyle mLineStyle; | ||||
// reimplemented virtual methods: | ||||
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; | ||||
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; | ||||
// introduced virtual methods: | ||||
virtual void drawCurveLine(QCPPainter *painter, const QVector<QPointF> &lines) const; | ||||
virtual void drawScatterPlot(QCPPainter *painter, const QVector<QPointF> &points, | ||||
const QCPScatterStyle &style) const; | ||||
// non-virtual methods: | ||||
void getCurveLines(QVector<QPointF> *lines, const QCPDataRange &dataRange, | ||||
double penWidth) const; | ||||
void getScatters(QVector<QPointF> *scatters, const QCPDataRange &dataRange, | ||||
double scatterWidth) const; | ||||
int getRegion(double key, double value, double keyMin, double valueMax, double keyMax, | ||||
double valueMin) const; | ||||
QPointF getOptimizedPoint(int prevRegion, double prevKey, double prevValue, double key, | ||||
double value, double keyMin, double valueMax, double keyMax, | ||||
double valueMin) const; | ||||
QVector<QPointF> getOptimizedCornerPoints(int prevRegion, int currentRegion, double prevKey, | ||||
double prevValue, double key, double value, | ||||
double keyMin, double valueMax, double keyMax, | ||||
double valueMin) const; | ||||
bool mayTraverse(int prevRegion, int currentRegion) const; | ||||
bool getTraverse(double prevKey, double prevValue, double key, double value, double keyMin, | ||||
double valueMax, double keyMax, double valueMin, QPointF &crossA, | ||||
QPointF &crossB) const; | ||||
void getTraverseCornerPoints(int prevRegion, int currentRegion, double keyMin, double valueMax, | ||||
double keyMax, double valueMin, QVector<QPointF> &beforeTraverse, | ||||
QVector<QPointF> &afterTraverse) const; | ||||
double pointDistance(const QPointF &pixelPoint, | ||||
QCPCurveDataContainer::const_iterator &closestData) const; | ||||
friend class QCustomPlot; | ||||
friend class QCPLegend; | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPCurve::LineStyle) | ||||
/* end of 'src/plottables/plottable-curve.h' */ | ||||
/* including file 'src/plottables/plottable-bars.h', size 8924 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
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 | ||||
}; | ||||
Q_ENUMS(SpacingType) | ||||
QCPBarsGroup(QCustomPlot *parentPlot); | ||||
virtual ~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<QCPBars *> 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<QCPBars *> 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; | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPBarsGroup::SpacingType) | ||||
class QCP_LIB_DECL QCPBarsData { | ||||
public: | ||||
QCPBarsData(); | ||||
QCPBarsData(double key, double value); | ||||
inline double sortKey() const { return key; } | ||||
inline static QCPBarsData fromSortKey(double sortKey) { return QCPBarsData(sortKey, 0); } | ||||
inline static bool sortKeyIsMainKey() { return true; } | ||||
inline double mainKey() const { return key; } | ||||
inline double mainValue() const { return value; } | ||||
inline QCPRange valueRange() const | ||||
{ | ||||
return QCPRange(value, value); | ||||
} // note that bar base value isn't held in each QCPBarsData and thus can't/shouldn't be | ||||
// returned here | ||||
double key, value; | ||||
}; | ||||
Q_DECLARE_TYPEINFO(QCPBarsData, Q_PRIMITIVE_TYPE); | ||||
/*! \typedef QCPBarsDataContainer | ||||
Container for storing \ref QCPBarsData points. The data is stored sorted by \a key. | ||||
This template instantiation is the container in which QCPBars holds its data. For details about | ||||
the generic container, see the documentation of the class template \ref QCPDataContainer. | ||||
\see QCPBarsData, QCPBars::setData | ||||
*/ | ||||
typedef QCPDataContainer<QCPBarsData> QCPBarsDataContainer; | ||||
class QCP_LIB_DECL QCPBars : public QCPAbstractPlottable1D<QCPBarsData> { | ||||
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(double stackingGap READ stackingGap WRITE setStackingGap) | ||||
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; } | ||||
double stackingGap() const { return mStackingGap; } | ||||
QCPBars *barBelow() const { return mBarBelow.data(); } | ||||
QCPBars *barAbove() const { return mBarAbove.data(); } | ||||
QSharedPointer<QCPBarsDataContainer> data() const { return mDataContainer; } | ||||
// setters: | ||||
void setData(QSharedPointer<QCPBarsDataContainer> data); | ||||
void setData(const QVector<double> &keys, const QVector<double> &values, | ||||
bool alreadySorted = false); | ||||
void setWidth(double width); | ||||
void setWidthType(WidthType widthType); | ||||
void setBarsGroup(QCPBarsGroup *barsGroup); | ||||
void setBaseValue(double baseValue); | ||||
void setStackingGap(double pixels); | ||||
// non-property methods: | ||||
void addData(const QVector<double> &keys, const QVector<double> &values, | ||||
bool alreadySorted = false); | ||||
void addData(double key, double value); | ||||
void moveBelow(QCPBars *bars); | ||||
void moveAbove(QCPBars *bars); | ||||
// reimplemented virtual methods: | ||||
virtual QCPDataSelection selectTestRect(const QRectF &rect, | ||||
bool onlySelectable) const Q_DECL_OVERRIDE; | ||||
virtual double selectTest(const QPointF &pos, bool onlySelectable, | ||||
QVariant *details = 0) const Q_DECL_OVERRIDE; | ||||
virtual QCPRange getKeyRange(bool &foundRange, | ||||
QCP::SignDomain inSignDomain = QCP::sdBoth) const Q_DECL_OVERRIDE; | ||||
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain = QCP::sdBoth, | ||||
const QCPRange &inKeyRange = QCPRange()) const Q_DECL_OVERRIDE; | ||||
virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; | ||||
protected: | ||||
// property members: | ||||
double mWidth; | ||||
WidthType mWidthType; | ||||
QCPBarsGroup *mBarsGroup; | ||||
double mBaseValue; | ||||
double mStackingGap; | ||||
QPointer<QCPBars> mBarBelow, mBarAbove; | ||||
// reimplemented virtual methods: | ||||
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; | ||||
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; | ||||
// non-virtual methods: | ||||
void getVisibleDataBounds(QCPBarsDataContainer::const_iterator &begin, | ||||
QCPBarsDataContainer::const_iterator &end) const; | ||||
QRectF getBarRect(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; | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPBars::WidthType) | ||||
/* end of 'src/plottables/plottable-bars.h' */ | ||||
/* including file 'src/plottables/plottable-statisticalbox.h', size 7516 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
class QCP_LIB_DECL QCPStatisticalBoxData { | ||||
public: | ||||
QCPStatisticalBoxData(); | ||||
QCPStatisticalBoxData(double key, double minimum, double lowerQuartile, double median, | ||||
double upperQuartile, double maximum, | ||||
const QVector<double> &outliers = QVector<double>()); | ||||
inline double sortKey() const { return key; } | ||||
inline static QCPStatisticalBoxData fromSortKey(double sortKey) | ||||
{ | ||||
return QCPStatisticalBoxData(sortKey, 0, 0, 0, 0, 0); | ||||
} | ||||
inline static bool sortKeyIsMainKey() { return true; } | ||||
inline double mainKey() const { return key; } | ||||
inline double mainValue() const { return median; } | ||||
inline QCPRange valueRange() const | ||||
{ | ||||
QCPRange result(minimum, maximum); | ||||
for (QVector<double>::const_iterator it = outliers.constBegin(); it != outliers.constEnd(); | ||||
++it) | ||||
result.expand(*it); | ||||
return result; | ||||
} | ||||
double key, minimum, lowerQuartile, median, upperQuartile, maximum; | ||||
QVector<double> outliers; | ||||
}; | ||||
Q_DECLARE_TYPEINFO(QCPStatisticalBoxData, Q_MOVABLE_TYPE); | ||||
/*! \typedef QCPStatisticalBoxDataContainer | ||||
Container for storing \ref QCPStatisticalBoxData points. The data is stored sorted by \a key. | ||||
This template instantiation is the container in which QCPStatisticalBox holds its data. For | ||||
details about the generic container, see the documentation of the class template \ref | ||||
QCPDataContainer. | ||||
\see QCPStatisticalBoxData, QCPStatisticalBox::setData | ||||
*/ | ||||
typedef QCPDataContainer<QCPStatisticalBoxData> QCPStatisticalBoxDataContainer; | ||||
class QCP_LIB_DECL QCPStatisticalBox : public QCPAbstractPlottable1D<QCPStatisticalBoxData> { | ||||
Q_OBJECT | ||||
/// \cond INCLUDE_QPROPERTIES | ||||
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(bool whiskerAntialiased READ whiskerAntialiased WRITE setWhiskerAntialiased) | ||||
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: | ||||
QSharedPointer<QCPStatisticalBoxDataContainer> data() const { return mDataContainer; } | ||||
double width() const { return mWidth; } | ||||
double whiskerWidth() const { return mWhiskerWidth; } | ||||
QPen whiskerPen() const { return mWhiskerPen; } | ||||
QPen whiskerBarPen() const { return mWhiskerBarPen; } | ||||
bool whiskerAntialiased() const { return mWhiskerAntialiased; } | ||||
QPen medianPen() const { return mMedianPen; } | ||||
QCPScatterStyle outlierStyle() const { return mOutlierStyle; } | ||||
// setters: | ||||
void setData(QSharedPointer<QCPStatisticalBoxDataContainer> data); | ||||
void setData(const QVector<double> &keys, const QVector<double> &minimum, | ||||
const QVector<double> &lowerQuartile, const QVector<double> &median, | ||||
const QVector<double> &upperQuartile, const QVector<double> &maximum, | ||||
bool alreadySorted = false); | ||||
void setWidth(double width); | ||||
void setWhiskerWidth(double width); | ||||
void setWhiskerPen(const QPen &pen); | ||||
void setWhiskerBarPen(const QPen &pen); | ||||
void setWhiskerAntialiased(bool enabled); | ||||
void setMedianPen(const QPen &pen); | ||||
void setOutlierStyle(const QCPScatterStyle &style); | ||||
// non-property methods: | ||||
void addData(const QVector<double> &keys, const QVector<double> &minimum, | ||||
const QVector<double> &lowerQuartile, const QVector<double> &median, | ||||
const QVector<double> &upperQuartile, const QVector<double> &maximum, | ||||
bool alreadySorted = false); | ||||
void addData(double key, double minimum, double lowerQuartile, double median, | ||||
double upperQuartile, double maximum, | ||||
const QVector<double> &outliers = QVector<double>()); | ||||
// reimplemented virtual methods: | ||||
virtual QCPDataSelection selectTestRect(const QRectF &rect, | ||||
bool onlySelectable) const Q_DECL_OVERRIDE; | ||||
virtual double selectTest(const QPointF &pos, bool onlySelectable, | ||||
QVariant *details = 0) const Q_DECL_OVERRIDE; | ||||
virtual QCPRange getKeyRange(bool &foundRange, | ||||
QCP::SignDomain inSignDomain = QCP::sdBoth) const Q_DECL_OVERRIDE; | ||||
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain = QCP::sdBoth, | ||||
const QCPRange &inKeyRange = QCPRange()) const Q_DECL_OVERRIDE; | ||||
protected: | ||||
// property members: | ||||
double mWidth; | ||||
double mWhiskerWidth; | ||||
QPen mWhiskerPen, mWhiskerBarPen; | ||||
bool mWhiskerAntialiased; | ||||
QPen mMedianPen; | ||||
QCPScatterStyle mOutlierStyle; | ||||
// reimplemented virtual methods: | ||||
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; | ||||
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; | ||||
// introduced virtual methods: | ||||
virtual void drawStatisticalBox(QCPPainter *painter, | ||||
QCPStatisticalBoxDataContainer::const_iterator it, | ||||
const QCPScatterStyle &outlierStyle) const; | ||||
// non-virtual methods: | ||||
void getVisibleDataBounds(QCPStatisticalBoxDataContainer::const_iterator &begin, | ||||
QCPStatisticalBoxDataContainer::const_iterator &end) const; | ||||
QRectF getQuartileBox(QCPStatisticalBoxDataContainer::const_iterator it) const; | ||||
QVector<QLineF> | ||||
getWhiskerBackboneLines(QCPStatisticalBoxDataContainer::const_iterator it) const; | ||||
QVector<QLineF> getWhiskerBarLines(QCPStatisticalBoxDataContainer::const_iterator it) const; | ||||
friend class QCustomPlot; | ||||
friend class QCPLegend; | ||||
}; | ||||
/* end of 'src/plottables/plottable-statisticalbox.h' */ | ||||
/* including file 'src/plottables/plottable-colormap.h', size 7070 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
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); | ||||
unsigned char alpha(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); | ||||
void setAlpha(int keyIndex, int valueIndex, unsigned char alpha); | ||||
// non-property methods: | ||||
void recalculateDataBounds(); | ||||
void clear(); | ||||
void clearAlpha(); | ||||
void fill(double z); | ||||
void fillAlpha(unsigned char alpha); | ||||
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; | ||||
unsigned char *mAlpha; | ||||
QCPRange mDataBounds; | ||||
bool mDataModified; | ||||
bool createAlpha(bool initializeOpaque = true); | ||||
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 double selectTest(const QPointF &pos, bool onlySelectable, | ||||
QVariant *details = 0) const Q_DECL_OVERRIDE; | ||||
virtual QCPRange getKeyRange(bool &foundRange, | ||||
QCP::SignDomain inSignDomain = QCP::sdBoth) const Q_DECL_OVERRIDE; | ||||
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain = QCP::sdBoth, | ||||
const QCPRange &inKeyRange = QCPRange()) const Q_DECL_OVERRIDE; | ||||
signals: | ||||
void dataRangeChanged(const QCPRange &newRange); | ||||
void dataScaleTypeChanged(QCPAxis::ScaleType scaleType); | ||||
void gradientChanged(const QCPColorGradient &newGradient); | ||||
protected: | ||||
// property members: | ||||
QCPRange mDataRange; | ||||
QCPAxis::ScaleType mDataScaleType; | ||||
QCPColorMapData *mMapData; | ||||
QCPColorGradient mGradient; | ||||
bool mInterpolate; | ||||
bool mTightBoundary; | ||||
QPointer<QCPColorScale> 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) Q_DECL_OVERRIDE; | ||||
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; | ||||
friend class QCustomPlot; | ||||
friend class QCPLegend; | ||||
}; | ||||
/* end of 'src/plottables/plottable-colormap.h' */ | ||||
/* including file 'src/plottables/plottable-financial.h', size 8622 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
class QCP_LIB_DECL QCPFinancialData { | ||||
public: | ||||
QCPFinancialData(); | ||||
QCPFinancialData(double key, double open, double high, double low, double close); | ||||
inline double sortKey() const { return key; } | ||||
inline static QCPFinancialData fromSortKey(double sortKey) | ||||
{ | ||||
return QCPFinancialData(sortKey, 0, 0, 0, 0); | ||||
} | ||||
inline static bool sortKeyIsMainKey() { return true; } | ||||
inline double mainKey() const { return key; } | ||||
inline double mainValue() const { return open; } | ||||
inline QCPRange valueRange() const | ||||
{ | ||||
return QCPRange(low, high); | ||||
} // open and close must lie between low and high, so we don't need to check them | ||||
double key, open, high, low, close; | ||||
}; | ||||
Q_DECLARE_TYPEINFO(QCPFinancialData, Q_PRIMITIVE_TYPE); | ||||
/*! \typedef QCPFinancialDataContainer | ||||
Container for storing \ref QCPFinancialData points. The data is stored sorted by \a key. | ||||
This template instantiation is the container in which QCPFinancial holds its data. For details | ||||
about the generic container, see the documentation of the class template \ref QCPDataContainer. | ||||
\see QCPFinancialData, QCPFinancial::setData | ||||
*/ | ||||
typedef QCPDataContainer<QCPFinancialData> QCPFinancialDataContainer; | ||||
class QCP_LIB_DECL QCPFinancial : public QCPAbstractPlottable1D<QCPFinancialData> { | ||||
Q_OBJECT | ||||
/// \cond INCLUDE_QPROPERTIES | ||||
Q_PROPERTY(ChartStyle chartStyle READ chartStyle WRITE setChartStyle) | ||||
Q_PROPERTY(double width READ width WRITE setWidth) | ||||
Q_PROPERTY(WidthType widthType READ widthType WRITE setWidthType) | ||||
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 ways the width of the financial bar can be specified. Thus it defines what the | ||||
number passed to \ref setWidth actually means. | ||||
\see setWidthType, setWidth | ||||
*/ | ||||
enum WidthType { | ||||
wtAbsolute ///< width is in absolute pixels | ||||
, | ||||
wtAxisRectRatio ///< width is given by a fraction of the axis rect size | ||||
, | ||||
wtPlotCoords ///< width is in key coordinates and thus scales with the key axis range | ||||
}; | ||||
Q_ENUMS(WidthType) | ||||
/*! | ||||
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: | ||||
QSharedPointer<QCPFinancialDataContainer> data() const { return mDataContainer; } | ||||
ChartStyle chartStyle() const { return mChartStyle; } | ||||
double width() const { return mWidth; } | ||||
WidthType widthType() const { return mWidthType; } | ||||
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(QSharedPointer<QCPFinancialDataContainer> data); | ||||
void setData(const QVector<double> &keys, const QVector<double> &open, | ||||
const QVector<double> &high, const QVector<double> &low, | ||||
const QVector<double> &close, bool alreadySorted = false); | ||||
void setChartStyle(ChartStyle style); | ||||
void setWidth(double width); | ||||
void setWidthType(WidthType widthType); | ||||
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 QVector<double> &keys, const QVector<double> &open, | ||||
const QVector<double> &high, const QVector<double> &low, | ||||
const QVector<double> &close, bool alreadySorted = false); | ||||
void addData(double key, double open, double high, double low, double close); | ||||
// reimplemented virtual methods: | ||||
virtual QCPDataSelection selectTestRect(const QRectF &rect, | ||||
bool onlySelectable) const Q_DECL_OVERRIDE; | ||||
virtual double selectTest(const QPointF &pos, bool onlySelectable, | ||||
QVariant *details = 0) const Q_DECL_OVERRIDE; | ||||
virtual QCPRange getKeyRange(bool &foundRange, | ||||
QCP::SignDomain inSignDomain = QCP::sdBoth) const Q_DECL_OVERRIDE; | ||||
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain = QCP::sdBoth, | ||||
const QCPRange &inKeyRange = QCPRange()) const Q_DECL_OVERRIDE; | ||||
// static methods: | ||||
static QCPFinancialDataContainer timeSeriesToOhlc(const QVector<double> &time, | ||||
const QVector<double> &value, | ||||
double timeBinSize, double timeBinOffset = 0); | ||||
protected: | ||||
// property members: | ||||
ChartStyle mChartStyle; | ||||
double mWidth; | ||||
WidthType mWidthType; | ||||
bool mTwoColored; | ||||
QBrush mBrushPositive, mBrushNegative; | ||||
QPen mPenPositive, mPenNegative; | ||||
// reimplemented virtual methods: | ||||
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; | ||||
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; | ||||
// non-virtual methods: | ||||
void drawOhlcPlot(QCPPainter *painter, const QCPFinancialDataContainer::const_iterator &begin, | ||||
const QCPFinancialDataContainer::const_iterator &end, bool isSelected); | ||||
void drawCandlestickPlot(QCPPainter *painter, | ||||
const QCPFinancialDataContainer::const_iterator &begin, | ||||
const QCPFinancialDataContainer::const_iterator &end, bool isSelected); | ||||
double getPixelWidth(double key, double keyPixel) const; | ||||
double ohlcSelectTest(const QPointF &pos, | ||||
const QCPFinancialDataContainer::const_iterator &begin, | ||||
const QCPFinancialDataContainer::const_iterator &end, | ||||
QCPFinancialDataContainer::const_iterator &closestDataPoint) const; | ||||
double candlestickSelectTest(const QPointF &pos, | ||||
const QCPFinancialDataContainer::const_iterator &begin, | ||||
const QCPFinancialDataContainer::const_iterator &end, | ||||
QCPFinancialDataContainer::const_iterator &closestDataPoint) const; | ||||
void getVisibleDataBounds(QCPFinancialDataContainer::const_iterator &begin, | ||||
QCPFinancialDataContainer::const_iterator &end) const; | ||||
QRectF selectionHitBox(QCPFinancialDataContainer::const_iterator it) const; | ||||
friend class QCustomPlot; | ||||
friend class QCPLegend; | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPFinancial::ChartStyle) | ||||
/* end of 'src/plottables/plottable-financial.h' */ | ||||
r610 | /* including file 'src/plottables/plottable-errorbar.h', size 7727 */ | |||
/* commit 681a87c5e5365a5c7187d20b4077031003c48449 2017-07-23 23:46:48 +0200 */ | ||||
r59 | ||||
class QCP_LIB_DECL QCPErrorBarsData { | ||||
public: | ||||
QCPErrorBarsData(); | ||||
explicit QCPErrorBarsData(double error); | ||||
QCPErrorBarsData(double errorMinus, double errorPlus); | ||||
double errorMinus, errorPlus; | ||||
}; | ||||
Q_DECLARE_TYPEINFO(QCPErrorBarsData, Q_PRIMITIVE_TYPE); | ||||
/*! \typedef QCPErrorBarsDataContainer | ||||
Container for storing \ref QCPErrorBarsData points. It is a typedef for <tt>QVector<\ref | ||||
QCPErrorBarsData></tt>. | ||||
This is the container in which \ref QCPErrorBars holds its data. Unlike most other data | ||||
containers for plottables, it is not based on \ref QCPDataContainer. This is because the error | ||||
bars plottable is special in that it doesn't store its own key and value coordinate per error | ||||
bar. It adopts the key and value from the plottable to which the error bars shall be applied | ||||
(\ref QCPErrorBars::setDataPlottable). So the stored \ref QCPErrorBarsData doesn't need a | ||||
sortable key, but merely an index (as \c QVector provides), which maps one-to-one to the indices | ||||
of the other plottable's data. | ||||
\see QCPErrorBarsData, QCPErrorBars::setData | ||||
*/ | ||||
typedef QVector<QCPErrorBarsData> QCPErrorBarsDataContainer; | ||||
class QCP_LIB_DECL QCPErrorBars : public QCPAbstractPlottable, public QCPPlottableInterface1D { | ||||
Q_OBJECT | ||||
/// \cond INCLUDE_QPROPERTIES | ||||
Q_PROPERTY(QSharedPointer<QCPErrorBarsDataContainer> data READ data WRITE setData) | ||||
Q_PROPERTY(QCPAbstractPlottable *dataPlottable READ dataPlottable WRITE setDataPlottable) | ||||
Q_PROPERTY(ErrorType errorType READ errorType WRITE setErrorType) | ||||
Q_PROPERTY(double whiskerWidth READ whiskerWidth WRITE setWhiskerWidth) | ||||
Q_PROPERTY(double symbolGap READ symbolGap WRITE setSymbolGap) | ||||
/// \endcond | ||||
public: | ||||
/*! | ||||
Defines in which orientation the error bars shall appear. If your data needs both error | ||||
dimensions, create two \ref QCPErrorBars with different \ref ErrorType. | ||||
\see setErrorType | ||||
*/ | ||||
enum ErrorType { | ||||
etKeyError ///< The errors are for the key dimension (bars appear parallel to the key axis) | ||||
, | ||||
etValueError ///< The errors are for the value dimension (bars appear parallel to the value | ||||
/// axis) | ||||
}; | ||||
Q_ENUMS(ErrorType) | ||||
explicit QCPErrorBars(QCPAxis *keyAxis, QCPAxis *valueAxis); | ||||
virtual ~QCPErrorBars(); | ||||
// getters: | ||||
QSharedPointer<QCPErrorBarsDataContainer> data() const { return mDataContainer; } | ||||
QCPAbstractPlottable *dataPlottable() const { return mDataPlottable.data(); } | ||||
ErrorType errorType() const { return mErrorType; } | ||||
double whiskerWidth() const { return mWhiskerWidth; } | ||||
double symbolGap() const { return mSymbolGap; } | ||||
// setters: | ||||
void setData(QSharedPointer<QCPErrorBarsDataContainer> data); | ||||
void setData(const QVector<double> &error); | ||||
void setData(const QVector<double> &errorMinus, const QVector<double> &errorPlus); | ||||
void setDataPlottable(QCPAbstractPlottable *plottable); | ||||
void setErrorType(ErrorType type); | ||||
void setWhiskerWidth(double pixels); | ||||
void setSymbolGap(double pixels); | ||||
// non-property methods: | ||||
void addData(const QVector<double> &error); | ||||
void addData(const QVector<double> &errorMinus, const QVector<double> &errorPlus); | ||||
void addData(double error); | ||||
void addData(double errorMinus, double errorPlus); | ||||
// virtual methods of 1d plottable interface: | ||||
r610 | virtual int dataCount() const Q_DECL_OVERRIDE; | |||
virtual double dataMainKey(int index) const Q_DECL_OVERRIDE; | ||||
virtual double dataSortKey(int index) const Q_DECL_OVERRIDE; | ||||
virtual double dataMainValue(int index) const Q_DECL_OVERRIDE; | ||||
virtual QCPRange dataValueRange(int index) const Q_DECL_OVERRIDE; | ||||
virtual QPointF dataPixelPosition(int index) const Q_DECL_OVERRIDE; | ||||
virtual bool sortKeyIsMainKey() const Q_DECL_OVERRIDE; | ||||
virtual QCPDataSelection selectTestRect(const QRectF &rect, | ||||
bool onlySelectable) const Q_DECL_OVERRIDE; | ||||
virtual int findBegin(double sortKey, bool expandedRange = true) const Q_DECL_OVERRIDE; | ||||
virtual int findEnd(double sortKey, bool expandedRange = true) const Q_DECL_OVERRIDE; | ||||
r59 | ||||
// reimplemented virtual methods: | ||||
virtual double selectTest(const QPointF &pos, bool onlySelectable, | ||||
QVariant *details = 0) const Q_DECL_OVERRIDE; | ||||
virtual QCPPlottableInterface1D *interface1D() Q_DECL_OVERRIDE { return this; } | ||||
protected: | ||||
// property members: | ||||
QSharedPointer<QCPErrorBarsDataContainer> mDataContainer; | ||||
QPointer<QCPAbstractPlottable> mDataPlottable; | ||||
ErrorType mErrorType; | ||||
double mWhiskerWidth; | ||||
double mSymbolGap; | ||||
// reimplemented virtual methods: | ||||
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; | ||||
virtual void drawLegendIcon(QCPPainter *painter, const QRectF &rect) const Q_DECL_OVERRIDE; | ||||
virtual QCPRange getKeyRange(bool &foundRange, | ||||
QCP::SignDomain inSignDomain = QCP::sdBoth) const Q_DECL_OVERRIDE; | ||||
virtual QCPRange getValueRange(bool &foundRange, QCP::SignDomain inSignDomain = QCP::sdBoth, | ||||
const QCPRange &inKeyRange = QCPRange()) const Q_DECL_OVERRIDE; | ||||
// non-virtual methods: | ||||
void getErrorBarLines(QCPErrorBarsDataContainer::const_iterator it, QVector<QLineF> &backbones, | ||||
QVector<QLineF> &whiskers) const; | ||||
void getVisibleDataBounds(QCPErrorBarsDataContainer::const_iterator &begin, | ||||
QCPErrorBarsDataContainer::const_iterator &end, | ||||
const QCPDataRange &rangeRestriction) const; | ||||
double pointDistance(const QPointF &pixelPoint, | ||||
QCPErrorBarsDataContainer::const_iterator &closestData) const; | ||||
// helpers: | ||||
void getDataSegments(QList<QCPDataRange> &selectedSegments, | ||||
QList<QCPDataRange> &unselectedSegments) const; | ||||
bool errorBarVisible(int index) const; | ||||
bool rectIntersectsLine(const QRectF &pixelRect, const QLineF &line) const; | ||||
friend class QCustomPlot; | ||||
friend class QCPLegend; | ||||
}; | ||||
/* end of 'src/plottables/plottable-errorbar.h' */ | ||||
/* including file 'src/items/item-straightline.h', size 3117 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
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: | ||||
explicit 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 Q_DECL_OVERRIDE; | ||||
QCPItemPosition *const point1; | ||||
QCPItemPosition *const point2; | ||||
protected: | ||||
// property members: | ||||
QPen mPen, mSelectedPen; | ||||
// reimplemented virtual methods: | ||||
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; | ||||
// non-virtual methods: | ||||
QLineF getRectClippedStraightLine(const QCPVector2D &point1, const QCPVector2D &vec, | ||||
const QRect &rect) const; | ||||
QPen mainPen() const; | ||||
}; | ||||
/* end of 'src/items/item-straightline.h' */ | ||||
/* including file 'src/items/item-line.h', size 3407 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
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: | ||||
explicit 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 Q_DECL_OVERRIDE; | ||||
QCPItemPosition *const start; | ||||
QCPItemPosition *const end; | ||||
protected: | ||||
// property members: | ||||
QPen mPen, mSelectedPen; | ||||
QCPLineEnding mHead, mTail; | ||||
// reimplemented virtual methods: | ||||
virtual void draw(QCPPainter *painter) Q_DECL_OVERRIDE; | ||||
// non-virtual methods: | ||||
QLineF getRectClippedLine(const QCPVector2D &start, const QCPVector2D &end, | ||||
const QRect &rect) const; | ||||
QPen mainPen() const; | ||||
}; | ||||
/* end of 'src/items/item-line.h' */ | ||||
/* including file 'src/items/item-curve.h', size 3379 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
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: | ||||
explicit 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 Q_DECL_OVERRIDE; | ||||
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) Q_DECL_OVERRIDE; | ||||
// non-virtual methods: | ||||
QPen mainPen() const; | ||||
}; | ||||
/* end of 'src/items/item-curve.h' */ | ||||
/* including file 'src/items/item-rect.h', size 3688 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
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: | ||||
explicit 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 Q_DECL_OVERRIDE; | ||||
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) Q_DECL_OVERRIDE; | ||||
virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; | ||||
// non-virtual methods: | ||||
QPen mainPen() const; | ||||
QBrush mainBrush() const; | ||||
}; | ||||
/* end of 'src/items/item-rect.h' */ | ||||
/* including file 'src/items/item-text.h', size 5554 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
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: | ||||
explicit 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 Q_DECL_OVERRIDE; | ||||
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) Q_DECL_OVERRIDE; | ||||
virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; | ||||
// 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; | ||||
}; | ||||
/* end of 'src/items/item-text.h' */ | ||||
/* including file 'src/items/item-ellipse.h', size 3868 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
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: | ||||
explicit 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 Q_DECL_OVERRIDE; | ||||
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) Q_DECL_OVERRIDE; | ||||
virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; | ||||
// non-virtual methods: | ||||
QPen mainPen() const; | ||||
QBrush mainBrush() const; | ||||
}; | ||||
/* end of 'src/items/item-ellipse.h' */ | ||||
/* including file 'src/items/item-pixmap.h', size 4373 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
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: | ||||
explicit 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 Q_DECL_OVERRIDE; | ||||
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) Q_DECL_OVERRIDE; | ||||
virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; | ||||
// 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; | ||||
}; | ||||
/* end of 'src/items/item-pixmap.h' */ | ||||
/* including file 'src/items/item-tracer.h', size 4762 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
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) | ||||
explicit 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 Q_DECL_OVERRIDE; | ||||
// 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) Q_DECL_OVERRIDE; | ||||
// non-virtual methods: | ||||
QPen mainPen() const; | ||||
QBrush mainBrush() const; | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPItemTracer::TracerStyle) | ||||
/* end of 'src/items/item-tracer.h' */ | ||||
/* including file 'src/items/item-bracket.h', size 3969 */ | ||||
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */ | ||||
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: | ||||
/*! | ||||
Defines the various visual shapes of the bracket item. The appearance can be further modified | ||||
by \ref setLength and \ref setPen. | ||||
\see setStyle | ||||
*/ | ||||
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 | ||||
}; | ||||
Q_ENUMS(BracketStyle) | ||||
explicit 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 Q_DECL_OVERRIDE; | ||||
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) Q_DECL_OVERRIDE; | ||||
virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE; | ||||
// non-virtual methods: | ||||
QPen mainPen() const; | ||||
}; | ||||
Q_DECLARE_METATYPE(QCPItemBracket::BracketStyle) | ||||
/* end of 'src/items/item-bracket.h' */ | ||||
#endif // QCUSTOMPLOT_H | ||||