qwt_plot_grid.cpp 9.62 KB
Newer Older
pixhawk's avatar
pixhawk committed
1
2
3
4
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
 * Qwt Widget Library
 * Copyright (C) 1997   Josef Wilgen
 * Copyright (C) 2002   Uwe Rathmann
5
 *
pixhawk's avatar
pixhawk committed
6
7
8
9
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the Qwt License, Version 1.0
 *****************************************************************************/

Bryant's avatar
Bryant committed
10
#include "qwt_plot_grid.h"
pixhawk's avatar
pixhawk committed
11
12
13
14
#include "qwt_painter.h"
#include "qwt_text.h"
#include "qwt_scale_map.h"
#include "qwt_scale_div.h"
Bryant's avatar
Bryant committed
15
16
17
#include "qwt_math.h"
#include <qpainter.h>
#include <qpen.h>
pixhawk's avatar
pixhawk committed
18
19
20
21
22

class QwtPlotGrid::PrivateData
{
public:
    PrivateData():
Bryant's avatar
Bryant committed
23
24
25
26
27
        xEnabled( true ),
        yEnabled( true ),
        xMinEnabled( false ),
        yMinEnabled( false )
    {
pixhawk's avatar
pixhawk committed
28
29
30
31
32
33
34
35
36
37
    }

    bool xEnabled;
    bool yEnabled;
    bool xMinEnabled;
    bool yMinEnabled;

    QwtScaleDiv xScaleDiv;
    QwtScaleDiv yScaleDiv;

Bryant's avatar
Bryant committed
38
39
    QPen majorPen;
    QPen minorPen;
pixhawk's avatar
pixhawk committed
40
41
42
43
};

//! Enables major grid, disables minor grid
QwtPlotGrid::QwtPlotGrid():
Bryant's avatar
Bryant committed
44
    QwtPlotItem( QwtText( "Grid" ) )
pixhawk's avatar
pixhawk committed
45
46
{
    d_data = new PrivateData;
Bryant's avatar
Bryant committed
47
48
49

    setItemInterest( QwtPlotItem::ScaleInterest, true );
    setZ( 10.0 );
pixhawk's avatar
pixhawk committed
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
}

//! Destructor
QwtPlotGrid::~QwtPlotGrid()
{
    delete d_data;
}

//! \return QwtPlotItem::Rtti_PlotGrid
int QwtPlotGrid::rtti() const
{
    return QwtPlotItem::Rtti_PlotGrid;
}

/*!
Bryant's avatar
Bryant committed
65
66
  \brief Enable or disable vertical grid lines
  \param on Enable (true) or disable
pixhawk's avatar
pixhawk committed
67

Bryant's avatar
Bryant committed
68
  \sa Minor grid lines can be enabled or disabled with
pixhawk's avatar
pixhawk committed
69
70
      enableXMin()
*/
Bryant's avatar
Bryant committed
71
void QwtPlotGrid::enableX( bool on )
pixhawk's avatar
pixhawk committed
72
{
Bryant's avatar
Bryant committed
73
74
75
76
77
    if ( d_data->xEnabled != on )
    {
        d_data->xEnabled = on;

        legendChanged();
pixhawk's avatar
pixhawk committed
78
79
80
81
82
        itemChanged();
    }
}

/*!
Bryant's avatar
Bryant committed
83
84
85
  \brief Enable or disable horizontal grid lines
  \param on Enable (true) or disable
  \sa Minor grid lines can be enabled or disabled with enableYMin()
pixhawk's avatar
pixhawk committed
86
*/
Bryant's avatar
Bryant committed
87
void QwtPlotGrid::enableY( bool on )
pixhawk's avatar
pixhawk committed
88
{
Bryant's avatar
Bryant committed
89
90
91
92
93
    if ( d_data->yEnabled != on )
    {
        d_data->yEnabled = on;

        legendChanged();
pixhawk's avatar
pixhawk committed
94
95
96
97
98
        itemChanged();
    }
}

/*!
Bryant's avatar
Bryant committed
99
100
  \brief Enable or disable  minor vertical grid lines.
  \param on Enable (true) or disable
pixhawk's avatar
pixhawk committed
101
102
  \sa enableX()
*/
Bryant's avatar
Bryant committed
103
void QwtPlotGrid::enableXMin( bool on )
pixhawk's avatar
pixhawk committed
104
{
Bryant's avatar
Bryant committed
105
106
107
108
109
    if ( d_data->xMinEnabled != on )
    {
        d_data->xMinEnabled = on;

        legendChanged();
pixhawk's avatar
pixhawk committed
110
111
112
113
114
        itemChanged();
    }
}

