📄 qwt_plot_curve.cpp
字号:
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
* Qwt Widget Library
* Copyright (C) 1997 Josef Wilgen
* Copyright (C) 2002 Uwe Rathmann
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Qwt License, Version 1.0
*****************************************************************************/
#include <qpainter.h>
#include <qpixmap.h>
#include <qbitarray.h>
#include "qwt_global.h"
#include "qwt_legend.h"
#include "qwt_legend_item.h"
#include "qwt_data.h"
#include "qwt_rect.h"
#include "qwt_scale_map.h"
#include "qwt_double_rect.h"
#include "qwt_math.h"
#include "qwt_painter.h"
#include "qwt_plot.h"
#include "qwt_plot_canvas.h"
#include "qwt_curve_fitter.h"
#include "qwt_symbol.h"
#include "qwt_plot_curve.h"
#if QT_VERSION >= 0x040000
#include <qevent.h>
class QwtPlotCurvePaintHelper: public QObject
{
public:
QwtPlotCurvePaintHelper(const QwtPlotCurve *curve, int from, int to):
_curve(curve),
_from(from),
_to(to)
{
}
virtual bool eventFilter(QObject *, QEvent *event)
{
if ( event->type() == QEvent::Paint )
{
_curve->draw(_from, _to);
return true;
}
return false;
}
private:
const QwtPlotCurve *_curve;
int _from;
int _to;
};
#endif // QT_VERSION >= 0x040000
static int verifyRange(int size, int &i1, int &i2)
{
if (size < 1)
return 0;
i1 = qwtLim(i1, 0, size-1);
i2 = qwtLim(i2, 0, size-1);
if ( i1 > i2 )
qSwap(i1, i2);
return (i2 - i1 + 1);
}
class QwtPlotCurve::PrivateData
{
public:
class PixelMatrix: private QBitArray
{
public:
PixelMatrix(const QRect& rect):
QBitArray(rect.width() * rect.height()),
_rect(rect)
{
fill(false);
}
inline bool testPixel(const QPoint& pos)
{
if ( !_rect.contains(pos) )
return false;
const int idx = _rect.width() * (pos.y() - _rect.y()) +
(pos.x() - _rect.x());
const bool marked = testBit(idx);
if ( !marked )
setBit(idx, true);
return !marked;
}
private:
QRect _rect;
};
PrivateData():
curveType(Yfx),
style(QwtPlotCurve::Lines),
reference(0.0),
attributes(0),
paintAttributes(0)
{
pen = QPen(Qt::black, 0);
curveFitter = new QwtSplineCurveFitter;
}
~PrivateData()
{
delete curveFitter;
}
QwtPlotCurve::CurveType curveType;
QwtPlotCurve::CurveStyle style;
double reference;
QwtSymbol sym;
QwtCurveFitter *curveFitter;
QPen pen;
QBrush brush;
int attributes;
int paintAttributes;
};
/*!
\brief Ctor
*/
QwtPlotCurve::QwtPlotCurve():
QwtPlotItem(QwtText())
{
init();
}
/*!
\brief Ctor
\param title title of the curve
*/
QwtPlotCurve::QwtPlotCurve(const QwtText &title):
QwtPlotItem(title)
{
init();
}
/*!
\brief Ctor
\param title title of the curve
*/
QwtPlotCurve::QwtPlotCurve(const QString &title):
QwtPlotItem(QwtText(title))
{
init();
}
//! Dtor
QwtPlotCurve::~QwtPlotCurve()
{
delete d_xy;
delete d_data;
}
/*!
\brief Initialize data members
*/
void QwtPlotCurve::init()
{
setItemAttribute(QwtPlotItem::Legend);
setItemAttribute(QwtPlotItem::AutoScale);
d_data = new PrivateData;
d_xy = new QwtPolygonFData(QwtArray<QwtDoublePoint>());
setZ(20.0);
}
int QwtPlotCurve::rtti() const
{
return QwtPlotItem::Rtti_PlotCurve;
}
/*!
\brief Specify an attribute how to draw the curve
The attributes can be used to modify the drawing algorithm.
The following attributes are defined:<dl>
<dt>PaintFiltered</dt>
<dd>Tries to reduce the data that has to be painted, by sorting out
duplicates, or paintings outside the visible area. Might have a
notable impact on curves with many close points.
Only a couple of very basic filtering algos are implemented.</dd>
<dt>ClipPolygons</dt>
<dd>Clip polygons before painting them.
</dl>
The default is, that no paint attributes are enabled.
\param attribute Paint attribute
\param on On/Off
/sa testPaintAttribute()
*/
void QwtPlotCurve::setPaintAttribute(PaintAttribute attribute, bool on)
{
if ( on )
d_data->paintAttributes |= attribute;
else
d_data->paintAttributes &= ~attribute;
}
/*!
\brief Return the current paint attributes
\sa setPaintAttribute
*/
bool QwtPlotCurve::testPaintAttribute(PaintAttribute attribute) const
{
return (d_data->paintAttributes & attribute);
}
/*!
\brief Set the curve's drawing style
Valid styles are:
<dl>
<dt>NoCurve</dt>
<dd>Don't draw a curve. Note: This doesn't affect the symbol. </dd>
<dt>Lines</dt>
<dd>Connect the points with straight lines. The lines might
be interpolated depending on the 'Fitted' option. Curve
fitting can be configured using setCurveFitter.</dd>
<dt>Sticks</dt>
<dd>Draw vertical sticks from a baseline which is defined by setBaseline().</dd>
<dt>Steps</dt>
<dd>Connect the points with a step function. The step function
is drawn from the left to the right or vice versa,
depending on the 'Inverted' option.</dd>
<dt>Dots</dt>
<dd>Draw dots at the locations of the data points. Note:
This is different from a dotted line (see setPen()).</dd>
<dt>UserCurve ...</dt>
<dd>Styles >= UserCurve are reserved for derived
classes of QwtPlotCurve that overload drawCurve() with
additional application specific curve types.</dd>
</dl>
\sa style()
*/
void QwtPlotCurve::setStyle(CurveStyle style)
{
if ( style != d_data->style )
{
d_data->style = style;
itemChanged();
}
}
/*!
\brief Return the current style
\sa setStyle
*/
QwtPlotCurve::CurveStyle QwtPlotCurve::style() const
{
return d_data->style;
}
/*!
\brief Assign a symbol
\param s symbol
\sa symbol()
*/
void QwtPlotCurve::setSymbol(const QwtSymbol &s )
{
d_data->sym = s;
itemChanged();
}
/*!
\brief Return the current symbol
\sa setSymbol
*/
const QwtSymbol &QwtPlotCurve::symbol() const
{
return d_data->sym;
}
/*!
\brief Assign a pen
\param p New pen
\sa pen(), brush()
*/
void QwtPlotCurve::setPen(const QPen &p)
{
if ( p != d_data->pen )
{
d_data->pen = p;
itemChanged();
}
}
/*!
\brief Return the pen used to draw the lines
\sa setPen(), brush()
*/
const QPen& QwtPlotCurve::pen() const
{
return d_data->pen;
}
/*!
\brief Assign a brush.
In case of brush.style() != QBrush::NoBrush
and style() != QwtPlotCurve::Sticks
the area between the curve and the baseline will be filled.
In case !brush.color().isValid() the area will be filled by
pen.color(). The fill algorithm simply connects the first and the
last curve point to the baseline. So the curve data has to be sorted
(ascending or descending).
\param brush New brush
\sa brush(), setBaseline(), baseline()
*/
void QwtPlotCurve::setBrush(const QBrush &brush)
{
if ( brush != d_data->brush )
{
d_data->brush = brush;
itemChanged();
}
}
/*!
\brief Return the brush used to fill the area between lines and the baseline
\sa setBrush(), setBaseline(), baseline()
*/
const QBrush& QwtPlotCurve::brush() const
{
return d_data->brush;
}
/*!
Set data by copying x- and y-values from specified memory blocks.
Contrary to setCurveRawData(), this function makes a 'deep copy' of
the data.
\param xData pointer to x values
\param yData pointer to y values
\param size size of xData and yData
\sa QwtCPointerData
*/
void QwtPlotCurve::setData(const double *xData, const double *yData, int size)
{
delete d_xy;
d_xy = new QwtArrayData(xData, yData, size);
itemChanged();
}
/*!
\brief Initialize data with x- and y-arrays (explicitly shared)
\param xData x data
\param yData y data
\sa QwtArrayData
*/
void QwtPlotCurve::setData(const QwtArray<double> &xData,
const QwtArray<double> &yData)
{
delete d_xy;
d_xy = new QwtArrayData(xData, yData);
itemChanged();
}
/*!
Initialize data with an array of points (explicitly shared).
\param data Data
\sa QwtPolygonFData
*/
#if QT_VERSION < 0x040000
void QwtPlotCurve::setData(const QwtArray<QwtDoublePoint> &data)
#else
void QwtPlotCurve::setData(const QPolygonF &data)
#endif
{
delete d_xy;
d_xy = new QwtPolygonFData(data);
itemChanged();
}
/*!
Initialize data with a pointer to QwtData.
\param data Data
\sa QwtData::copy()
*/
void QwtPlotCurve::setData(const QwtData &data)
{
delete d_xy;
d_xy = data.copy();
itemChanged();
}
/*!
\brief Initialize the data by pointing to memory blocks which are not managed
by QwtPlotCurve.
setRawData is provided for efficiency. It is important to keep the pointers
during the lifetime of the underlying QwtCPointerData class.
\param xData pointer to x data
\param yData pointer to y data
\param size size of x and y
\sa QwtCPointerData::setData.
*/
void QwtPlotCurve::setRawData(const double *xData, const double *yData, int size)
{
delete d_xy;
d_xy = new QwtCPointerData(xData, yData, size);
itemChanged();
}
/*!
Returns the bounding rectangle of the curve data. If there is
no bounding rect, like for empty data the rectangle is invalid.
\sa QwtData::boundingRect(), QwtDoubleRect::isValid()
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -