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>
29static inline QRectF qwtIntersectedClipRect(
const QRectF& rect, QPainter* painter )
31 QRectF clipRect = rect;
32 if ( painter->hasClipping() )
33 clipRect &= painter->clipBoundingRect();
38static void qwtUpdateLegendIconSize(
QwtPlotCurve* curve )
50 int w = qwtCeil( 1.5 * sz.width() );
54 sz.setWidth( qMax( 8, w ) );
61static int qwtVerifyRange(
int size,
int& i1,
int& i2 )
66 i1 = qBound( 0, i1, size - 1 );
67 i2 = qBound( 0, i2, size - 1 );
72 return ( i2 - i1 + 1 );
75class QwtPlotCurve::PrivateData
141 m_data =
new PrivateData;
163 m_data->paintAttributes |= attribute;
165 m_data->paintAttributes &= ~attribute;
174 return ( m_data->paintAttributes & attribute );
189 m_data->legendAttributes |= attribute;
191 m_data->legendAttributes &= ~attribute;
193 qwtUpdateLegendIconSize(
this );
204 return ( m_data->legendAttributes & attribute );
215 if ( attributes != m_data->legendAttributes )
217 m_data->legendAttributes = attributes;
219 qwtUpdateLegendIconSize(
this );
230 return m_data->legendAttributes;
241 if (
style != m_data->style )
243 m_data->style =
style;
256 return m_data->style;
271 if (
symbol != m_data->symbol )
273 delete m_data->symbol;
276 qwtUpdateLegendIconSize(
this );
289 return m_data->symbol;
318 if (
pen != m_data->pen )
353 if (
brush != m_data->brush )
355 m_data->brush =
brush;
368 return m_data->brush;
386 const QRectF& canvasRect,
int from,
int to )
const
388 const size_t numSamples =
dataSize();
390 if ( !painter || numSamples <= 0 )
396 if ( qwtVerifyRange( numSamples, from, to ) > 0 )
399 painter->setPen( m_data->pen );
407 drawCurve( painter, m_data->style, xMap, yMap, canvasRect, from, to );
410 if ( m_data->symbol &&
415 xMap, yMap, canvasRect, from, to );
434 const QRectF& canvasRect,
int from,
int to )
const
446 drawLines( painter, xMap, yMap, canvasRect, from, to );
449 drawSticks( painter, xMap, yMap, canvasRect, from, to );
452 drawSteps( painter, xMap, yMap, canvasRect, from, to );
455 drawDots( painter, xMap, yMap, canvasRect, from, to );
481 const QRectF& canvasRect,
int from,
int to )
const
486 const bool doFit = ( m_data->attributes &
Fitted ) && m_data->curveFitter;
488 const bool doFill = ( m_data->brush.style() != Qt::NoBrush )
489 && ( m_data->brush.color().alpha() > 0 );
494 clipRect = qwtIntersectedClipRect( canvasRect, painter );
497 clipRect = clipRect.adjusted(-pw, -pw, pw, pw);
515 QPolygonF polyline = mapper.
toPolygonF( xMap, yMap,
data(), from, to );
525 polyline = m_data->curveFitter->
fitCurve( polyline );
528 if ( painter->pen().style() != Qt::NoPen )
533 QPolygonF filled = polyline;
534 fillCurve( painter, xMap, yMap, canvasRect, filled );
544 fillCurve( painter, xMap, yMap, canvasRect, polyline );
558 const QPainterPath curvePath =
561 painter->drawPath( curvePath );
565 polyline = m_data->curveFitter->
fitCurve( polyline );
590 const QRectF& canvasRect,
int from,
int to )
const
592 Q_UNUSED( canvasRect )
595 painter->setRenderHint( QPainter::Antialiasing,
false );
599 double x0 = xMap.
transform( m_data->baseline );
600 double y0 = yMap.
transform( m_data->baseline );
611 for (
int i = from; i <= to; i++ )
622 if ( o == Qt::Horizontal )
645 const QRectF& canvasRect,
int from,
int to )
const
647 const QColor color = painter->pen().color();
649 if ( painter->pen().style() == Qt::NoPen || color.alpha() == 0 )
654 const bool doFill = ( m_data->brush.style() != Qt::NoBrush )
655 && ( m_data->brush.color().alpha() > 0 );
664 if ( ( color.alpha() == 255 )
665 && !( painter->renderHints() & QPainter::Antialiasing ) )
676 xMap, yMap,
data(), from, to );
679 fillCurve( painter, xMap, yMap, canvasRect, points );
683 const QImage image = mapper.
toImage( xMap, yMap,
684 data(), from, to, m_data->pen,
685 painter->testRenderHint( QPainter::Antialiasing ),
688 painter->drawImage( canvasRect.toAlignedRect(), image );
694 for (
int i = from; i <= to; i++ )
714 const QPolygon points = mapper.
toPoints(
715 xMap, yMap,
data(), from, to );
721 const QPolygonF points = mapper.
toPointsF(
722 xMap, yMap,
data(), from, to );
746 const QRectF& canvasRect,
int from,
int to )
const
750 QPolygonF polygon( 2 * ( to - from ) + 1 );
751 QPointF* points = polygon.data();
754 if ( m_data->attributes &
Inverted )
755 inverted = !inverted;
760 for ( i = from, ip = 0; i <= to; i++, ip += 2 )
773 const QPointF& p0 = points[ip - 2];
774 QPointF& p = points[ip - 1];
788 points[ip].rx() = xi;
789 points[ip].ry() = yi;
794 QRectF clipRect = qwtIntersectedClipRect( canvasRect, painter );
797 clipRect = clipRect.adjusted(-pw, -pw, pw, pw);
800 clipRect, polygon,
false );
809 if ( m_data->brush.style() != Qt::NoBrush )
810 fillCurve( painter, xMap, yMap, canvasRect, polygon );
824 if (
bool( m_data->attributes & attribute ) == on )
828 m_data->attributes |= attribute;
830 m_data->attributes &= ~attribute;
841 return m_data->attributes & attribute;
863 delete m_data->curveFitter;
877 return m_data->curveFitter;
894 const QRectF& canvasRect, QPolygonF& polygon )
const
896 if ( m_data->brush.style() == Qt::NoBrush )
900 if ( polygon.count() <= 2 )
903 QBrush
brush = m_data->brush;
904 if ( !
brush.color().isValid() )
905 brush.setColor( m_data->pen.color() );
909 const QRectF clipRect = qwtIntersectedClipRect( canvasRect, painter );
915 painter->setPen( Qt::NoPen );
916 painter->setBrush(
brush );
934 QPolygonF& polygon )
const
936 if ( polygon.size() < 2 )
949 if ( doAlign && qAbs( refY ) < std::numeric_limits< int >::max() )
950 refY = qRound( refY );
952 polygon += QPointF( polygon.last().x(), refY );
953 polygon += QPointF( polygon.first().x(), refY );
961 if ( doAlign && qAbs( refX ) < std::numeric_limits< int >::max() )
962 refX = qRound( refX );
964 polygon += QPointF( refX, polygon.last().y() );
965 polygon += QPointF( refX, polygon.first().y() );
984 const QRectF& canvasRect,
int from,
int to )
const
992 const QRectF clipRect = qwtIntersectedClipRect( canvasRect, painter );
995 const int chunkSize = 500;
997 for (
int i = from; i <= to; i += chunkSize )
999 const int n = qMin( chunkSize, to - i + 1 );
1001 const QPolygonF points = mapper.
toPointsF( xMap, yMap,
1002 data(), i, i + n - 1 );
1004 if ( points.size() > 0 )
1027 if ( m_data->baseline != value )
1029 m_data->baseline = value;
1040 return m_data->baseline;
1061 const size_t numSamples =
dataSize();
1062 if ( numSamples <= 0 )
1071 double dmin = 1.0e10;
1073 for ( uint i = 0; i < numSamples; i++ )
1080 const double f = qwtSqr( cx ) + qwtSqr( cy );
1088 *dist = std::sqrt( dmin );
1118 inline bool operator()(
const double x,
const QPointF& pos )
const
1120 return ( x < pos.x() );
1124 return qwtUpperSampleIndex< QPointF >( *
data, value, compareX() );
1130 inline bool operator()(
const double y,
const QPointF& pos )
const
1132 return ( y < pos.y() );
1136 return qwtUpperSampleIndex< QPointF >( *
data, value, compareY() );
1161 if ( br.width() <= 0.0 )
1168 if ( value < br.left() || value > br.right() )
1177 if ( value != last.x() )
1184 const QLineF line(
sample( index - 1 ),
sample( index ) );
1185 v = line.pointAt( ( value - line.p1().x() ) / line.dx() ).y();
1190 if ( value < br.top() || value > br.bottom() )
1199 if ( value != last.y() )
1206 const QLineF line(
sample( index - 1 ),
sample( index ) );
1207 v = line.pointAt( ( value - line.p1().y() ) / line.dy() ).x();
1227 if ( size.isEmpty() )
1234 QPainter painter( &graphic );
1235 painter.setRenderHint( QPainter::Antialiasing,
1238 if ( m_data->legendAttributes == 0 ||
1241 QBrush
brush = m_data->brush;
1243 if (
brush.style() == Qt::NoBrush &&
1244 m_data->legendAttributes == 0 )
1250 else if ( m_data->symbol &&
1253 brush = QBrush( m_data->symbol->
pen().color() );
1257 if (
brush.style() != Qt::NoBrush )
1259 QRectF r( 0, 0, size.width(), size.height() );
1260 painter.fillRect( r,
brush );
1266 if (
pen() != Qt::NoPen )
1269 pn.setCapStyle( Qt::FlatCap );
1271 painter.setPen( pn );
1273 const double y = 0.5 * size.height();
1280 if ( m_data->symbol )
1282 QRectF r( 0, 0, size.width(), size.height() );
1332 const double* xData,
const double* yData,
int size )
1352 const float* xData,
const float* yData,
int size )
1411 const double* xData,
const double* yData,
int size )
1428 const float* xData,
const float* yData,
int size )
Template class for data, that is organized as QVector.
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.
virtual QPainterPath fitCurvePath(const QPolygonF &polygon) const =0
virtual QPolygonF fitCurve(const QPolygonF &polygon) const =0
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.
qreal interpolatedValueAt(Qt::Orientation, double) const
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
virtual int adjacentPoint(Qt::Orientation orientation, qreal value) 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.
bool isAxisValid(QwtAxisId) const
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
virtual QRectF boundingRect() const override
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.
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.
void drawSymbol(QPainter *, const QRectF &) const
Draw the symbol into a rectangle.
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)