/*!
Bryant's avatar
Bryant committed
115
116
  \brief Enable or disable minor horizontal grid lines
  \param on Enable (true) or disable
pixhawk's avatar
pixhawk committed
117
118
  \sa enableY()
*/
Bryant's avatar
Bryant committed
119
void QwtPlotGrid::enableYMin( bool on )
pixhawk's avatar
pixhawk committed
120
{
Bryant's avatar
Bryant committed
121
122
123
124
125
    if ( d_data->yMinEnabled != on )
    {
        d_data->yMinEnabled = on;

        legendChanged();
pixhawk's avatar
pixhawk committed
126
127
128
129
130
        itemChanged();
    }
}

/*!
Bryant's avatar
Bryant committed
131
132
  Assign an x axis scale division

pixhawk's avatar
pixhawk committed
133
134
  \param scaleDiv Scale division
*/
Bryant's avatar
Bryant committed
135
void QwtPlotGrid::setXDiv( const QwtScaleDiv &scaleDiv )
pixhawk's avatar
pixhawk committed
136
{
Bryant's avatar
Bryant committed
137
138
    if ( d_data->xScaleDiv != scaleDiv )
    {
pixhawk's avatar
pixhawk committed
139
140
141
142
143
144
        d_data->xScaleDiv = scaleDiv;
        itemChanged();
    }
}

/*!
Bryant's avatar
Bryant committed
145
146
147
  Assign a y axis division

  \param scaleDiv Scale division
pixhawk's avatar
pixhawk committed
148
*/
Bryant's avatar
Bryant committed
149
void QwtPlotGrid::setYDiv( const QwtScaleDiv &scaleDiv )
pixhawk's avatar
pixhawk committed
150
{
Bryant's avatar
Bryant committed
151
152
153
    if ( d_data->yScaleDiv != scaleDiv )
    {
        d_data->yScaleDiv = scaleDiv;
pixhawk's avatar
pixhawk committed
154
155
156
157
158
        itemChanged();
    }
}

/*!
Bryant's avatar
Bryant committed
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
  Build and assign a pen for both major and minor grid lines

  In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it
  non cosmetic ( see QPen::isCosmetic() ). This method has been introduced
  to hide this incompatibility.

  \param color Pen color
  \param width Pen width
  \param style Pen style

  \sa pen(), brush()
 */
void QwtPlotGrid::setPen( const QColor &color, qreal width, Qt::PenStyle style )
{
    setPen( QPen( color, width, style ) );
}

/*!
  Assign a pen for both major and minor grid lines

  \param pen Pen
  \sa setMajorPen(), setMinorPen()
pixhawk's avatar
pixhawk committed
181
*/
Bryant's avatar
Bryant committed
182
void QwtPlotGrid::setPen( const QPen &pen )
pixhawk's avatar
pixhawk committed
183
{
Bryant's avatar
Bryant committed
184
185
186
187
188
189
    if ( d_data->majorPen != pen || d_data->minorPen != pen )
    {
        d_data->majorPen = pen;
        d_data->minorPen = pen;

        legendChanged();
pixhawk's avatar
pixhawk committed
190
191
192
193
194
        itemChanged();
    }
}

/*!
Bryant's avatar
Bryant committed
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
  Build and assign a pen for both major grid lines

  In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it
  non cosmetic ( see QPen::isCosmetic() ). This method has been introduced
  to hide this incompatibility.

  \param color Pen color
  \param width Pen width
  \param style Pen style

  \sa pen(), brush()
 */
void QwtPlotGrid::setMajorPen( const QColor &color, qreal width, Qt::PenStyle style )
{
    setMajorPen( QPen( color, width, style ) );
}

/*!
  Assign a pen for the major grid lines

  \param pen Pen
  \sa majorPen(), setMinorPen(), setPen()
pixhawk's avatar
pixhawk committed
217
*/
Bryant's avatar
Bryant committed
218
void QwtPlotGrid::setMajorPen( const QPen &pen )
pixhawk's avatar
pixhawk committed
219
{
Bryant's avatar
Bryant committed
220
221
222
223
224
    if ( d_data->majorPen != pen )
    {
        d_data->majorPen = pen;

        legendChanged();
pixhawk's avatar
pixhawk committed
225
226
227
228
229
        itemChanged();
    }
}

/*!
Bryant's avatar
Bryant committed
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
  Build and assign a pen for the minor grid lines

  In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it
  non cosmetic ( see QPen::isCosmetic() ). This method has been introduced
  to hide this incompatibility.

  \param color Pen color
  \param width Pen width
  \param style Pen style

  \sa pen(), brush()
 */
