Changeset 8127 in ntrip for trunk/BNC/qwt/qwt_series_data.h


Ignore:
Timestamp:
May 10, 2017, 3:20:54 PM (7 years ago)
Author:
stoecker
Message:

update qwt and qwtpolar, many QT5 fixes (unfinished)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/BNC/qwt/qwt_series_data.h

    r4271 r8127  
    1212
    1313#include "qwt_global.h"
    14 #include "qwt_interval.h"
     14#include "qwt_samples.h"
    1515#include "qwt_point_3d.h"
    1616#include "qwt_point_polar.h"
     
    1818#include <qrect.h>
    1919
    20 //! \brief A sample of the types (x1-x2, y) or (x, y1-y2)
    21 class QWT_EXPORT QwtIntervalSample
    22 {
    23 public:
    24     QwtIntervalSample();
    25     QwtIntervalSample( double, const QwtInterval & );
    26     QwtIntervalSample( double value, double min, double max );
    27 
    28     bool operator==( const QwtIntervalSample & ) const;
    29     bool operator!=( const QwtIntervalSample & ) const;
    30 
    31     //! Value
    32     double value;
    33 
    34     //! Interval
    35     QwtInterval interval;
    36 };
    37 
    38 /*!
    39   Constructor
    40   The value is set to 0.0, the interval is invalid
    41 */
    42 inline QwtIntervalSample::QwtIntervalSample():
    43     value( 0.0 )
    44 {
    45 }
    46 
    47 //! Constructor
    48 inline QwtIntervalSample::QwtIntervalSample(
    49         double v, const QwtInterval &intv ):
    50     value( v ),
    51     interval( intv )
    52 {
    53 }
    54 
    55 //! Constructor
    56 inline QwtIntervalSample::QwtIntervalSample(
    57         double v, double min, double max ):
    58     value( v ),
    59     interval( min, max )
    60 {
    61 }
    62 
    63 //! Compare operator
    64 inline bool QwtIntervalSample::operator==(
    65     const QwtIntervalSample &other ) const
    66 {
    67     return value == other.value && interval == other.interval;
    68 }
    69 
    70 //! Compare operator
    71 inline bool QwtIntervalSample::operator!=(
    72     const QwtIntervalSample &other ) const
    73 {
    74     return !( *this == other );
    75 }
    76 
    77 //! \brief A sample of the types (x1...xn, y) or (x, y1..yn)
    78 class QWT_EXPORT QwtSetSample
    79 {
    80 public:
    81     QwtSetSample();
    82     bool operator==( const QwtSetSample &other ) const;
    83     bool operator!=( const QwtSetSample &other ) const;
    84 
    85     //! value
    86     double value;
    87 
    88     //! Vector of values associated to value
    89     QVector<double> set;
    90 };
    91 
    92 /*!
    93   Constructor
    94   The value is set to 0.0
    95 */
    96 inline QwtSetSample::QwtSetSample():
    97     value( 0.0 )
    98 {
    99 }
    100 
    101 //! Compare operator
    102 inline bool QwtSetSample::operator==( const QwtSetSample &other ) const
    103 {
    104     return value == other.value && set == other.set;
    105 }
    106 
    107 //! Compare operator
    108 inline bool QwtSetSample::operator!=( const QwtSetSample &other ) const
    109 {
    110     return !( *this == other );
    111 }
    112 
    11320/*!
    11421   \brief Abstract interface for iterating over samples
     
    11825   needs to be displayed, without having to copy it, it is recommended
    11926   to implement an individual data access.
     27
     28   A subclass of QwtSeriesData<QPointF> must implement:
     29
     30   - size()\n
     31     Should return number of data points.
     32
     33   - sample()\n
     34     Should return values x and y values of the sample at specific position
     35     as QPointF object.
     36
     37   - boundingRect()\n
     38     Should return the bounding rectangle of the data series.
     39     It is used for autoscaling and might help certain algorithms for displaying
     40     the data. You can use qwtBoundingRect() for an implementation
     41     but often it is possible to implement a more efficient algorithm
     42     depending on the characteristics of the series.
     43     The member d_boundingRect is intended for caching the calculated rectangle.
     44   
    12045*/
    12146template <typename T>
     
    12348{
    12449public:
     50    //! Constructor
    12551    QwtSeriesData();
     52
     53    //! Destructor
    12654    virtual ~QwtSeriesData();
    12755
     
    14472       qwtBoundingRect(...) offers slow implementations iterating
    14573       over the samples. For large sets it is recommended to implement
    146        something faster f.e. by caching the bounding rect.
     74       something faster f.e. by caching the bounding rectangle.
     75
     76       \return Bounding rectangle
    14777     */
    14878    virtual QRectF boundingRect() const = 0;
    14979
    150     virtual void setRectOfInterest( const QRectF & );
     80    /*!
     81       Set a the "rect of interest"
     82
     83       QwtPlotSeriesItem defines the current area of the plot canvas
     84       as "rectangle of interest" ( QwtPlotSeriesItem::updateScaleDiv() ).
     85       It can be used to implement different levels of details.
     86
     87       The default implementation does nothing.
     88   
     89       \param rect Rectangle of interest
     90    */
     91    virtual void setRectOfInterest( const QRectF &rect );
    15192
    15293protected:
     
    15899};
    159100
    160 //! Constructor
    161101template <typename T>
    162102QwtSeriesData<T>::QwtSeriesData():
     
    165105}
    166106
    167 //! Destructor
    168107template <typename T>
    169108QwtSeriesData<T>::~QwtSeriesData()
     
    171110}
    172111
    173 /*!
    174    Set a the "rect of interest"
    175 
    176    QwtPlotSeriesItem defines the current area of the plot canvas
    177    as "rect of interest" ( QwtPlotSeriesItem::updateScaleDiv() ).
    178    It can be used to implement different levels of details.
    179 
    180    The default implementation does nothing.
    181 */
    182112template <typename T>
    183113void QwtSeriesData<T>::setRectOfInterest( const QRectF & )
     
    195125{
    196126public:
     127    //! Constructor
    197128    QwtArraySeriesData();
    198     QwtArraySeriesData( const QVector<T> & );
    199 
    200     void setSamples( const QVector<T> & );
     129
     130    /*!
     131       Constructor
     132       \param samples Array of samples
     133    */
     134    QwtArraySeriesData( const QVector<T> &samples );
     135
     136    /*!
     137      Assign an array of samples
     138      \param samples Array of samples
     139    */
     140    void setSamples( const QVector<T> &samples );
     141
     142    //! \return Array of samples
    201143    const QVector<T> samples() const;
    202144
     145    //! \return Number of samples
    203146    virtual size_t size() const;
    204     virtual T sample( size_t ) const;
     147
     148    /*!
     149      \return Sample at a specific position
     150
     151      \param index Index
     152      \return Sample at position index
     153    */
     154    virtual T sample( size_t index ) const;
    205155
    206156protected:
     
    209159};
    210160
    211 //! Constructor
    212161template <typename T>
    213162QwtArraySeriesData<T>::QwtArraySeriesData()
     
    215164}
    216165
    217 /*!
    218    Constructor
    219    \param samples Array of samples
    220 */
    221166template <typename T>
    222167QwtArraySeriesData<T>::QwtArraySeriesData( const QVector<T> &samples ):
     
    225170}
    226171
    227 /*!
    228   Assign an array of samples
    229   \param samples Array of samples
    230 */
    231172template <typename T>
    232173void QwtArraySeriesData<T>::setSamples( const QVector<T> &samples )
     
    236177}
    237178
    238 //! \return Array of samples
    239179template <typename T>
    240180const QVector<T> QwtArraySeriesData<T>::samples() const
     
    243183}
    244184
    245 //! \return Number of samples
    246185template <typename T>
    247186size_t QwtArraySeriesData<T>::size() const
     
    250189}
    251190
    252 /*!
    253   Return a sample
    254   \param i Index
    255   \return Sample at position i
    256 */
    257191template <typename T>
    258192T QwtArraySeriesData<T>::sample( size_t i ) const
    259193{
    260     return d_samples[i];
     194    return d_samples[ static_cast<int>( i ) ];
    261195}
    262196
     
    301235
    302236/*!
    303   \brief Interface for iterating over two QVector<double> objects.
     237    Interface for iterating over an array of OHLC samples
    304238*/
    305 class QWT_EXPORT QwtPointArrayData: public QwtSeriesData<QPointF>
    306 {
    307 public:
    308     QwtPointArrayData( const QVector<double> &x, const QVector<double> &y );
    309     QwtPointArrayData( const double *x, const double *y, size_t size );
    310 
    311     virtual QRectF boundingRect() const;
    312 
    313     virtual size_t size() const;
    314     virtual QPointF sample( size_t i ) const;
    315 
    316     const QVector<double> &xData() const;
    317     const QVector<double> &yData() const;
    318 
    319 private:
    320     QVector<double> d_x;
    321     QVector<double> d_y;
    322 };
     239class QWT_EXPORT QwtTradingChartData: public QwtArraySeriesData<QwtOHLCSample>
     240{
     241public:
     242    QwtTradingChartData(
     243        const QVector<QwtOHLCSample> & = QVector<QwtOHLCSample>() );
     244
     245    virtual QRectF boundingRect() const;
     246};
     247
     248QWT_EXPORT QRectF qwtBoundingRect(
     249    const QwtSeriesData<QPointF> &, int from = 0, int to = -1 );
     250
     251QWT_EXPORT QRectF qwtBoundingRect(
     252    const QwtSeriesData<QwtPoint3D> &, int from = 0, int to = -1 );
     253
     254QWT_EXPORT QRectF qwtBoundingRect(
     255    const QwtSeriesData<QwtPointPolar> &, int from = 0, int to = -1 );
     256
     257QWT_EXPORT QRectF qwtBoundingRect(
     258    const QwtSeriesData<QwtIntervalSample> &, int from = 0, int to = -1 );
     259
     260QWT_EXPORT QRectF qwtBoundingRect(
     261    const QwtSeriesData<QwtSetSample> &, int from = 0, int to = -1 );
     262
     263QWT_EXPORT QRectF qwtBoundingRect(
     264    const QwtSeriesData<QwtOHLCSample> &, int from = 0, int to = -1 );
    323265
    324266/*!
    325   \brief Data class containing two pointers to memory blocks of doubles.
    326  */
    327 class QWT_EXPORT QwtCPointerData: public QwtSeriesData<QPointF>
    328 {
    329 public:
    330     QwtCPointerData( const double *x, const double *y, size_t size );
    331 
    332     virtual QRectF boundingRect() const;
    333     virtual size_t size() const;
    334     virtual QPointF sample( size_t i ) const;
    335 
    336     const double *xData() const;
    337     const double *yData() const;
    338 
    339 private:
    340     const double *d_x;
    341     const double *d_y;
    342     size_t d_size;
    343 };
    344 
    345 /*!
    346   \brief Synthetic point data
    347 
    348   QwtSyntheticPointData provides a fixed number of points for an interval.
    349   The points are calculated in equidistant steps in x-direction.
    350 
    351   If the interval is invalid, the points are calculated for
    352   the "rect of interest", what normally is the displayed area on the
    353   plot canvas. In this mode you get different levels of detail, when
    354   zooming in/out.
     267    Binary search for a sorted series of samples
     268
     269    qwtUpperSampleIndex returns the index of sample that is the upper bound
     270    of value. Is the the value smaller than the smallest value the return
     271    value will be 0. Is the value greater or equal than the largest
     272    value the return value will be -1.
    355273
    356274  \par Example
    357 
    358   The following example shows how to implement a sinus curve.
     275    The following example shows finds a point of curve from an x
     276    coordinate
    359277
    360278  \verbatim
    361 #include <cmath>
    362279#include <qwt_series_data.h>
    363280#include <qwt_plot_curve.h>
    364 #include <qwt_plot.h>
    365 #include <qapplication.h>
    366 
    367 class SinusData: public QwtSyntheticPointData
    368 {
    369 public:
    370     SinusData():
    371         QwtSyntheticPointData(100)
     281
     282struct compareX
     283{
     284    inline bool operator()( const double x, const QPointF &pos ) const
    372285    {
     286        return ( x < pos.x() );
    373287    }
    374     virtual double y(double x) const
     288};
     289
     290QLineF curveLineAt( const QwtPlotCurve *curve, double x )
     291{
     292    int index = qwtUpperSampleIndex<QPointF>(
     293        *curve->data(), x, compareX() );
     294           
     295    if ( index == -1 &&
     296        x == curve->sample( curve->dataSize() - 1 ).x() )
     297    {   
     298        // the last sample is excluded from qwtUpperSampleIndex
     299        index = curve->dataSize() - 1;
     300    }
     301
     302    QLineF line; // invalid
     303    if ( index > 0 )
    375304    {
    376         return qSin(x);
     305        line.setP1( curve->sample( index - 1 ) );
     306        line.setP2( curve->sample( index ) );
    377307    }
    378 };
    379 
    380 int main(int argc, char **argv)
    381 {
    382     QApplication a(argc, argv);
    383 
    384     QwtPlot plot;
    385     plot.setAxisScale(QwtPlot::xBottom, 0.0, 10.0);
    386     plot.setAxisScale(QwtPlot::yLeft, -1.0, 1.0);
    387 
    388     QwtPlotCurve *curve = new QwtPlotCurve("y = sin(x)");
    389     curve->setData(SinusData());
    390     curve->attach(&plot);
    391 
    392     plot.show();
    393     return a.exec();
    394 }
    395    \endverbatim
    396 */
    397 class QWT_EXPORT QwtSyntheticPointData: public QwtSeriesData<QPointF>
    398 {
    399 public:
    400     QwtSyntheticPointData( size_t size,
    401         const QwtInterval & = QwtInterval() );
    402 
    403     void setSize( size_t size );
    404     size_t size() const;
    405 
    406     void setInterval( const QwtInterval& );
    407     QwtInterval interval() const;
    408 
    409     virtual QRectF boundingRect() const;
    410     virtual QPointF sample( size_t i ) const;
    411 
    412     /*!
    413        Calculate a y value for a x value
    414 
    415        \param x x value
    416        \return Corresponding y value
    417      */
    418     virtual double y( double x ) const = 0;
    419     virtual double x( uint index ) const;
    420 
    421     virtual void setRectOfInterest( const QRectF & );
    422     QRectF rectOfInterest() const;
    423 
    424 private:
    425     size_t d_size;
    426     QwtInterval d_interval;
    427     QRectF d_rectOfInterest;
    428     QwtInterval d_intervalOfInterest;
    429 };
    430 
    431 QWT_EXPORT QRectF qwtBoundingRect(
    432     const QwtSeriesData<QPointF> &, int from = 0, int to = -1 );
    433 QWT_EXPORT QRectF qwtBoundingRect(
    434     const QwtSeriesData<QwtPoint3D> &, int from = 0, int to = -1 );
    435 QWT_EXPORT QRectF qwtBoundingRect(
    436     const QwtSeriesData<QwtPointPolar> &, int from = 0, int to = -1 );
    437 QWT_EXPORT QRectF qwtBoundingRect(
    438     const QwtSeriesData<QwtIntervalSample> &, int from = 0, int to = -1 );
    439 QWT_EXPORT QRectF qwtBoundingRect(
    440     const QwtSeriesData<QwtSetSample> &, int from = 0, int to = -1 );
    441 
    442 #endif
     308
     309    return line;
     310}
     311
     312\endverbatim
     313
     314
     315    \param series Series of samples
     316    \param value Value
     317    \param lessThan Compare operation
     318
     319    \note The samples must be sorted according to the order specified
     320          by the lessThan object
     321
     322of the range [begin, end) and returns the position of the one-past-the-last occurrence of value. If no such item is found, returns the position where the item should be inserted.
     323 */
     324template <typename T, typename LessThan>
     325inline int qwtUpperSampleIndex( const QwtSeriesData<T> &series,
     326    double value, LessThan lessThan  )
     327{
     328    const int indexMax = series.size() - 1;
     329
     330    if ( indexMax < 0 || !lessThan( value, series.sample( indexMax ) )  )
     331        return -1;
     332
     333    int indexMin = 0;
     334    int n = indexMax;
     335
     336    while ( n > 0 )
     337    {
     338        const int half = n >> 1;
     339        const int indexMid = indexMin + half;
     340
     341        if ( lessThan( value, series.sample( indexMid ) ) )
     342        {
     343            n = half;
     344        }
     345        else
     346        {
     347            indexMin = indexMid + 1;
     348            n -= half + 1;
     349        }
     350    }
     351
     352    return indexMin;
     353}
     354
     355#endif
Note: See TracChangeset for help on using the changeset viewer.