10 #include "qwt_plot_curve.h"
11 #include "qwt_point_data.h"
13 #include "qwt_clipper.h"
14 #include "qwt_painter.h"
15 #include "qwt_scale_map.h"
17 #include "qwt_spline_curve_fitter.h"
18 #include "qwt_symbol.h"
19 #include "qwt_point_mapper.h"
21 #include "qwt_graphic.h"
24 #include <qpainterpath.h>
26 static inline QRectF qwtIntersectedClipRect(
const QRectF& rect, QPainter* painter )
28 QRectF clipRect = rect;
29 if ( painter->hasClipping() )
30 clipRect &= painter->clipBoundingRect();
35 static void qwtUpdateLegendIconSize(
QwtPlotCurve* curve )
47 int w = qwtCeil( 1.5 * sz.width() );
51 sz.setWidth( qMax( 8, w ) );
58 static int qwtVerifyRange(
int size,
int& i1,
int& i2 )
63 i1 = qBound( 0, i1, size - 1 );
64 i2 = qBound( 0, i2, size - 1 );
69 return ( i2 - i1 + 1 );
72 class QwtPlotCurve::PrivateData
138 m_data =
new PrivateData;
160 m_data->paintAttributes |= attribute;
162 m_data->paintAttributes &= ~attribute;
171 return ( m_data->paintAttributes & attribute );
186 m_data->legendAttributes |= attribute;
188 m_data->legendAttributes &= ~attribute;
190 qwtUpdateLegendIconSize(
this );
201 return ( m_data->legendAttributes & attribute );
212 if ( attributes != m_data->legendAttributes )
214 m_data->legendAttributes = attributes;
216 qwtUpdateLegendIconSize(
this );
227 return m_data->legendAttributes;
238 if (
style != m_data->style )
240 m_data->style =
style;
253 return m_data->style;
268 if (
symbol != m_data->symbol )
270 delete m_data->symbol;
273 qwtUpdateLegendIconSize(
this );
286 return m_data->symbol;
315 if (
pen != m_data->pen )
350 if (
brush != m_data->brush )
352 m_data->brush =
brush;
365 return m_data->brush;
383 const QRectF& canvasRect,
int from,
int to )
const
385 const size_t numSamples =
dataSize();
387 if ( !painter || numSamples <= 0 )
393 if ( qwtVerifyRange( numSamples, from, to ) > 0 )
396 painter->setPen( m_data->pen );
404 drawCurve( painter, m_data->style, xMap, yMap, canvasRect, from, to );
407 if ( m_data->symbol &&
412 xMap, yMap, canvasRect, from, to );
431 const QRectF& canvasRect,
int from,
int to )
const
443 drawLines( painter, xMap, yMap, canvasRect, from, to );
446 drawSticks( painter, xMap, yMap, canvasRect, from, to );
449 drawSteps( painter, xMap, yMap, canvasRect, from, to );
452 drawDots( painter, xMap, yMap, canvasRect, from, to );
478 const QRectF& canvasRect,
int from,
int to )
const
483 const bool doFit = ( m_data->attributes &
Fitted ) && m_data->curveFitter;
485 const bool doFill = ( m_data->brush.style() != Qt::NoBrush )
486 && ( m_data->brush.color().alpha() > 0 );
491 clipRect = qwtIntersectedClipRect( canvasRect, painter );
494 clipRect = clipRect.adjusted(-pw, -pw, pw, pw);
512 QPolygonF polyline = mapper.
toPolygonF( xMap, yMap,
data(), from, to );
522 polyline = m_data->curveFitter->fitCurve( polyline );
525 if ( painter->pen().style() != Qt::NoPen )
530 QPolygonF filled = polyline;
531 fillCurve( painter, xMap, yMap, canvasRect, filled );
541 fillCurve( painter, xMap, yMap, canvasRect, polyline );
555 const QPainterPath curvePath =
556 m_data->curveFitter->fitCurvePath( polyline );
558 painter->drawPath( curvePath );
562 polyline = m_data->curveFitter->fitCurve( polyline );
587 const QRectF& canvasRect,
int from,
int to )
const
589 Q_UNUSED( canvasRect )
592 painter->setRenderHint( QPainter::Antialiasing,
false );
596 double x0 = xMap.
transform( m_data->baseline );
597 double y0 = yMap.
transform( m_data->baseline );
608 for (
int i = from; i <= to; i++ )
619 if ( o == Qt::Horizontal )
642 const QRectF& canvasRect,
int from,
int to )
const
644 const QColor color = painter->pen().color();
646 if ( painter->pen().style() == Qt::NoPen || color.alpha() == 0 )
651 const bool doFill = ( m_data->brush.style() != Qt::NoBrush )
652 && ( m_data->brush.color().alpha() > 0 );
661 if ( ( color.alpha() == 255 )
662 && !( painter->renderHints() & QPainter::Antialiasing ) )
673 xMap, yMap,
data(), from, to );
676 fillCurve( painter, xMap, yMap, canvasRect, points );
680 const QImage image = mapper.
toImage( xMap, yMap,
681 data(), from, to, m_data->pen,
682 painter->testRenderHint( QPainter::Antialiasing ),
685 painter->drawImage( canvasRect.toAlignedRect(), image );
691 for (
int i = from; i <= to; i++ )
711 const QPolygon points = mapper.
toPoints(
712 xMap, yMap,
data(), from, to );
718 const QPolygonF points = mapper.
toPointsF(
719 xMap, yMap,
data(), from, to );
743 const QRectF& canvasRect,
int from,
int to )
const
747 QPolygonF polygon( 2 * ( to - from ) + 1 );
748 QPointF* points = polygon.data();
751 if ( m_data->attributes &
Inverted )
752 inverted = !inverted;
757 for ( i = from, ip = 0; i <= to; i++, ip += 2 )
770 const QPointF& p0 = points[ip - 2];
771 QPointF& p = points[ip - 1];
785 points[ip].rx() = xi;
786 points[ip].ry() = yi;
791 QRectF clipRect = qwtIntersectedClipRect( canvasRect, painter );
794 clipRect = clipRect.adjusted(-pw, -pw, pw, pw);
797 clipRect, polygon,
false );
806 if ( m_data->brush.style() != Qt::NoBrush )
807 fillCurve( painter, xMap, yMap, canvasRect, polygon );
821 if (
bool( m_data->attributes & attribute ) == on )
825 m_data->attributes |= attribute;
827 m_data->attributes &= ~attribute;
838 return m_data->attributes & attribute;
860 delete m_data->curveFitter;
874 return m_data->curveFitter;
891 const QRectF& canvasRect, QPolygonF& polygon )
const
893 if ( m_data->brush.style() == Qt::NoBrush )
897 if ( polygon.count() <= 2 )
900 QBrush
brush = m_data->brush;
901 if ( !
brush.color().isValid() )
902 brush.setColor( m_data->pen.color() );
906 const QRectF clipRect = qwtIntersectedClipRect( canvasRect, painter );
912 painter->setPen( Qt::NoPen );
913 painter->setBrush(
brush );
931 QPolygonF& polygon )
const
933 if ( polygon.size() < 2 )
947 refY = qRound( refY );
949 polygon += QPointF( polygon.last().x(), refY );
950 polygon += QPointF( polygon.first().x(), refY );
959 refX = qRound( refX );
961 polygon += QPointF( refX, polygon.last().y() );
962 polygon += QPointF( refX, polygon.first().y() );
981 const QRectF& canvasRect,
int from,
int to )
const
989 const QRectF clipRect = qwtIntersectedClipRect( canvasRect, painter );
992 const int chunkSize = 500;
994 for (
int i = from; i <= to; i += chunkSize )
996 const int n = qMin( chunkSize, to - i + 1 );
998 const QPolygonF points = mapper.
toPointsF( xMap, yMap,
999 data(), i, i + n - 1 );
1001 if ( points.size() > 0 )
1024 if ( m_data->baseline != value )
1026 m_data->baseline = value;
1037 return m_data->baseline;
1053 const size_t numSamples =
dataSize();
1055 if (
plot() == NULL || numSamples <= 0 )
1064 double dmin = 1.0e10;
1066 for ( uint i = 0; i < numSamples; i++ )
1073 const double f = qwtSqr( cx ) + qwtSqr( cy );
1081 *dist = std::sqrt( dmin );
1099 if ( size.isEmpty() )
1106 QPainter painter( &graphic );
1107 painter.setRenderHint( QPainter::Antialiasing,
1110 if ( m_data->legendAttributes == 0 ||
1113 QBrush
brush = m_data->brush;
1115 if (
brush.style() == Qt::NoBrush &&
1116 m_data->legendAttributes == 0 )
1122 else if ( m_data->symbol &&
1125 brush = QBrush( m_data->symbol->pen().color() );
1129 if (
brush.style() != Qt::NoBrush )
1131 QRectF r( 0, 0, size.width(), size.height() );
1132 painter.fillRect( r,
brush );
1138 if (
pen() != Qt::NoPen )
1141 pn.setCapStyle( Qt::FlatCap );
1143 painter.setPen( pn );
1145 const double y = 0.5 * size.height();
1152 if ( m_data->symbol )
1154 QRectF r( 0, 0, size.width(), size.height() );
1155 m_data->symbol->drawSymbol( &painter, r );
1204 const double* xData,
const double* yData,
int size )
1224 const float* xData,
const float* yData,
int size )
1283 const double* xData,
const double* yData,
int size )
1300 const float* xData,
const float* yData,
int size )
Data class containing two pointers to memory blocks of T.
Data class containing a pointer to memory of y coordinates.
Abstract base class for a curve fitter.
A paint device for scalable graphics.
void setRenderHint(RenderHint, bool on=true)
void setDefaultSize(const QSizeF &)
Set a default size.
static void drawPoints(QPainter *, const QPolygon &)
Wrapper for QPainter::drawPoints()
static void drawPolygon(QPainter *, const QPolygonF &)
Wrapper for QPainter::drawPolygon()
static void drawPolyline(QPainter *, const QPolygonF &)
Wrapper for QPainter::drawPolyline()
static qreal effectivePenWidth(const QPen &)
static void drawPoint(QPainter *, const QPoint &)
Wrapper for QPainter::drawPoint()
static bool roundingAlignment()
static void drawLine(QPainter *, qreal x1, qreal y1, qreal x2, qreal y2)
Wrapper for QPainter::drawLine()
A plot item, that represents a series of points.
void setLegendAttribute(LegendAttribute, bool on=true)
virtual void drawSeries(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const override
void setLegendAttributes(LegendAttributes)
void closePolyline(QPainter *, const QwtScaleMap &, const QwtScaleMap &, QPolygonF &) const
Complete a polygon to be a closed polygon including the area between the original polygon and the bas...
LegendAttributes legendAttributes() const
virtual void drawCurve(QPainter *, int style, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
Draw the line part (without symbols) of a curve interval.
QFlags< LegendAttribute > LegendAttributes
virtual void fillCurve(QPainter *, const QwtScaleMap &, const QwtScaleMap &, const QRectF &canvasRect, QPolygonF &) const
void setStyle(CurveStyle style)
void setSymbol(QwtSymbol *)
Assign a symbol.
virtual int closestPoint(const QPointF &pos, double *dist=NULL) const
virtual void drawDots(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
QwtPlotCurve(const QString &title=QString())
virtual void drawSticks(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
virtual void drawSymbols(QPainter *, const QwtSymbol &, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
bool testLegendAttribute(LegendAttribute) const
bool testCurveAttribute(CurveAttribute) const
void setCurveAttribute(CurveAttribute, bool on=true)
void init()
Initialize internal members.
void setPaintAttribute(PaintAttribute, bool on=true)
bool testPaintAttribute(PaintAttribute) const
virtual QwtGraphic legendIcon(int index, const QSizeF &) const override
virtual void drawLines(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
Draw lines.
virtual ~QwtPlotCurve()
Destructor.
void setSamples(const double *xData, const double *yData, int size)
void setCurveFitter(QwtCurveFitter *)
const QBrush & brush() const
void setBaseline(double)
Set the value of the baseline.
void setBrush(const QBrush &)
Assign a brush.
const QwtSymbol * symbol() const
QFlags< PaintAttribute > PaintAttributes
void setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
QwtCurveFitter * curveFitter() const
QFlags< CurveAttribute > CurveAttributes
virtual void drawSteps(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
virtual int rtti() const override
void setRawSamples(const double *xData, const double *yData, int size)
Initialize the data by pointing to memory blocks which are not managed by QwtPlotCurve.
virtual QwtScaleMap canvasMap(QwtAxisId) const
QwtAxisId yAxis() const
Return yAxis.
void setLegendIconSize(const QSize &)
virtual void legendChanged()
void setZ(double z)
Set the z value.
void setItemAttribute(ItemAttribute, bool on=true)
QwtPlot * plot() const
Return attached plot.
QwtAxisId xAxis() const
Return xAxis.
@ Rtti_PlotCurve
For QwtPlotCurve.
@ RenderAntialiased
Enable antialiasing.
bool testRenderHint(RenderHint) const
virtual void itemChanged()
@ Legend
The item is represented on the legend.
uint renderThreadCount() const
Base class for plot items representing a series of samples.
Qt::Orientation orientation() const
Interface for iterating over two QVector<T> objects.
A helper class for translating a series of points.
void setBoundingRect(const QRectF &)
QPolygonF toPolygonF(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to) const
Translate a series of points into a QPolygonF.
QImage toImage(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to, const QPen &, bool antialiased, uint numThreads) const
Translate a series into a QImage.
QPolygonF toPointsF(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to) const
Translate a series into a QPolygonF.
void setFlag(TransformationFlag, bool on=true)
@ RoundPoints
Round points to integer values.
@ WeedOutIntermediatePoints
QPolygon toPoints(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtSeriesData< QPointF > *series, int from, int to) const
Translate a series of points into a QPolygon.
Interface for iterating over an array of points.
double transform(double s) const
const QwtTransform * transformation() const
Get the transformation.
virtual T sample(size_t i) const =0
QPointF sample(int index) const
virtual size_t dataSize() const override
QwtSeriesData< QPointF > * data()
void setData(QwtSeriesData< QPointF > *series)
A curve fitter using a spline interpolation.
A class for drawing symbols.
virtual QRect boundingRect() const
void drawSymbols(QPainter *, const QPolygonF &) const
Draw symbols at the specified points.
@ NoSymbol
No Style. The symbol cannot be drawn.
A class representing a text.
Interface for iterating over a QVector<T>.
QWT_EXPORT QPolygonF clippedPolygonF(const QRectF &, const QPolygonF &, bool closePolygon=false)
QWT_EXPORT void clipPolygonF(const QRectF &, QPolygonF &, bool closePolygon=false)