void QwtPlotGrid::setMinorPen( const QColor &color, qreal width, Qt::PenStyle style )
{
    setMinorPen( QPen( color, width, style ) );
}

/*!
  Assign a pen for the minor grid lines

  \param pen Pen
  \sa minorPen(), setMajorPen(), setPen()
pixhawk's avatar
pixhawk committed
252
*/
Bryant's avatar
Bryant committed
253
void QwtPlotGrid::setMinorPen( const QPen &pen )
pixhawk's avatar
pixhawk committed
254
{
Bryant's avatar
Bryant committed
255
256
257
258
259
    if ( d_data->minorPen != pen )
    {
        d_data->minorPen = pen;

        legendChanged();
pixhawk's avatar
pixhawk committed
260
261
262
263
264
265
        itemChanged();
    }
}

/*!
  \brief Draw the grid
266
267

  The grid is drawn into the bounding rectangle such that
Bryant's avatar
Bryant committed
268
  grid lines begin and end at the rectangle's borders. The X and Y
pixhawk's avatar
pixhawk committed
269
270
  maps are used to map the scale divisions into the drawing region
  screen.
Bryant's avatar
Bryant committed
271

pixhawk's avatar
pixhawk committed
272
273
  \param painter  Painter
  \param xMap X axis map
274
  \param yMap Y axis
Bryant's avatar
Bryant committed
275
  \param canvasRect Contents rectangle of the plot canvas
pixhawk's avatar
pixhawk committed
276
*/
Bryant's avatar
Bryant committed
277
278
279
void QwtPlotGrid::draw( QPainter *painter,
    const QwtScaleMap &xMap, const QwtScaleMap &yMap,
    const QRectF &canvasRect ) const
pixhawk's avatar
pixhawk committed
280
{
Bryant's avatar
Bryant committed
281
282
283
284
285
286
287
288
289
290
291
292
    //  draw minor grid lines
    QPen minorPen = d_data->minorPen;
    minorPen.setCapStyle( Qt::FlatCap );

    painter->setPen( minorPen );

    if ( d_data->xEnabled && d_data->xMinEnabled )
    {
        drawLines( painter, canvasRect, Qt::Vertical, xMap,
            d_data->xScaleDiv.ticks( QwtScaleDiv::MinorTick ) );
        drawLines( painter, canvasRect, Qt::Vertical, xMap,
            d_data->xScaleDiv.ticks( QwtScaleDiv::MediumTick ) );
pixhawk's avatar
pixhawk committed
293
294
    }

Bryant's avatar
Bryant committed
295
296
297
298
299
300
    if ( d_data->yEnabled && d_data->yMinEnabled )
    {
        drawLines( painter, canvasRect, Qt::Horizontal, yMap,
            d_data->yScaleDiv.ticks( QwtScaleDiv::MinorTick ) );
        drawLines( painter, canvasRect, Qt::Horizontal, yMap,
            d_data->yScaleDiv.ticks( QwtScaleDiv::MediumTick ) );
pixhawk's avatar
pixhawk committed
301
302
    }

Bryant's avatar
Bryant committed
303
304
305
    //  draw major grid lines
    QPen majorPen = d_data->majorPen;
    majorPen.setCapStyle( Qt::FlatCap );
306

Bryant's avatar
Bryant committed
307
308
309
310
311
312
    painter->setPen( majorPen );

    if ( d_data->xEnabled )
    {
        drawLines( painter, canvasRect, Qt::Vertical, xMap,
            d_data->xScaleDiv.ticks( QwtScaleDiv::MajorTick ) );
pixhawk's avatar
pixhawk committed
313
314
    }

Bryant's avatar
Bryant committed
315
316
317
318
    if ( d_data->yEnabled )
    {
        drawLines( painter, canvasRect, Qt::Horizontal, yMap,
            d_data->yScaleDiv.ticks( QwtScaleDiv::MajorTick ) );
pixhawk's avatar
pixhawk committed
319
320
321
    }
}

Bryant's avatar
Bryant committed
322
323
324
void QwtPlotGrid::drawLines( QPainter *painter, const QRectF &canvasRect,
    Qt::Orientation orientation, const QwtScaleMap &scaleMap,
    const QList<double> &values ) const
