source: ntrip/trunk/BNC/qwt/qwt_series_data.cpp@ 5349

Last change on this file since 5349 was 4271, checked in by mervart, 12 years ago
File size: 13.4 KB
Line 
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#include "qwt_series_data.h"
11#include "qwt_math.h"
12
13static inline QRectF qwtBoundingRect( const QPointF &sample )
14{
15 return QRectF( sample.x(), sample.y(), 0.0, 0.0 );
16}
17
18static inline QRectF qwtBoundingRect( const QwtPoint3D &sample )
19{
20 return QRectF( sample.x(), sample.y(), 0.0, 0.0 );
21}
22
23static inline QRectF qwtBoundingRect( const QwtPointPolar &sample )
24{
25 return QRectF( sample.azimuth(), sample.radius(), 0.0, 0.0 );
26}
27
28static inline QRectF qwtBoundingRect( const QwtIntervalSample &sample )
29{
30 return QRectF( sample.interval.minValue(), sample.value,
31 sample.interval.maxValue() - sample.interval.minValue(), 0.0 );
32}
33
34static inline QRectF qwtBoundingRect( const QwtSetSample &sample )
35{
36 double minX = sample.set[0];
37 double maxX = sample.set[0];
38
39 for ( int i = 1; i < ( int )sample.set.size(); i++ )
40 {
41 if ( sample.set[i] < minX )
42 minX = sample.set[i];
43 if ( sample.set[i] > maxX )
44 maxX = sample.set[i];
45 }
46
47 double minY = sample.value;
48 double maxY = sample.value;
49
50 return QRectF( minX, minY, maxX - minX, maxY - minY );
51}
52
53/*!
54 \brief Calculate the bounding rect of a series subset
55
56 Slow implementation, that iterates over the series.
57
58 \param series Series
59 \param from Index of the first sample, <= 0 means from the beginning
60 \param to Index of the last sample, < 0 means to the end
61
62 \return Bounding rectangle
63*/
64
65template <class T>
66QRectF qwtBoundingRectT(
67 const QwtSeriesData<T>& series, int from, int to )
68{
69 QRectF boundingRect( 1.0, 1.0, -2.0, -2.0 ); // invalid;
70
71 if ( from < 0 )
72 from = 0;
73
74 if ( to < 0 )
75 to = series.size() - 1;
76
77 if ( to < from )
78 return boundingRect;
79
80 int i;
81 for ( i = from; i <= to; i++ )
82 {
83 const QRectF rect = qwtBoundingRect( series.sample( i ) );
84 if ( rect.width() >= 0.0 && rect.height() >= 0.0 )
85 {
86 boundingRect = rect;
87 i++;
88 break;
89 }
90 }
91
92 for ( ; i <= to; i++ )
93 {
94 const QRectF rect = qwtBoundingRect( series.sample( i ) );
95 if ( rect.width() >= 0.0 && rect.height() >= 0.0 )
96 {
97 boundingRect.setLeft( qMin( boundingRect.left(), rect.left() ) );
98 boundingRect.setRight( qMax( boundingRect.right(), rect.right() ) );
99 boundingRect.setTop( qMin( boundingRect.top(), rect.top() ) );
100 boundingRect.setBottom( qMax( boundingRect.bottom(), rect.bottom() ) );
101 }
102 }
103
104 return boundingRect;
105}
106
107/*!
108 \brief Calculate the bounding rect of a series subset
109
110 Slow implementation, that iterates over the series.
111
112 \param series Series
113 \param from Index of the first sample, <= 0 means from the beginning
114 \param to Index of the last sample, < 0 means to the end
115
116 \return Bounding rectangle
117*/
118QRectF qwtBoundingRect(
119 const QwtSeriesData<QPointF> &series, int from, int to )
120{
121 return qwtBoundingRectT<QPointF>( series, from, to );
122}
123
124/*!
125 \brief Calculate the bounding rect of a series subset
126
127 Slow implementation, that iterates over the series.
128
129 \param series Series
130 \param from Index of the first sample, <= 0 means from the beginning
131 \param to Index of the last sample, < 0 means to the end
132
133 \return Bounding rectangle
134*/
135QRectF qwtBoundingRect(
136 const QwtSeriesData<QwtPoint3D> &series, int from, int to )
137{
138 return qwtBoundingRectT<QwtPoint3D>( series, from, to );
139}
140
141/*!
142 \brief Calculate the bounding rect of a series subset
143
144 The horizontal coordinates represent the azimuth, the
145 vertical coordinates the radius.
146
147 Slow implementation, that iterates over the series.
148
149 \param series Series
150 \param from Index of the first sample, <= 0 means from the beginning
151 \param to Index of the last sample, < 0 means to the end
152
153 \return Bounding rectangle
154*/
155QRectF qwtBoundingRect(
156 const QwtSeriesData<QwtPointPolar> &series, int from, int to )
157{
158 return qwtBoundingRectT<QwtPointPolar>( series, from, to );
159}
160
161/*!
162 \brief Calculate the bounding rect of a series subset
163
164 Slow implementation, that iterates over the series.
165
166 \param series Series
167 \param from Index of the first sample, <= 0 means from the beginning
168 \param to Index of the last sample, < 0 means to the end
169
170 \return Bounding rectangle
171*/
172QRectF qwtBoundingRect(
173 const QwtSeriesData<QwtIntervalSample>& series, int from, int to )
174{
175 return qwtBoundingRectT<QwtIntervalSample>( series, from, to );
176}
177
178/*!
179 \brief Calculate the bounding rect of a series subset
180
181 Slow implementation, that iterates over the series.
182
183 \param series Series
184 \param from Index of the first sample, <= 0 means from the beginning
185 \param to Index of the last sample, < 0 means to the end
186
187 \return Bounding rectangle
188*/
189QRectF qwtBoundingRect(
190 const QwtSeriesData<QwtSetSample>& series, int from, int to )
191{
192 return qwtBoundingRectT<QwtSetSample>( series, from, to );
193}
194
195/*!
196 Constructor
197 \param samples Samples
198*/
199QwtPointSeriesData::QwtPointSeriesData(
200 const QVector<QPointF> &samples ):
201 QwtArraySeriesData<QPointF>( samples )
202{
203}
204
205/*!
206 \brief Calculate the bounding rect
207
208 The bounding rectangle is calculated once by iterating over all
209 points and is stored for all following requests.
210
211 \return Bounding rectangle
212*/
213QRectF QwtPointSeriesData::boundingRect() const
214{
215 if ( d_boundingRect.width() < 0.0 )
216 d_boundingRect = qwtBoundingRect( *this );
217
218 return d_boundingRect;
219}
220
221/*!
222 Constructor
223 \param samples Samples
224*/
225QwtPoint3DSeriesData::QwtPoint3DSeriesData(
226 const QVector<QwtPoint3D> &samples ):
227 QwtArraySeriesData<QwtPoint3D>( samples )
228{
229}
230
231/*!
232 \brief Calculate the bounding rect
233
234 The bounding rectangle is calculated once by iterating over all
235 points and is stored for all following requests.
236
237 \return Bounding rectangle
238*/
239QRectF QwtPoint3DSeriesData::boundingRect() const
240{
241 if ( d_boundingRect.width() < 0.0 )
242 d_boundingRect = qwtBoundingRect( *this );
243
244 return d_boundingRect;
245}
246
247/*!
248 Constructor
249 \param samples Samples
250*/
251QwtIntervalSeriesData::QwtIntervalSeriesData(
252 const QVector<QwtIntervalSample> &samples ):
253 QwtArraySeriesData<QwtIntervalSample>( samples )
254{
255}
256
257/*!
258 \brief Calculate the bounding rect
259
260 The bounding rectangle is calculated once by iterating over all
261 points and is stored for all following requests.
262
263 \return Bounding rectangle
264*/
265QRectF QwtIntervalSeriesData::boundingRect() const
266{
267 if ( d_boundingRect.width() < 0.0 )
268 d_boundingRect = qwtBoundingRect( *this );
269
270 return d_boundingRect;
271}
272
273/*!
274 Constructor
275 \param samples Samples
276*/
277QwtSetSeriesData::QwtSetSeriesData(
278 const QVector<QwtSetSample> &samples ):
279 QwtArraySeriesData<QwtSetSample>( samples )
280{
281}
282
283/*!
284 \brief Calculate the bounding rect
285
286 The bounding rectangle is calculated once by iterating over all
287 points and is stored for all following requests.
288
289 \return Bounding rectangle
290*/
291QRectF QwtSetSeriesData::boundingRect() const
292{
293 if ( d_boundingRect.width() < 0.0 )
294 d_boundingRect = qwtBoundingRect( *this );
295
296 return d_boundingRect;
297}
298
299/*!
300 Constructor
301
302 \param x Array of x values
303 \param y Array of y values
304
305 \sa QwtPlotCurve::setData(), QwtPlotCurve::setSamples()
306*/
307QwtPointArrayData::QwtPointArrayData(
308 const QVector<double> &x, const QVector<double> &y ):
309 d_x( x ),
310 d_y( y )
311{
312}
313
314/*!
315 Constructor
316
317 \param x Array of x values
318 \param y Array of y values
319 \param size Size of the x and y arrays
320 \sa QwtPlotCurve::setData(), QwtPlotCurve::setSamples()
321*/
322QwtPointArrayData::QwtPointArrayData( const double *x,
323 const double *y, size_t size )
324{
325 d_x.resize( size );
326 qMemCopy( d_x.data(), x, size * sizeof( double ) );
327
328 d_y.resize( size );
329 qMemCopy( d_y.data(), y, size * sizeof( double ) );
330}
331
332/*!
333 \brief Calculate the bounding rect
334
335 The bounding rectangle is calculated once by iterating over all
336 points and is stored for all following requests.
337
338 \return Bounding rectangle
339*/
340QRectF QwtPointArrayData::boundingRect() const
341{
342 if ( d_boundingRect.width() < 0 )
343 d_boundingRect = qwtBoundingRect( *this );
344
345 return d_boundingRect;
346}
347
348//! \return Size of the data set
349size_t QwtPointArrayData::size() const
350{
351 return qMin( d_x.size(), d_y.size() );
352}
353
354/*!
355 Return the sample at position i
356
357 \param i Index
358 \return Sample at position i
359*/
360QPointF QwtPointArrayData::sample( size_t i ) const
361{
362 return QPointF( d_x[int( i )], d_y[int( i )] );
363}
364
365//! \return Array of the x-values
366const QVector<double> &QwtPointArrayData::xData() const
367{
368 return d_x;
369}
370
371//! \return Array of the y-values
372const QVector<double> &QwtPointArrayData::yData() const
373{
374 return d_y;
375}
376
377/*!
378 Constructor
379
380 \param x Array of x values
381 \param y Array of y values
382 \param size Size of the x and y arrays
383
384 \warning The programmer must assure that the memory blocks referenced
385 by the pointers remain valid during the lifetime of the
386 QwtPlotCPointer object.
387
388 \sa QwtPlotCurve::setData(), QwtPlotCurve::setRawSamples()
389*/
390QwtCPointerData::QwtCPointerData(
391 const double *x, const double *y, size_t size ):
392 d_x( x ),
393 d_y( y ),
394 d_size( size )
395{
396}
397
398/*!
399 \brief Calculate the bounding rect
400
401 The bounding rectangle is calculated once by iterating over all
402 points and is stored for all following requests.
403
404 \return Bounding rectangle
405*/
406QRectF QwtCPointerData::boundingRect() const
407{
408 if ( d_boundingRect.width() < 0 )
409 d_boundingRect = qwtBoundingRect( *this );
410
411 return d_boundingRect;
412}
413
414//! \return Size of the data set
415size_t QwtCPointerData::size() const
416{
417 return d_size;
418}
419
420/*!
421 Return the sample at position i
422
423 \param i Index
424 \return Sample at position i
425*/
426QPointF QwtCPointerData::sample( size_t i ) const
427{
428 return QPointF( d_x[int( i )], d_y[int( i )] );
429}
430
431//! \return Array of the x-values
432const double *QwtCPointerData::xData() const
433{
434 return d_x;
435}
436
437//! \return Array of the y-values
438const double *QwtCPointerData::yData() const
439{
440 return d_y;
441}
442
443/*!
444 Constructor
445
446 \param size Number of points
447 \param interval Bounding interval for the points
448
449 \sa setInterval(), setSize()
450*/
451QwtSyntheticPointData::QwtSyntheticPointData(
452 size_t size, const QwtInterval &interval ):
453 d_size( size ),
454 d_interval( interval )
455{
456}
457
458/*!
459 Change the number of points
460
461 \param size Number of points
462 \sa size(), setInterval()
463*/
464void QwtSyntheticPointData::setSize( size_t size )
465{
466 d_size = size;
467}
468
469/*!
470 \return Number of points
471 \sa setSize(), interval()
472*/
473size_t QwtSyntheticPointData::size() const
474{
475 return d_size;
476}
477
478/*!
479 Set the bounding interval
480
481 \param interval Interval
482 \sa interval(), setSize()
483*/
484void QwtSyntheticPointData::setInterval( const QwtInterval &interval )
485{
486 d_interval = interval.normalized();
487}
488
489/*!
490 \return Bounding interval
491 \sa setInterval(), size()
492*/
493QwtInterval QwtSyntheticPointData::interval() const
494{
495 return d_interval;
496}
497
498/*!
499 Set a the "rect of interest"
500
501 QwtPlotSeriesItem defines the current area of the plot canvas
502 as "rect of interest" ( QwtPlotSeriesItem::updateScaleDiv() ).
503
504 If interval().isValid() == false the x values are calculated
505 in the interval rect.left() -> rect.right().
506
507 \sa rectOfInterest()
508*/
509void QwtSyntheticPointData::setRectOfInterest( const QRectF &rect )
510{
511 d_rectOfInterest = rect;
512 d_intervalOfInterest = QwtInterval(
513 rect.left(), rect.right() ).normalized();
514}
515
516/*!
517 \return "rect of interest"
518 \sa setRectOfInterest()
519*/
520QRectF QwtSyntheticPointData::rectOfInterest() const
521{
522 return d_rectOfInterest;
523}
524
525/*!
526 \brief Calculate the bounding rect
527
528 This implementation iterates over all points, what could often
529 be implemented much faster using the characteristics of the series.
530 When there are many points it is recommended to overload and
531 reimplement this method using the characteristics of the series
532 ( if possible ).
533
534 \return Bounding rectangle
535*/
536QRectF QwtSyntheticPointData::boundingRect() const
537{
538 if ( d_size == 0 ||
539 !( d_interval.isValid() || d_intervalOfInterest.isValid() ) )
540 {
541 return QRectF(1.0, 1.0, -2.0, -2.0); // something invalid
542 }
543
544 return qwtBoundingRect( *this );
545}
546
547/*!
548 Calculate the point from an index
549
550 \param index Index
551 \return QPointF(x(index), y(x(index)));
552
553 \warning For invalid indices ( index < 0 || index >= size() )
554 (0, 0) is returned.
555*/
556QPointF QwtSyntheticPointData::sample( size_t index ) const
557{
558 if ( index >= d_size )
559 return QPointF( 0, 0 );
560
561 const double xValue = x( index );
562 const double yValue = y( xValue );
563
564 return QPointF( xValue, yValue );
565}
566
567/*!
568 Calculate a x-value from an index
569
570 x values are calculated by deviding an interval into
571 equidistant steps. If !interval().isValid() the
572 interval is calculated from the "rect of interest".
573
574 \sa interval(), rectOfInterest(), y()
575*/
576double QwtSyntheticPointData::x( uint index ) const
577{
578 const QwtInterval &interval = d_interval.isValid() ?
579 d_interval : d_intervalOfInterest;
580
581 if ( !interval.isValid() || d_size == 0 || index >= d_size )
582 return 0.0;
583
584 const double dx = interval.width() / d_size;
585 return interval.minValue() + index * dx;
586}
Note: See TracBrowser for help on using the repository browser.