|
|
/***************************************************************************
|
|
|
** **
|
|
|
** 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
|
|
|
#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;
|
|
|
|
|
|
/* including file 'src/global.h', size 16131 */
|
|
|
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
|
|
|
|
|
|
// 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' */
|
|
|
|
|
|
|
|
|
/* including file 'src/axis/axistickertime.h', size 3288 */
|
|
|
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
|
|
|
|
|
|
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
|
|
|
*/
|
|
|
enum TimeUnit { tuMilliseconds, tuSeconds, tuMinutes, tuHours, tuDays };
|
|
|
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' */
|
|
|
|
|
|
|
|
|
/* including file 'src/axis/axis.h', size 20230 */
|
|
|
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
|
|
|
|
|
|
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;
|
|
|
|
|
|
// 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;
|
|
|
|
|
|
// 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' */
|
|
|
|
|
|
|
|
|
/* including file 'src/datacontainer.h', size 4535 */
|
|
|
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
|
|
|
|
|
|
/*! \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>
|
|
|
class QCP_LIB_DECL QCPDataContainer {
|
|
|
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:
|
|
|
|
|
|
/* including file 'src/datacontainer.cpp', size 31224 */
|
|
|
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
//////////////////// 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
|
|
|
container's data, as well as within the specified \a dataRange.
|
|
|
|
|
|
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' */
|
|
|
|
|
|
|
|
|
/* including file 'src/item.h', size 9368 */
|
|
|
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
|
|
|
|
|
|
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;
|
|
|
virtual QPointF pixelPosition() const;
|
|
|
|
|
|
// setters:
|
|
|
void setType(PositionType type);
|
|
|
void setTypeX(PositionType type);
|
|
|
void setTypeY(PositionType type);
|
|
|
bool setParentAnchor(QCPItemAnchor *parentAnchor, bool keepPixelPosition = false);
|
|
|
bool setParentAnchorX(QCPItemAnchor *parentAnchor, bool keepPixelPosition = false);
|
|
|
bool setParentAnchorY(QCPItemAnchor *parentAnchor, bool keepPixelPosition = false);
|
|
|
void setCoords(double key, double value);
|
|
|
void setCoords(const QPointF &coords);
|
|
|
void setAxes(QCPAxis *keyAxis, QCPAxis *valueAxis);
|
|
|
void setAxisRect(QCPAxisRect *axisRect);
|
|
|
void 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' */
|
|
|
|
|
|
|
|
|
/* including file 'src/core.h', size 14797 */
|
|
|
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
|
|
|
|
|
|
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;
|
|
|
QVariant mMouseEventLayerableDetails;
|
|
|
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' */
|
|
|
|
|
|
|
|
|
/* including file 'src/plottable1d.h', size 4250 */
|
|
|
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
|
|
|
|
|
|
class QCP_LIB_DECL QCPPlottableInterface1D {
|
|
|
public:
|
|
|
// 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>
|
|
|
class QCP_LIB_DECL QCPAbstractPlottable1D : public QCPAbstractPlottable,
|
|
|
public QCPPlottableInterface1D {
|
|
|
// No Q_OBJECT macro due to template class
|
|
|
|
|
|
public:
|
|
|
QCPAbstractPlottable1D(QCPAxis *keyAxis, QCPAxis *valueAxis);
|
|
|
virtual ~QCPAbstractPlottable1D();
|
|
|
|
|
|
// virtual methods of 1d plottable interface:
|
|
|
virtual int dataCount() const;
|
|
|
virtual double dataMainKey(int index) const;
|
|
|
virtual double dataSortKey(int index) const;
|
|
|
virtual double dataMainValue(int index) const;
|
|
|
virtual QCPRange dataValueRange(int index) const;
|
|
|
virtual QPointF dataPixelPosition(int index) const;
|
|
|
virtual bool sortKeyIsMainKey() const;
|
|
|
virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const;
|
|
|
virtual int findBegin(double sortKey, bool expandedRange = true) const;
|
|
|
virtual int findEnd(double sortKey, bool expandedRange = true) const;
|
|
|
|
|
|
// virtual methods:
|
|
|
virtual double selectTest(const QPointF &pos, bool onlySelectable, QVariant *details = 0) const;
|
|
|
virtual QCPPlottableInterface1D *interface1D() { return this; }
|
|
|
|
|
|
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' */
|
|
|
|
|
|
|
|
|
/* including file 'src/selectiondecorator-bracket.h', size 4426 */
|
|
|
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
|
|
|
|
|
|
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:
|
|
|
virtual void drawDecoration(QCPPainter *painter, QCPDataSelection selection);
|
|
|
|
|
|
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' */
|
|
|
|
|
|
|
|
|
/* including file 'src/layoutelements/layoutelement-axisrect.h', size 7528 */
|
|
|
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
|
|
|
|
|
|
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;
|
|
|
QPoint mDragStart;
|
|
|
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' */
|
|
|
|
|
|
|
|
|
/* including file 'src/layoutelements/layoutelement-colorscale.h', size 5907 */
|
|
|
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
|
|
|
|
|
|
|
|
|
class QCPColorScaleAxisRectPrivate : public QCPAxisRect {
|
|
|
Q_OBJECT
|
|
|
public:
|
|
|
explicit QCPColorScaleAxisRectPrivate(QCPColorScale *parentColorScale);
|
|
|
|
|
|
protected:
|
|
|
QCPColorScale *mParentColorScale;
|
|
|
QImage mGradientImage;
|
|
|
bool mGradientImageInvalidated;
|
|
|
// re-using some methods of QCPAxisRect to make them available to friend class QCPColorScale
|
|
|
using QCPAxisRect::calculateAutoMargin;
|
|
|
using QCPAxisRect::mousePressEvent;
|
|
|
using QCPAxisRect::mouseMoveEvent;
|
|
|
using QCPAxisRect::mouseReleaseEvent;
|
|
|
using QCPAxisRect::wheelEvent;
|
|
|
using QCPAxisRect::update;
|
|
|
virtual void draw(QCPPainter *painter);
|
|
|
void updateGradientImage();
|
|
|
Q_SLOT void axisSelectionChanged(QCPAxis::SelectableParts selectedParts);
|
|
|
Q_SLOT void axisSelectableChanged(QCPAxis::SelectableParts selectableParts);
|
|
|
friend class QCPColorScale;
|
|
|
};
|
|
|
|
|
|
|
|
|
class QCP_LIB_DECL QCPColorScale : public QCPLayoutElement {
|
|
|
Q_OBJECT
|
|
|
/// \cond INCLUDE_QPROPERTIES
|
|
|
Q_PROPERTY(QCPAxis::AxisType type READ type WRITE setType)
|
|
|
Q_PROPERTY(QCPRange dataRange READ dataRange WRITE setDataRange NOTIFY dataRangeChanged)
|
|
|
Q_PROPERTY(QCPAxis::ScaleType dataScaleType READ dataScaleType WRITE setDataScaleType NOTIFY
|
|
|
dataScaleTypeChanged)
|
|
|
Q_PROPERTY(QCPColorGradient gradient READ gradient WRITE setGradient NOTIFY gradientChanged)
|
|
|
Q_PROPERTY(QString label READ label WRITE setLabel)
|
|
|
Q_PROPERTY(int barWidth READ barWidth WRITE setBarWidth)
|
|
|
Q_PROPERTY(bool rangeDrag READ rangeDrag WRITE setRangeDrag)
|
|
|
Q_PROPERTY(bool rangeZoom READ rangeZoom WRITE setRangeZoom)
|
|
|
/// \endcond
|
|
|
public:
|
|
|
explicit QCPColorScale(QCustomPlot *parentPlot);
|
|
|
virtual ~QCPColorScale();
|
|
|
|
|
|
// getters:
|
|
|
QCPAxis *axis() const { return mColorAxis.data(); }
|
|
|
QCPAxis::AxisType type() const { return mType; }
|
|
|
QCPRange dataRange() const { return mDataRange; }
|
|
|
QCPAxis::ScaleType dataScaleType() const { return mDataScaleType; }
|
|
|
QCPColorGradient gradient() const { return mGradient; }
|
|
|
QString label() const;
|
|
|
int barWidth() const { return mBarWidth; }
|
|
|
bool rangeDrag() const;
|
|
|
bool rangeZoom() const;
|
|
|
|
|
|
// setters:
|
|
|
void setType(QCPAxis::AxisType type);
|
|
|
Q_SLOT void setDataRange(const QCPRange &dataRange);
|
|
|
Q_SLOT void setDataScaleType(QCPAxis::ScaleType scaleType);
|
|
|
Q_SLOT void setGradient(const QCPColorGradient &gradient);
|
|
|
void setLabel(const QString &str);
|
|
|
void setBarWidth(int width);
|
|
|
void setRangeDrag(bool enabled);
|
|
|
void setRangeZoom(bool enabled);
|
|
|
|
|
|
// non-property methods:
|
|
|
QList<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' */
|
|
|
|
|
|
|
|
|
/* including file 'src/plottables/plottable-graph.h', size 8826 */
|
|
|
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
|
|
|
|
|
|
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;
|
|
|
void addFillBasePoints(QVector<QPointF> *lines) const;
|
|
|
void removeFillBasePoints(QVector<QPointF> *lines) const;
|
|
|
QPointF lowerFillBasePoint(double lowerKey) const;
|
|
|
QPointF upperFillBasePoint(double upperKey) const;
|
|
|
const QPolygonF getChannelFillPolygon(const QVector<QPointF> *lines) const;
|
|
|
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' */
|
|
|
|
|
|
|
|
|
/* including file 'src/plottables/plottable-errorbar.h', size 7567 */
|
|
|
/* commit 633339dadc92cb10c58ef3556b55570685fafb99 2016-09-13 23:54:56 +0200 */
|
|
|
|
|
|
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:
|
|
|
virtual int dataCount() const;
|
|
|
virtual double dataMainKey(int index) const;
|
|
|
virtual double dataSortKey(int index) const;
|
|
|
virtual double dataMainValue(int index) const;
|
|
|
virtual QCPRange dataValueRange(int index) const;
|
|
|
virtual QPointF dataPixelPosition(int index) const;
|
|
|
virtual bool sortKeyIsMainKey() const;
|
|
|
virtual QCPDataSelection selectTestRect(const QRectF &rect, bool onlySelectable) const;
|
|
|
virtual int findBegin(double sortKey, bool expandedRange = true) const;
|
|
|
virtual int findEnd(double sortKey, bool expandedRange = true) const;
|
|
|
|
|
|
// 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
|
|
|
|