pixhawk's avatar
pixhawk committed
325
{
Bryant's avatar
Bryant committed
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
    const double x1 = canvasRect.left();
    const double x2 = canvasRect.right() - 1.0;
    const double y1 = canvasRect.top();
    const double y2 = canvasRect.bottom() - 1.0;

    const bool doAlign = QwtPainter::roundingAlignment( painter );

    for ( int i = 0; i < values.count(); i++ )
    {
        double value = scaleMap.transform( values[i] );
        if ( doAlign )
            value = qRound( value );

        if ( orientation == Qt::Horizontal )
        {
            if ( qwtFuzzyGreaterOrEqual( value, y1 ) &&
                qwtFuzzyLessOrEqual( value, y2 ) )
            {
                QwtPainter::drawLine( painter, x1, value, x2, value );
            }
        }
        else
        {
            if ( qwtFuzzyGreaterOrEqual( value, x1 ) &&
                qwtFuzzyLessOrEqual( value, x2 ) )
            {
                QwtPainter::drawLine( painter, value, y1, value, y2 );
            }
pixhawk's avatar
pixhawk committed
354
355
356
357
358
        }
    }
}

/*!
Bryant's avatar
Bryant committed
359
360
  \return the pen for the major grid lines
  \sa setMajorPen(), setMinorPen(), setPen()
pixhawk's avatar
pixhawk committed
361
*/
Bryant's avatar
Bryant committed
362
const QPen &QwtPlotGrid::majorPen() const
363
{
Bryant's avatar
Bryant committed
364
    return d_data->majorPen;
pixhawk's avatar
pixhawk committed
365
366
367
}

/*!
Bryant's avatar
Bryant committed
368
369
  \return the pen for the minor grid lines
  \sa setMinorPen(), setMajorPen(), setPen()
pixhawk's avatar
pixhawk committed
370
*/
Bryant's avatar
Bryant committed
371
const QPen &QwtPlotGrid::minorPen() const
372
{
Bryant's avatar
Bryant committed
373
    return d_data->minorPen;
pixhawk's avatar
pixhawk committed
374
}
375

pixhawk's avatar
pixhawk committed
376
/*!
Bryant's avatar
Bryant committed
377
  \return true if vertical grid lines are enabled
pixhawk's avatar
pixhawk committed
378
379
380
  \sa enableX()
*/
bool QwtPlotGrid::xEnabled() const
381
382
{
    return d_data->xEnabled;
pixhawk's avatar
pixhawk committed
383
384
385
}

/*!
Bryant's avatar
Bryant committed
386
  \return true if minor vertical grid lines are enabled
pixhawk's avatar
pixhawk committed
387
388
  \sa enableXMin()
*/
389
390
391
bool QwtPlotGrid::xMinEnabled() const
{
    return d_data->xMinEnabled;
pixhawk's avatar
pixhawk committed
392
393
394
}

/*!
Bryant's avatar
Bryant committed
395
  \return true if horizontal grid lines are enabled
pixhawk's avatar
pixhawk committed
396
397
  \sa enableY()
*/
398
399
400
bool QwtPlotGrid::yEnabled() const
{
    return d_data->yEnabled;
pixhawk's avatar
pixhawk committed
401
402
403
}

/*!
Bryant's avatar
Bryant committed
404
  \return true if minor horizontal grid lines are enabled
pixhawk's avatar
pixhawk committed
405
406
  \sa enableYMin()
*/
407
bool QwtPlotGrid::yMinEnabled() const
pixhawk's avatar
pixhawk committed
408
{
409
    return d_data->yMinEnabled;
pixhawk's avatar
pixhawk committed
410
411
}

412

pixhawk's avatar
pixhawk committed
413
/*! \return the scale division of the x axis */
414
415
416
const QwtScaleDiv &QwtPlotGrid::xScaleDiv() const
{
    return d_data->xScaleDiv;
pixhawk's avatar
pixhawk committed
417
418
419
}

/*! \return the scale division of the y axis */
420
421
422
const QwtScaleDiv &QwtPlotGrid::yScaleDiv() const
{
    return d_data->yScaleDiv;
pixhawk's avatar
pixhawk committed
423
}
424

Bryant's avatar
Bryant committed
425
426
427
428
429
430
431
432
433
434
/*!
   Update the grid to changes of the axes scale division

   \param xScaleDiv Scale division of the x-axis
   \param yScaleDiv Scale division of the y-axis

   \sa QwtPlot::updateAxes()
*/
void QwtPlotGrid::updateScaleDiv( const QwtScaleDiv& xScaleDiv,
    const QwtScaleDiv& yScaleDiv )
pixhawk's avatar
pixhawk committed
435
{
Bryant's avatar
Bryant committed
436
437
    setXDiv( xScaleDiv );
    setYDiv( yScaleDiv );
pixhawk's avatar
pixhawk committed
438
}