~ubuntu-branches/ubuntu/oneiric/qwt/oneiric-proposed

« back to all changes in this revision

Viewing changes to qwt-5.1.1/src/qwt_plot_axis.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Fathi Boudra
  • Date: 2008-05-26 10:26:31 UTC
  • mfrom: (1.1.3 upstream) (2.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080526102631-bp95mfccnrb957nx
Tags: 5.1.1-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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_plot.h"
 
11
#include "qwt_math.h"
 
12
#include "qwt_scale_widget.h"
 
13
#include "qwt_scale_div.h"
 
14
#include "qwt_scale_engine.h"
 
15
 
 
16
class QwtPlot::AxisData
 
17
{
 
18
public:
 
19
    bool isEnabled;
 
20
    bool doAutoScale;
 
21
 
 
22
    double minValue;
 
23
    double maxValue;
 
24
    double stepSize;
 
25
 
 
26
    int maxMajor;
 
27
    int maxMinor;
 
28
 
 
29
    QwtScaleDiv scaleDiv;
 
30
    QwtScaleEngine *scaleEngine;
 
31
    QwtScaleWidget *scaleWidget;
 
32
};
 
33
 
 
34
//! Initialize axes
 
35
void QwtPlot::initAxesData()
 
36
{
 
37
    int axisId;
 
38
 
 
39
    for( axisId = 0; axisId < axisCnt; axisId++)
 
40
        d_axisData[axisId] = new AxisData;
 
41
 
 
42
    d_axisData[yLeft]->scaleWidget = 
 
43
        new QwtScaleWidget(QwtScaleDraw::LeftScale, this);
 
44
    d_axisData[yRight]->scaleWidget = 
 
45
        new QwtScaleWidget(QwtScaleDraw::RightScale, this);
 
46
    d_axisData[xTop]->scaleWidget = 
 
47
        new QwtScaleWidget(QwtScaleDraw::TopScale, this);
 
48
    d_axisData[xBottom]->scaleWidget = 
 
49
        new QwtScaleWidget(QwtScaleDraw::BottomScale, this);
 
50
 
 
51
 
 
52
    QFont fscl(fontInfo().family(), 10);
 
53
    QFont fttl(fontInfo().family(), 12, QFont::Bold);
 
54
 
 
55
    for(axisId = 0; axisId < axisCnt; axisId++)
 
56
    {
 
57
        AxisData &d = *d_axisData[axisId];
 
58
 
 
59
        d.scaleWidget->setFont(fscl);
 
60
        d.scaleWidget->setMargin(2);
 
61
 
 
62
        QwtText text;
 
63
        text.setFont(fttl);
 
64
        d.scaleWidget->setTitle(text);
 
65
 
 
66
        d.doAutoScale = true;
 
67
 
 
68
        d.minValue = 0.0;
 
69
        d.maxValue = 1000.0;
 
70
        d.stepSize = 0.0;
 
71
 
 
72
        d.maxMinor = 5;
 
73
        d.maxMajor = 8;
 
74
 
 
75
        d.scaleEngine = new QwtLinearScaleEngine;
 
76
 
 
77
        d.scaleDiv.invalidate();
 
78
    }
 
79
 
 
80
    d_axisData[yLeft]->isEnabled = true;
 
81
    d_axisData[yRight]->isEnabled = false;
 
82
    d_axisData[xBottom]->isEnabled = true;
 
83
    d_axisData[xTop]->isEnabled = false;
 
84
}
 
85
 
 
86
void QwtPlot::deleteAxesData()
 
87
{
 
88
    for( int axisId = 0; axisId < axisCnt; axisId++)
 
89
    {
 
90
        delete d_axisData[axisId]->scaleEngine;
 
91
        delete d_axisData[axisId];
 
92
        d_axisData[axisId] = NULL;
 
93
    }
 
94
}
 
95
 
 
96
/*!
 
97
  \return specified axis, or NULL if axisId is invalid.
 
98
  \param axisId axis index
 
99
*/
 
100
const QwtScaleWidget *QwtPlot::axisWidget(int axisId) const
 
101
{
 
102
    if (axisValid(axisId))
 
103
        return d_axisData[axisId]->scaleWidget;
 
104
 
 
105
    return NULL;
 
106
}
 
107
 
 
108
/*!
 
109
  \return specified axis, or NULL if axisId is invalid.
 
110
  \param axisId axis index
 
111
*/
 
112
QwtScaleWidget *QwtPlot::axisWidget(int axisId)
 
113
{
 
114
    if (axisValid(axisId))
 
115
        return d_axisData[axisId]->scaleWidget;
 
116
 
 
117
    return NULL;
 
118
}
 
119
 
 
120
/*!
 
121
   Change the scale engine for an axis
 
122
 
 
123
  \param axisId axis index
 
124
  \param scaleEngine Scale engine
 
125
 
 
126
  \sa axisScaleEngine()
 
127
*/
 
128
void QwtPlot::setAxisScaleEngine(int axisId, QwtScaleEngine *scaleEngine)
 
129
{
 
130
    if (axisValid(axisId) && scaleEngine != NULL )
 
131
    {
 
132
        AxisData &d = *d_axisData[axisId];
 
133
 
 
134
        delete d.scaleEngine;
 
135
        d.scaleEngine = scaleEngine;
 
136
 
 
137
        d.scaleDiv.invalidate();
 
138
 
 
139
        autoRefresh();
 
140
    }
 
141
}
 
142
 
 
143
//! \return Scale engine for a specific axis
 
144
QwtScaleEngine *QwtPlot::axisScaleEngine(int axisId)
 
145
{
 
146
    if (axisValid(axisId))
 
147
        return d_axisData[axisId]->scaleEngine;
 
148
    else
 
149
        return NULL;
 
150
}
 
151
 
 
152
//! \return Scale engine for a specific axis
 
153
const QwtScaleEngine *QwtPlot::axisScaleEngine(int axisId) const
 
154
{
 
155
    if (axisValid(axisId))
 
156
        return d_axisData[axisId]->scaleEngine;
 
157
    else
 
158
        return NULL;
 
159
}
 
160
/*!
 
161
  \return \c true if autoscaling is enabled
 
162
  \param axisId axis index
 
163
*/
 
164
bool QwtPlot::axisAutoScale(int axisId) const
 
165
{
 
166
    if (axisValid(axisId))
 
167
        return d_axisData[axisId]->doAutoScale;
 
168
    else
 
169
        return false;
 
170
    
 
171
}
 
172
 
 
173
/*!
 
174
  \return \c true if a specified axis is enabled
 
175
  \param axisId axis index
 
176
*/
 
177
bool QwtPlot::axisEnabled(int axisId) const
 
178
{
 
179
    if (axisValid(axisId))
 
180
        return d_axisData[axisId]->isEnabled;
 
181
    else
 
182
        return false;
 
183
}
 
184
 
 
185
/*!
 
186
  \return the font of the scale labels for a specified axis
 
187
  \param axisId axis index
 
188
*/
 
189
QFont QwtPlot::axisFont(int axisId) const
 
190
{
 
191
    if (axisValid(axisId))
 
192
        return axisWidget(axisId)->font();
 
193
    else
 
194
        return QFont();
 
195
    
 
196
}
 
197
 
 
198
/*!
 
199
  \return the maximum number of major ticks for a specified axis
 
200
  \param axisId axis index
 
201
  sa setAxisMaxMajor()
 
202
*/
 
203
int QwtPlot::axisMaxMajor(int axisId) const
 
204
{
 
205
    if (axisValid(axisId))
 
206
        return d_axisData[axisId]->maxMajor;
 
207
    else
 
208
        return 0;
 
209
}
 
210
 
 
211
/*!
 
212
  \return the maximum number of minor ticks for a specified axis
 
213
  \param axisId axis index
 
214
  sa setAxisMaxMinor()
 
215
*/
 
216
int QwtPlot::axisMaxMinor(int axisId) const
 
217
{
 
218
    if (axisValid(axisId))
 
219
        return d_axisData[axisId]->maxMinor;
 
220
    else
 
221
        return 0;
 
222
}
 
223
 
 
224
/*!
 
225
  \brief Return the scale division of a specified axis
 
226
 
 
227
  axisScaleDiv(axisId)->lBound(), axisScaleDiv(axisId)->hBound()
 
228
  are the current limits of the axis scale.
 
229
 
 
230
  \param axisId axis index
 
231
  \return Scale division 
 
232
 
 
233
  \sa QwtScaleDiv, setAxisScaleDiv
 
234
*/
 
235
const QwtScaleDiv *QwtPlot::axisScaleDiv(int axisId) const
 
236
{
 
237
    if (!axisValid(axisId))
 
238
        return NULL;
 
239
 
 
240
    return &d_axisData[axisId]->scaleDiv;
 
241
}
 
242
 
 
243
/*!
 
244
  \brief Return the scale division of a specified axis
 
245
 
 
246
  axisScaleDiv(axisId)->lBound(), axisScaleDiv(axisId)->hBound()
 
247
  are the current limits of the axis scale.
 
248
 
 
249
  \param axisId axis index
 
250
  \return Scale division 
 
251
 
 
252
  \sa QwtScaleDiv, setAxisScaleDiv
 
253
*/
 
254
QwtScaleDiv *QwtPlot::axisScaleDiv(int axisId) 
 
255
{
 
256
    if (!axisValid(axisId))
 
257
        return NULL;
 
258
 
 
259
    return &d_axisData[axisId]->scaleDiv;
 
260
}
 
261
 
 
262
/*!
 
263
  \returns the scale draw of a specified axis
 
264
  \param axisId axis index
 
265
  \return specified scaleDraw for axis, or NULL if axis is invalid.
 
266
  \sa QwtScaleDraw
 
267
*/
 
268
const QwtScaleDraw *QwtPlot::axisScaleDraw(int axisId) const
 
269
{
 
270
    if (!axisValid(axisId))
 
271
        return NULL;
 
272
 
 
273
    return axisWidget(axisId)->scaleDraw();
 
274
}
 
275
 
 
276
/*!
 
277
  \returns the scale draw of a specified axis
 
278
  \param axisId axis index
 
279
  \return specified scaleDraw for axis, or NULL if axis is invalid.
 
280
  \sa QwtScaleDraw
 
281
*/
 
282
QwtScaleDraw *QwtPlot::axisScaleDraw(int axisId) 
 
283
{
 
284
    if (!axisValid(axisId))
 
285
        return NULL;
 
286
 
 
287
    return axisWidget(axisId)->scaleDraw();
 
288
}
 
289
 
 
290
/*!
 
291
   Return the step size parameter, that has been set
 
292
   in setAxisScale. This doesn't need to be the step size 
 
293
   of the current scale.
 
294
 
 
295
  \param axisId axis index
 
296
  \return step size parameter value
 
297
 
 
298
   \sa setAxisScale
 
299
*/ 
 
300
double QwtPlot::axisStepSize(int axisId) const
 
301
{
 
302
    if (!axisValid(axisId))
 
303
        return 0;
 
304
 
 
305
    return d_axisData[axisId]->stepSize;
 
306
}
 
307
 
 
308
/*!
 
309
  \return the title of a specified axis
 
310
  \param axisId axis index
 
311
*/
 
312
QwtText QwtPlot::axisTitle(int axisId) const
 
313
{
 
314
    if (axisValid(axisId))
 
315
        return axisWidget(axisId)->title();
 
316
    else
 
317
        return QwtText();
 
318
}
 
319
 
 
320
/*!
 
321
  \brief Enable or disable a specified axis
 
322
 
 
323
  When an axis is disabled, this only means that it is not
 
324
  visible on the screen. Curves, markers and can be attached
 
325
  to disabled axes, and transformation of screen coordinates
 
326
  into values works as normal.
 
327
 
 
328
  Only xBottom and yLeft are enabled by default.
 
329
  \param axisId axis index
 
330
  \param tf \c true (enabled) or \c false (disabled)
 
331
*/
 
332
void QwtPlot::enableAxis(int axisId, bool tf)
 
333
{
 
334
    if (axisValid(axisId) && tf != d_axisData[axisId]->isEnabled)
 
335
    {
 
336
        d_axisData[axisId]->isEnabled = tf;
 
337
        updateLayout();
 
338
    }
 
339
}
 
340
 
 
341
/*!
 
342
  Transform the x or y coordinate of a position in the
 
343
  drawing region into a value.
 
344
  \param axisId axis index
 
345
  \param pos position
 
346
  \warning The position can be an x or a y coordinate,
 
347
           depending on the specified axis.
 
348
*/
 
349
double QwtPlot::invTransform(int axisId, int pos) const
 
350
{
 
351
    if (axisValid(axisId))
 
352
       return(canvasMap(axisId).invTransform(pos));
 
353
    else
 
354
       return 0.0;
 
355
}
 
356
 
 
357
 
 
358
/*!
 
359
  \brief Transform a value into a coordinate in the plotting region
 
360
  \param axisId axis index
 
361
  \param value value
 
362
  \return X or y coordinate in the plotting region corresponding
 
363
          to the value.
 
364
*/
 
365
int QwtPlot::transform(int axisId, double value) const
 
366
{
 
367
    if (axisValid(axisId))
 
368
       return(canvasMap(axisId).transform(value));
 
369
    else
 
370
       return 0;
 
371
    
 
372
}
 
373
 
 
374
/*!
 
375
  \brief Change the font of an axis
 
376
  \param axisId axis index
 
377
  \param f font
 
378
  \warning This function changes the font of the tick labels,
 
379
           not of the axis title.
 
380
*/
 
381
void QwtPlot::setAxisFont(int axisId, const QFont &f)
 
382
{
 
383
    if (axisValid(axisId))
 
384
        axisWidget(axisId)->setFont(f);
 
385
}
 
386
 
 
387
/*!
 
388
  \brief Enable autoscaling for a specified axis
 
389
 
 
390
  This member function is used to switch back to autoscaling mode
 
391
  after a fixed scale has been set. Autoscaling is enabled by default.
 
392
 
 
393
  \param axisId axis index
 
394
  \sa QwtPlot::setAxisScale(), QwtPlot::setAxisScaleDiv()
 
395
*/
 
396
void QwtPlot::setAxisAutoScale(int axisId)
 
397
{
 
398
    if (axisValid(axisId) && !d_axisData[axisId]->doAutoScale )
 
399
    {
 
400
        d_axisData[axisId]->doAutoScale = true;
 
401
        autoRefresh();
 
402
    }
 
403
}
 
404
 
 
405
/*!
 
406
  \brief Disable autoscaling and specify a fixed scale for a selected axis.
 
407
  \param axisId axis index
 
408
  \param min
 
409
  \param max minimum and maximum of the scale
 
410
  \param stepSize Major step size. If <code>step == 0</code>, the step size is
 
411
            calculated automatically using the maxMajor setting.
 
412
  \sa setAxisMaxMajor(), setAxisAutoScale()
 
413
*/
 
414
void QwtPlot::setAxisScale(int axisId, double min, double max, double stepSize)
 
415
{
 
416
    if (axisValid(axisId))
 
417
    {
 
418
        AxisData &d = *d_axisData[axisId];
 
419
 
 
420
        d.doAutoScale = false;
 
421
        d.scaleDiv.invalidate();
 
422
 
 
423
        d.minValue = min;
 
424
        d.maxValue = max;
 
425
        d.stepSize = stepSize;
 
426
            
 
427
        autoRefresh();
 
428
    }
 
429
}
 
430
 
 
431
/*!
 
432
  \brief Disable autoscaling and specify a fixed scale for a selected axis.
 
433
  \param axisId axis index
 
434
  \param scaleDiv Scale division
 
435
  \sa setAxisScale(), setAxisAutoScale()
 
436
*/
 
437
void QwtPlot::setAxisScaleDiv(int axisId, const QwtScaleDiv &scaleDiv)
 
438
{
 
439
    if (axisValid(axisId))
 
440
    {
 
441
        AxisData &d = *d_axisData[axisId];
 
442
 
 
443
        d.doAutoScale = false;
 
444
        d.scaleDiv = scaleDiv;
 
445
 
 
446
        autoRefresh();
 
447
    }
 
448
}
 
449
 
 
450
/*!
 
451
  \brief Set a scale draw
 
452
  \param axisId axis index
 
453
  \param scaleDraw object responsible for drawing scales.
 
454
 
 
455
  By passing scaleDraw it is possible to extend QwtScaleDraw
 
456
  functionality and let it take place in QwtPlot. Please note
 
457
  that scaleDraw has to be created with new and will be deleted
 
458
  by the corresponding QwtScale member ( like a child object ).
 
459
 
 
460
  \sa QwtScaleDraw, QwtScaleWidget
 
461
  \warning The attributes of scaleDraw will be overwritten by those of the  
 
462
           previous QwtScaleDraw. 
 
463
*/
 
464
 
 
465
void QwtPlot::setAxisScaleDraw(int axisId, QwtScaleDraw *scaleDraw)
 
466
{
 
467
    if (axisValid(axisId))
 
468
    {
 
469
        axisWidget(axisId)->setScaleDraw(scaleDraw);
 
470
        autoRefresh();
 
471
    }
 
472
}
 
473
 
 
474
/*!
 
475
  Change the alignment of the tick labels
 
476
  \param axisId axis index
 
477
  \param alignment Or'd Qt::AlignmentFlags <see qnamespace.h>
 
478
  \sa QwtScaleDraw::setLabelAlignment()
 
479
*/
 
480
#if QT_VERSION < 0x040000
 
481
void QwtPlot::setAxisLabelAlignment(int axisId, int alignment)
 
482
#else
 
483
void QwtPlot::setAxisLabelAlignment(int axisId, Qt::Alignment alignment)
 
484
#endif
 
485
{
 
486
    if (axisValid(axisId))
 
487
        axisWidget(axisId)->setLabelAlignment(alignment);
 
488
}
 
489
 
 
490
/*!
 
491
  Rotate all tick labels
 
492
  \param axisId axis index
 
493
  \param rotation Angle in degrees. When changing the label rotation,
 
494
                  the label alignment might be adjusted too.
 
495
  \sa QwtScaleDraw::setLabelRotation(), QwtPlot::setAxisLabelAlignment
 
496
*/
 
497
void QwtPlot::setAxisLabelRotation(int axisId, double rotation)
 
498
{
 
499
    if (axisValid(axisId))
 
500
        axisWidget(axisId)->setLabelRotation(rotation);
 
501
}
 
502
 
 
503
/*!
 
504
  Set the maximum number of minor scale intervals for a specified axis
 
505
 
 
506
  \param axisId axis index
 
507
  \param maxMinor maximum number of minor steps
 
508
  \sa axisMaxMinor()
 
509
*/
 
510
void QwtPlot::setAxisMaxMinor(int axisId, int maxMinor)
 
511
{
 
512
    if (axisValid(axisId))
 
513
    {
 
514
        if ( maxMinor < 0 )
 
515
            maxMinor = 0;
 
516
        if ( maxMinor > 100 )
 
517
            maxMinor = 100;
 
518
            
 
519
        AxisData &d = *d_axisData[axisId];
 
520
 
 
521
        if ( maxMinor != d.maxMinor )
 
522
        {
 
523
            d.maxMinor = maxMinor;
 
524
            d.scaleDiv.invalidate();
 
525
            autoRefresh();
 
526
        }
 
527
    }
 
528
}
 
529
 
 
530
/*!
 
531
  Set the maximum number of major scale intervals for a specified axis
 
532
 
 
533
  \param axisId axis index
 
534
  \param maxMajor maximum number of major steps
 
535
  \sa axisMaxMajor()
 
536
*/
 
537
void QwtPlot::setAxisMaxMajor(int axisId, int maxMajor)
 
538
{
 
539
    if (axisValid(axisId))
 
540
    {
 
541
        if ( maxMajor < 1 )
 
542
            maxMajor = 1;
 
543
        if ( maxMajor > 1000 )
 
544
            maxMajor = 10000;
 
545
            
 
546
        AxisData &d = *d_axisData[axisId];
 
547
        if ( maxMajor != d.maxMinor )
 
548
        {
 
549
            d.maxMajor = maxMajor;
 
550
            d.scaleDiv.invalidate();
 
551
            autoRefresh();
 
552
        }
 
553
    }
 
554
}
 
555
 
 
556
/*!
 
557
  \brief Change the title of a specified axis
 
558
  \param axisId axis index
 
559
  \param title axis title
 
560
*/
 
561
void QwtPlot::setAxisTitle(int axisId, const QString &title)
 
562
{
 
563
    if (axisValid(axisId))
 
564
        axisWidget(axisId)->setTitle(title);
 
565
}
 
566
 
 
567
/*!
 
568
  \brief Change the title of a specified axis
 
569
  \param axisId axis index
 
570
  \param title axis title
 
571
*/
 
572
void QwtPlot::setAxisTitle(int axisId, const QwtText &title)
 
573
{
 
574
    if (axisValid(axisId))
 
575
        axisWidget(axisId)->setTitle(title);
 
576
}
 
577
 
 
578
//! Rebuild the scales
 
579
void QwtPlot::updateAxes() 
 
580
{
 
581
    // Find bounding interval of the item data
 
582
    // for all axes, where autoscaling is enabled
 
583
    
 
584
    QwtDoubleInterval intv[axisCnt];
 
585
 
 
586
    const QwtPlotItemList& itmList = itemList();
 
587
 
 
588
    QwtPlotItemIterator it;
 
589
    for ( it = itmList.begin(); it != itmList.end(); ++it )
 
590
    {
 
591
        const QwtPlotItem *item = *it;
 
592
 
 
593
        if ( !item->testItemAttribute(QwtPlotItem::AutoScale) )
 
594
            continue;
 
595
 
 
596
        if ( axisAutoScale(item->xAxis()) || axisAutoScale(item->yAxis()) )
 
597
        {
 
598
            const QwtDoubleRect rect = item->boundingRect();
 
599
            intv[item->xAxis()] |= QwtDoubleInterval(rect.left(), rect.right());
 
600
            intv[item->yAxis()] |= QwtDoubleInterval(rect.top(), rect.bottom());
 
601
        }
 
602
    }
 
603
 
 
604
    // Adjust scales
 
605
 
 
606
    for (int axisId = 0; axisId < axisCnt; axisId++)
 
607
    {
 
608
        AxisData &d = *d_axisData[axisId];
 
609
 
 
610
        double minValue = d.minValue;
 
611
        double maxValue = d.maxValue;
 
612
        double stepSize = d.stepSize;
 
613
 
 
614
        if ( d.doAutoScale && intv[axisId].isValid() )
 
615
        {
 
616
            d.scaleDiv.invalidate();
 
617
 
 
618
            minValue = intv[axisId].minValue();
 
619
            maxValue = intv[axisId].maxValue();
 
620
 
 
621
            d.scaleEngine->autoScale(d.maxMajor, 
 
622
                minValue, maxValue, stepSize);
 
623
        }
 
624
        if ( !d.scaleDiv.isValid() )
 
625
        {
 
626
            d.scaleDiv = d.scaleEngine->divideScale(
 
627
                minValue, maxValue, 
 
628
                d.maxMajor, d.maxMinor, stepSize);
 
629
        }
 
630
 
 
631
        QwtScaleWidget *scaleWidget = axisWidget(axisId);
 
632
        scaleWidget->setScaleDiv(
 
633
            d.scaleEngine->transformation(), d.scaleDiv);
 
634
 
 
635
        int startDist, endDist;
 
636
        scaleWidget->getBorderDistHint(startDist, endDist);
 
637
        scaleWidget->setBorderDist(startDist, endDist);
 
638
    }
 
639
 
 
640
    for ( it = itmList.begin(); it != itmList.end(); ++it )
 
641
    {
 
642
        QwtPlotItem *item = *it;
 
643
        item->updateScaleDiv( *axisScaleDiv(item->xAxis()),
 
644
            *axisScaleDiv(item->yAxis()));
 
645
    }
 
646
}
 
647