1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
2  * Qwt Widget Library
3  * Copyright (C) 1997   Josef Wilgen
4  * Copyright (C) 2002   Uwe Rathmann
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the Qwt License, Version 1.0
8  *****************************************************************************/
9 
10 #ifndef QWT_PLOT_CURVE_H
11 #define QWT_PLOT_CURVE_H
12 
13 #include "qwt_global.h"
14 #include "qwt_plot_seriesitem.h"
15 #include "qwt_series_data.h"
16 #include "qwt_text.h"
17 #include <qpen.h>
18 #include <qstring.h>
19 
20 class QPainter;
21 class QPolygonF;
22 class QwtScaleMap;
23 class QwtSymbol;
24 class QwtCurveFitter;
25 
26 /*!
27   \brief A plot item, that represents a series of points
28 
29   A curve is the representation of a series of points in the x-y plane.
30   It supports different display styles, interpolation ( f.e. spline )
31   and symbols.
32 
33   \par Usage
34   <dl><dt>a) Assign curve properties</dt>
35   <dd>When a curve is created, it is configured to draw black solid lines
36   with in QwtPlotCurve::Lines style and no symbols.
37   You can change this by calling
38   setPen(), setStyle() and setSymbol().</dd>
39   <dt>b) Connect/Assign data.</dt>
40   <dd>QwtPlotCurve gets its points using a QwtSeriesData object offering
41   a bridge to the real storage of the points ( like QAbstractItemModel ).
42   There are several convenience classes derived from QwtSeriesData, that also store
43   the points inside ( like QStandardItemModel ). QwtPlotCurve also offers
44   a couple of variations of setSamples(), that build QwtSeriesData objects from
45   arrays internally.</dd>
46   <dt>c) Attach the curve to a plot</dt>
47   <dd>See QwtPlotItem::attach()
48   </dd></dl>
49 
50   \par Example:
51   see examples/bode
52 
53   \sa QwtPointSeriesData, QwtSymbol, QwtScaleMap
54 */
55 class QWT_EXPORT QwtPlotCurve:
56     public QwtPlotSeriesItem, public QwtSeriesStore<QPointF>
57 {
58 public:
59     /*!
60         Curve styles.
61         \sa setStyle(), style()
62     */
63     enum CurveStyle
64     {
65         /*!
66            Don't draw a curve. Note: This doesn't affect the symbols.
67         */
68         NoCurve = -1,
69 
70         /*!
71            Connect the points with straight lines. The lines might
72            be interpolated depending on the 'Fitted' attribute. Curve
73            fitting can be configured using setCurveFitter().
74         */
75         Lines,
76 
77         /*!
78            Draw vertical or horizontal sticks ( depending on the
79            orientation() ) from a baseline which is defined by setBaseline().
80         */
81         Sticks,
82 
83         /*!
84            Connect the points with a step function. The step function
85            is drawn from the left to the right or vice versa,
86            depending on the QwtPlotCurve::Inverted attribute.
87         */
88         Steps,
89 
90         /*!
91            Draw dots at the locations of the data points. Note:
92            This is different from a dotted line (see setPen()), and faster
93            as a curve in QwtPlotCurve::NoStyle style and a symbol
94            painting a point.
95         */
96         Dots,
97 
98         /*!
99            Styles >= QwtPlotCurve::UserCurve are reserved for derived
100            classes of QwtPlotCurve that overload drawCurve() with
101            additional application specific curve types.
102         */
103         UserCurve = 100
104     };
105 
106     /*!
107       Attribute for drawing the curve
108       \sa setCurveAttribute(), testCurveAttribute(), curveFitter()
109     */
110     enum CurveAttribute
111     {
112         /*!
113            For QwtPlotCurve::Steps only.
114            Draws a step function from the right to the left.
115          */
116         Inverted = 0x01,
117 
118         /*!
119           Only in combination with QwtPlotCurve::Lines
120           A QwtCurveFitter tries to
121           interpolate/smooth the curve, before it is painted.
122 
123           \note Curve fitting requires temporary memory
124           for calculating coefficients and additional points.
125           If painting in QwtPlotCurve::Fitted mode is slow it might be better
126           to fit the points, before they are passed to QwtPlotCurve.
127          */
128         Fitted = 0x02
129     };
130 
131     //! Curve attributes
132     typedef QFlags<CurveAttribute> CurveAttributes;
133 
134     /*!
135         Attributes how to represent the curve on the legend
136 
137         \sa setLegendAttribute(), testLegendAttribute(),
138             QwtPlotItem::legendData(), legendIcon()
139      */
140 
141     enum LegendAttribute
142     {
143         /*!
144           QwtPlotCurve tries to find a color representing the curve
145           and paints a rectangle with it.
146          */
147         LegendNoAttribute = 0x00,
148 
149         /*!
150           If the style() is not QwtPlotCurve::NoCurve a line
151           is painted with the curve pen().
152          */
153         LegendShowLine = 0x01,
154 
155         /*!
156           If the curve has a valid symbol it is painted.
157          */
158         LegendShowSymbol = 0x02,
159 
160         /*!
161           If the curve has a brush a rectangle filled with the
162           curve brush() is painted.
163          */
164         LegendShowBrush = 0x04
165     };
166 
167     //! Legend attributes
168     typedef QFlags<LegendAttribute> LegendAttributes;
169 
170     /*!
171         Attributes to modify the drawing algorithm.
172         The default setting enables ClipPolygons | FilterPoints
173 
174         \sa setPaintAttribute(), testPaintAttribute()
175     */
176     enum PaintAttribute
177     {
178         /*!
179           Clip polygons before painting them. In situations, where points
180           are far outside the visible area (f.e when zooming deep) this
181           might be a substantial improvement for the painting performance
182          */
183         ClipPolygons = 0x01,
184 
185         /*!
186           Tries to reduce the data that has to be painted, by sorting out
187           duplicates, or paintings outside the visible area. Might have a
188           notable impact on curves with many close points.
189           Only a couple of very basic filtering algorithms are implemented.
190          */
191         FilterPoints = 0x02,
192 
193         /*!
194           Minimize memory usage that is temporarily needed for the
195           translated points, before they get painted.
196           This might slow down the performance of painting
197          */
198         MinimizeMemory = 0x04,
199 
200         /*!
201           Render the points to a temporary image and paint the image.
202           This is a very special optimization for Dots style, when
203           having a huge amount of points.
204           With a reasonable number of points QPainter::drawPoints()
205           will be faster.
206          */
207         ImageBuffer = 0x08
208     };
209 
210     //! Paint attributes
211     typedef QFlags<PaintAttribute> PaintAttributes;
212 
213     explicit QwtPlotCurve( const QString &title = QString() );
214     explicit QwtPlotCurve( const QwtText &title );
215 
216     virtual ~QwtPlotCurve();
217 
218     virtual int rtti() const;
219 
220     void setPaintAttribute( PaintAttribute, bool on = true );
221     bool testPaintAttribute( PaintAttribute ) const;
222 
223     void setLegendAttribute( LegendAttribute, bool on = true );
224     bool testLegendAttribute( LegendAttribute ) const;
225 
226 #ifndef QWT_NO_COMPAT
227     void setRawSamples( const double *xData, const double *yData, int size );
228     void setSamples( const double *xData, const double *yData, int size );
229     void setSamples( const QVector<double> &xData, const QVector<double> &yData );
230 #endif
231     void setSamples( const QVector<QPointF> & );
232     void setSamples( QwtSeriesData<QPointF> * );
233 
234     int closestPoint( const QPoint &pos, double *dist = NULL ) const;
235 
236     double minXValue() const;
237     double maxXValue() const;
238     double minYValue() const;
239     double maxYValue() const;
240 
241     void setCurveAttribute( CurveAttribute, bool on = true );
242     bool testCurveAttribute( CurveAttribute ) const;
243 
244     void setPen( const QColor &, qreal width = 0.0, Qt::PenStyle = Qt::SolidLine );
245     void setPen( const QPen & );
246     const QPen &pen() const;
247 
248     void setBrush( const QBrush & );
249     const QBrush &brush() const;
250 
251     void setBaseline( double );
252     double baseline() const;
253 
254     void setStyle( CurveStyle style );
255     CurveStyle style() const;
256 
257     void setSymbol( QwtSymbol * );
258     const QwtSymbol *symbol() const;
259 
260     void setCurveFitter( QwtCurveFitter * );
261     QwtCurveFitter *curveFitter() const;
262 
263     virtual void drawSeries( QPainter *,
264         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
265         const QRectF &canvasRect, int from, int to ) const;
266 
267     virtual QwtGraphic legendIcon( int index, const QSizeF & ) const;
268 
269 protected:
270 
271     void init();
272 
273     virtual void drawCurve( QPainter *, int style,
274         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
275         const QRectF &canvasRect, int from, int to ) const;
276 
277     virtual void drawSymbols( QPainter *, const QwtSymbol &,
278         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
279         const QRectF &canvasRect, int from, int to ) const;
280 
281     virtual void drawLines( QPainter *,
282         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
283         const QRectF &canvasRect, int from, int to ) const;
284 
285     virtual void drawSticks( QPainter *,
286         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
287         const QRectF &canvasRect, int from, int to ) const;
288 
289     virtual void drawDots( QPainter *,
290         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
291         const QRectF &canvasRect, int from, int to ) const;
292 
293     virtual void drawSteps( QPainter *,
294         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
295         const QRectF &canvasRect, int from, int to ) const;
296 
297     virtual void fillCurve( QPainter *,
298         const QwtScaleMap &, const QwtScaleMap &,
299         const QRectF &canvasRect, QPolygonF & ) const;
300 
301     void closePolyline( QPainter *,
302         const QwtScaleMap &, const QwtScaleMap &, QPolygonF & ) const;
303 
304 private:
305     class PrivateData;
306     PrivateData *d_data;
307 };
308 
309 //! boundingRect().left()
minXValue()310 inline double QwtPlotCurve::minXValue() const
311 {
312     return boundingRect().left();
313 }
314 
315 //! boundingRect().right()
maxXValue()316 inline double QwtPlotCurve::maxXValue() const
317 {
318     return boundingRect().right();
319 }
320 
321 //! boundingRect().top()
minYValue()322 inline double QwtPlotCurve::minYValue() const
323 {
324     return boundingRect().top();
325 }
326 
327 //! boundingRect().bottom()
maxYValue()328 inline double QwtPlotCurve::maxYValue() const
329 {
330     return boundingRect().bottom();
331 }
332 
333 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotCurve::PaintAttributes )
334 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotCurve::LegendAttributes )
335 Q_DECLARE_OPERATORS_FOR_FLAGS( QwtPlotCurve::CurveAttributes )
336 
337 #endif
338