qwt_series_data.h 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  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. #ifndef QWT_SERIES_DATA_H
  10. #define QWT_SERIES_DATA_H 1
  11. #include "qwt_global.h"
  12. #include "qwt_samples.h"
  13. #include "qwt_point_3d.h"
  14. #include "qwt_point_polar.h"
  15. #include <qvector.h>
  16. #include <qrect.h>
  17. /*!
  18. \brief Abstract interface for iterating over samples
  19. Qwt offers several implementations of the QwtSeriesData API,
  20. but in situations, where data of an application specific format
  21. needs to be displayed, without having to copy it, it is recommended
  22. to implement an individual data access.
  23. A subclass of QwtSeriesData<QPointF> must implement:
  24. - size()\n
  25. Should return number of data points.
  26. - sample()\n
  27. Should return values x and y values of the sample at specific position
  28. as QPointF object.
  29. - boundingRect()\n
  30. Should return the bounding rectangle of the data series.
  31. It is used for autoscaling and might help certain algorithms for displaying
  32. the data. You can use qwtBoundingRect() for an implementation
  33. but often it is possible to implement a more efficient algorithm
  34. depending on the characteristics of the series.
  35. The member d_boundingRect is intended for caching the calculated rectangle.
  36. */
  37. template <typename T>
  38. class QwtSeriesData
  39. {
  40. public:
  41. //! Constructor
  42. QwtSeriesData();
  43. //! Destructor
  44. virtual ~QwtSeriesData();
  45. #ifndef QWT_PYTHON_WRAPPER
  46. //! \return Number of samples
  47. virtual size_t size() const = 0;
  48. /*!
  49. Return a sample
  50. \param i Index
  51. \return Sample at position i
  52. */
  53. virtual T sample( size_t i ) const = 0;
  54. /*!
  55. Calculate the bounding rect of all samples
  56. The bounding rect is necessary for autoscaling and can be used
  57. for a couple of painting optimizations.
  58. qwtBoundingRect(...) offers slow implementations iterating
  59. over the samples. For large sets it is recommended to implement
  60. something faster f.e. by caching the bounding rectangle.
  61. \return Bounding rectangle
  62. */
  63. virtual QRectF boundingRect() const = 0;
  64. #else
  65. // Needed for generating the python bindings, but not for using them !
  66. virtual size_t size() const { return 0; }
  67. virtual T sample( size_t i ) const { return T(); }
  68. virtual QRectF boundingRect() const { return d_boundingRect; }
  69. #endif
  70. /*!
  71. Set a the "rect of interest"
  72. QwtPlotSeriesItem defines the current area of the plot canvas
  73. as "rectangle of interest" ( QwtPlotSeriesItem::updateScaleDiv() ).
  74. It can be used to implement different levels of details.
  75. The default implementation does nothing.
  76. \param rect Rectangle of interest
  77. */
  78. virtual void setRectOfInterest( const QRectF &rect );
  79. protected:
  80. //! Can be used to cache a calculated bounding rectangle
  81. mutable QRectF d_boundingRect;
  82. private:
  83. QwtSeriesData<T> &operator=( const QwtSeriesData<T> & );
  84. };
  85. template <typename T>
  86. QwtSeriesData<T>::QwtSeriesData():
  87. d_boundingRect( 0.0, 0.0, -1.0, -1.0 )
  88. {
  89. }
  90. template <typename T>
  91. QwtSeriesData<T>::~QwtSeriesData()
  92. {
  93. }
  94. template <typename T>
  95. void QwtSeriesData<T>::setRectOfInterest( const QRectF & )
  96. {
  97. }
  98. /*!
  99. \brief Template class for data, that is organized as QVector
  100. QVector uses implicit data sharing and can be
  101. passed around as argument efficiently.
  102. */
  103. template <typename T>
  104. class QwtArraySeriesData: public QwtSeriesData<T>
  105. {
  106. public:
  107. //! Constructor
  108. QwtArraySeriesData();
  109. /*!
  110. Constructor
  111. \param samples Array of samples
  112. */
  113. QwtArraySeriesData( const QVector<T> &samples );
  114. /*!
  115. Assign an array of samples
  116. \param samples Array of samples
  117. */
  118. void setSamples( const QVector<T> &samples );
  119. //! \return Array of samples
  120. const QVector<T> samples() const;
  121. //! \return Number of samples
  122. virtual size_t size() const;
  123. /*!
  124. \return Sample at a specific position
  125. \param index Index
  126. \return Sample at position index
  127. */
  128. virtual T sample( size_t index ) const;
  129. protected:
  130. //! Vector of samples
  131. QVector<T> d_samples;
  132. };
  133. template <typename T>
  134. QwtArraySeriesData<T>::QwtArraySeriesData()
  135. {
  136. }
  137. template <typename T>
  138. QwtArraySeriesData<T>::QwtArraySeriesData( const QVector<T> &samples ):
  139. d_samples( samples )
  140. {
  141. }
  142. template <typename T>
  143. void QwtArraySeriesData<T>::setSamples( const QVector<T> &samples )
  144. {
  145. QwtSeriesData<T>::d_boundingRect = QRectF( 0.0, 0.0, -1.0, -1.0 );
  146. d_samples = samples;
  147. }
  148. template <typename T>
  149. const QVector<T> QwtArraySeriesData<T>::samples() const
  150. {
  151. return d_samples;
  152. }
  153. template <typename T>
  154. size_t QwtArraySeriesData<T>::size() const
  155. {
  156. return d_samples.size();
  157. }
  158. template <typename T>
  159. T QwtArraySeriesData<T>::sample( size_t i ) const
  160. {
  161. return d_samples[ static_cast<int>( i ) ];
  162. }
  163. //! Interface for iterating over an array of points
  164. class QWT_EXPORT QwtPointSeriesData: public QwtArraySeriesData<QPointF>
  165. {
  166. public:
  167. QwtPointSeriesData(
  168. const QVector<QPointF> & = QVector<QPointF>() );
  169. virtual QRectF boundingRect() const;
  170. };
  171. //! Interface for iterating over an array of 3D points
  172. class QWT_EXPORT QwtPoint3DSeriesData: public QwtArraySeriesData<QwtPoint3D>
  173. {
  174. public:
  175. QwtPoint3DSeriesData(
  176. const QVector<QwtPoint3D> & = QVector<QwtPoint3D>() );
  177. virtual QRectF boundingRect() const;
  178. };
  179. //! Interface for iterating over an array of intervals
  180. class QWT_EXPORT QwtIntervalSeriesData: public QwtArraySeriesData<QwtIntervalSample>
  181. {
  182. public:
  183. QwtIntervalSeriesData(
  184. const QVector<QwtIntervalSample> & = QVector<QwtIntervalSample>() );
  185. virtual QRectF boundingRect() const;
  186. };
  187. //! Interface for iterating over an array of samples
  188. class QWT_EXPORT QwtSetSeriesData: public QwtArraySeriesData<QwtSetSample>
  189. {
  190. public:
  191. QwtSetSeriesData(
  192. const QVector<QwtSetSample> & = QVector<QwtSetSample>() );
  193. virtual QRectF boundingRect() const;
  194. };
  195. /*!
  196. Interface for iterating over an array of OHLC samples
  197. */
  198. class QWT_EXPORT QwtTradingChartData: public QwtArraySeriesData<QwtOHLCSample>
  199. {
  200. public:
  201. QwtTradingChartData(
  202. const QVector<QwtOHLCSample> & = QVector<QwtOHLCSample>() );
  203. virtual QRectF boundingRect() const;
  204. };
  205. QWT_EXPORT QRectF qwtBoundingRect(
  206. const QwtSeriesData<QPointF> &, int from = 0, int to = -1 );
  207. QWT_EXPORT QRectF qwtBoundingRect(
  208. const QwtSeriesData<QwtPoint3D> &, int from = 0, int to = -1 );
  209. QWT_EXPORT QRectF qwtBoundingRect(
  210. const QwtSeriesData<QwtPointPolar> &, int from = 0, int to = -1 );
  211. QWT_EXPORT QRectF qwtBoundingRect(
  212. const QwtSeriesData<QwtIntervalSample> &, int from = 0, int to = -1 );
  213. QWT_EXPORT QRectF qwtBoundingRect(
  214. const QwtSeriesData<QwtSetSample> &, int from = 0, int to = -1 );
  215. QWT_EXPORT QRectF qwtBoundingRect(
  216. const QwtSeriesData<QwtOHLCSample> &, int from = 0, int to = -1 );
  217. /*!
  218. Binary search for a sorted series of samples
  219. qwtUpperSampleIndex returns the index of sample that is the upper bound
  220. of value. Is the the value smaller than the smallest value the return
  221. value will be 0. Is the value greater or equal than the largest
  222. value the return value will be -1.
  223. \par Example
  224. The following example shows finds a point of curve from an x
  225. coordinate
  226. \code
  227. #include <qwt_series_data.h>
  228. #include <qwt_plot_curve.h>
  229. struct compareX
  230. {
  231. inline bool operator()( const double x, const QPointF &pos ) const
  232. {
  233. return ( x < pos.x() );
  234. }
  235. };
  236. QLineF curveLineAt( const QwtPlotCurve *curve, double x )
  237. {
  238. int index = qwtUpperSampleIndex<QPointF>(
  239. *curve->data(), x, compareX() );
  240. if ( index == -1 &&
  241. x == curve->sample( curve->dataSize() - 1 ).x() )
  242. {
  243. // the last sample is excluded from qwtUpperSampleIndex
  244. index = curve->dataSize() - 1;
  245. }
  246. QLineF line; // invalid
  247. if ( index > 0 )
  248. {
  249. line.setP1( curve->sample( index - 1 ) );
  250. line.setP2( curve->sample( index ) );
  251. }
  252. return line;
  253. }
  254. \endcode
  255. \endpar
  256. \param series Series of samples
  257. \param value Value
  258. \param lessThan Compare operation
  259. \note The samples must be sorted according to the order specified
  260. by the lessThan object
  261. */
  262. template <typename T, typename LessThan>
  263. inline int qwtUpperSampleIndex( const QwtSeriesData<T> &series,
  264. double value, LessThan lessThan )
  265. {
  266. const int indexMax = series.size() - 1;
  267. if ( indexMax < 0 || !lessThan( value, series.sample( indexMax ) ) )
  268. return -1;
  269. int indexMin = 0;
  270. int n = indexMax;
  271. while ( n > 0 )
  272. {
  273. const int half = n >> 1;
  274. const int indexMid = indexMin + half;
  275. if ( lessThan( value, series.sample( indexMid ) ) )
  276. {
  277. n = half;
  278. }
  279. else
  280. {
  281. indexMin = indexMid + 1;
  282. n -= half + 1;
  283. }
  284. }
  285. return indexMin;
  286. }
  287. #endif