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 <qpen.h>
14 #include <qstring.h>
15 #include "qwt_global.h"
16 #include "qwt_plot_item.h"
17 #include "qwt_text.h"
18 #include "qwt_polygon.h"
19 #include "qwt_data.h"
20 
21 class QPainter;
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 Lines style and no symbols. You can change this by calling
37   setPen(), setStyle() and setSymbol().</dd>
38   <dt>b) Connect/Assign data.</dt>
39   <dd>QwtPlotCurve gets its points using a QwtData object offering
40   a bridge to the real storage of the points ( like QAbstractItemModel ).
41   There are several convenience classes derived from QwtData, that also store
42   the points inside ( like QStandardItemModel ). QwtPlotCurve also offers
43   a couple of variations of setData(), that build QwtData objects from
44   arrays internally.</dd>
45   <dt>c) Attach the curve to a plot</dt>
46   <dd>See QwtPlotItem::attach()
47   </dd></dl>
48 
49   \par Example:
50   see examples/bode
51 
52   \sa QwtPlot, QwtData, QwtSymbol, QwtScaleMap
53 */
54 class QWT_EXPORT QwtPlotCurve: public QwtPlotItem
55 {
56 public:
57     /*!
58        Curve type.
59 
60        - Yfx\n
61          Draws y as a function of x (the default). The
62          baseline is interpreted as a horizontal line
63          with y = baseline().
64        - Xfy\n
65          Draws x as a function of y. The baseline is
66          interpreted as a vertical line with x = baseline().
67 
68        The baseline is used for aligning the sticks, or
69        filling the curve with a brush.
70 
71        \sa setCurveType(), curveType(), baseline() brush()
72      */
73     enum CurveType
74     {
75         Yfx,
76         Xfy
77     };
78 
79     /*!
80         Curve styles.
81 
82          - NoCurve\n
83            Don't draw a curve. Note: This doesn't affect the symbols.
84          - Lines\n
85            Connect the points with straight lines. The lines might
86            be interpolated depending on the 'Fitted' attribute. Curve
87            fitting can be configured using setCurveFitter().
88          - Sticks\n
89            Draw vertical(Yfx) or horizontal(Xfy) sticks from a baseline
90            which is defined by setBaseline().
91          - Steps\n
92            Connect the points with a step function. The step function
93            is drawn from the left to the right or vice versa,
94            depending on the 'Inverted' attribute.
95          - Dots\n
96            Draw dots at the locations of the data points. Note:
97            This is different from a dotted line (see setPen()), and faster
98            as a curve in NoStyle style and a symbol painting a point.
99          - UserCurve\n
100            Styles >= UserCurve are reserved for derived
101            classes of QwtPlotCurve that overload drawCurve() with
102            additional application specific curve types.
103 
104         \sa setStyle(), style()
105     */
106     enum CurveStyle
107     {
108         NoCurve,
109 
110         Lines,
111         Sticks,
112         Steps,
113         Dots,
114 
115         UserCurve = 100
116     };
117 
118     /*!
119       Attribute for drawing the curve
120 
121       - Fitted ( in combination with the Lines QwtPlotCurve::CurveStyle only )\n
122         A QwtCurveFitter tries to
123         interpolate/smooth the curve, before it is painted.
124         Note that curve fitting requires temorary memory
125         for calculating coefficients and additional points.
126         If painting in Fitted mode is slow it might be better
127         to fit the points, before they are passed to QwtPlotCurve.
128       - Inverted\n
129         For Steps only. Draws a step function
130         from the right to the left.
131 
132         \sa setCurveAttribute(), testCurveAttribute(), curveFitter()
133     */
134     enum CurveAttribute
135     {
136         Inverted = 1,
137         Fitted = 2
138     };
139 
140     /*!
141         Attributes to modify the drawing algorithm.
142 
143         - PaintFiltered\n
144           Tries to reduce the data that has to be painted, by sorting out
145           duplicates, or paintings outside the visible area. Might have a
146           notable impact on curves with many close points.
147           Only a couple of very basic filtering algos are implemented.
148         - ClipPolygons\n
149           Clip polygons before painting them. In situations, where points
150           are far outside the visible area (f.e when zooming deep) this
151           might be a substantial improvement for the painting performance
152           ( especially on Windows ).
153 
154         The default is, that no paint attributes are enabled.
155 
156         \sa setPaintAttribute(), testPaintAttribute()
157     */
158     enum PaintAttribute
159     {
160         PaintFiltered = 1,
161         ClipPolygons = 2
162     };
163 
164     explicit QwtPlotCurve();
165     explicit QwtPlotCurve(const QwtText &title);
166     explicit QwtPlotCurve(const QString &title);
167 
168     virtual ~QwtPlotCurve();
169 
170     virtual int rtti() const;
171 
172     void setCurveType(CurveType);
173     CurveType curveType() const;
174 
175     void setPaintAttribute(PaintAttribute, bool on = true);
176     bool testPaintAttribute(PaintAttribute) const;
177 
178     void setRawData(const double *x, const double *y, int size);
179     void setData(const double *xData, const double *yData, int size);
180     void setData(const QwtArray<double> &xData, const QwtArray<double> &yData);
181 #if QT_VERSION < 0x040000
182     void setData(const QwtArray<QwtDoublePoint> &data);
183 #else
184     void setData(const QPolygonF &data);
185 #endif
186     void setData(const QwtData &data);
187 
188     int closestPoint(const QPoint &pos, double *dist = NULL) const;
189 
190     QwtData &data();
191     const QwtData &data() const;
192 
193     int dataSize() const;
194     double x(int i) const;
195     double y(int i) const;
196 
197     virtual QwtDoubleRect boundingRect() const;
198 
199     double minXValue() const;
200     double maxXValue() const;
201     double minYValue() const;
202     double maxYValue() const;
203 
204     void setCurveAttribute(CurveAttribute, bool on = true);
205     bool testCurveAttribute(CurveAttribute) const;
206 
207     void setPen(const QPen &);
208     const QPen &pen() const;
209 
210     void setBrush(const QBrush &);
211     const QBrush &brush() const;
212 
213     void setBaseline(double ref);
214     double baseline() const;
215 
216     void setStyle(CurveStyle style);
217     CurveStyle style() const;
218 
219     void setSymbol(const QwtSymbol &s);
220     const QwtSymbol& symbol() const;
221 
222     void setCurveFitter(QwtCurveFitter *);
223     QwtCurveFitter *curveFitter() const;
224 
225     virtual void draw(QPainter *p,
226         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
227         const QRect &) const;
228 
229     virtual void draw(QPainter *p,
230         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
231         int from, int to) const;
232 
233     void draw(int from, int to) const;
234 
235     virtual void updateLegend(QwtLegend *) const;
236 
237 protected:
238 
239     void init();
240 
241     virtual void drawCurve(QPainter *p, int style,
242         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
243         int from, int to) const;
244 
245     virtual void drawSymbols(QPainter *p, const QwtSymbol &,
246         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
247         int from, int to) const;
248 
249     void drawLines(QPainter *p,
250         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
251         int from, int to) const;
252     void drawSticks(QPainter *p,
253         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
254         int from, int to) const;
255     void drawDots(QPainter *p,
256         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
257         int from, int to) const;
258     void drawSteps(QPainter *p,
259         const QwtScaleMap &xMap, const QwtScaleMap &yMap,
260         int from, int to) const;
261 
262     void fillCurve(QPainter *,
263         const QwtScaleMap &, const QwtScaleMap &,
264         QwtPolygon &) const;
265     void closePolyline(const QwtScaleMap &, const QwtScaleMap &,
266         QwtPolygon &) const;
267 
268 private:
269     QwtData *d_xy;
270 
271     class PrivateData;
272     PrivateData *d_data;
273 };
274 
275 //! \return the the curve data
data()276 inline QwtData &QwtPlotCurve::data()
277 {
278     return *d_xy;
279 }
280 
281 //! \return the the curve data
data()282 inline const QwtData &QwtPlotCurve::data() const
283 {
284     return *d_xy;
285 }
286 
287 /*!
288     \param i index
289     \return x-value at position i
290 */
x(int i)291 inline double QwtPlotCurve::x(int i) const
292 {
293     return d_xy->x(i);
294 }
295 
296 /*!
297     \param i index
298     \return y-value at position i
299 */
y(int i)300 inline double QwtPlotCurve::y(int i) const
301 {
302     return d_xy->y(i);
303 }
304 
305 //! boundingRect().left()
minXValue()306 inline double QwtPlotCurve::minXValue() const
307 {
308     return boundingRect().left();
309 }
310 
311 //! boundingRect().right()
maxXValue()312 inline double QwtPlotCurve::maxXValue() const
313 {
314     return boundingRect().right();
315 }
316 
317 //! boundingRect().top()
minYValue()318 inline double QwtPlotCurve::minYValue() const
319 {
320     return boundingRect().top();
321 }
322 
323 //! boundingRect().bottom()
maxYValue()324 inline double QwtPlotCurve::maxYValue() const
325 {
326     return boundingRect().bottom();
327 }
328 
329 #endif
330