1
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
3
* Copyright (C) 1997 Josef Wilgen
4
* Copyright (C) 2002 Uwe Rathmann
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
*****************************************************************************/
12
#include "qwt_scale_widget.h"
13
#include "qwt_scale_div.h"
14
#include "qwt_scale_engine.h"
16
class QwtPlot::AxisData
30
QwtScaleEngine *scaleEngine;
31
QwtScaleWidget *scaleWidget;
35
void QwtPlot::initAxesData()
39
for( axisId = 0; axisId < axisCnt; axisId++)
40
d_axisData[axisId] = new AxisData;
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);
52
QFont fscl(fontInfo().family(), 10);
53
QFont fttl(fontInfo().family(), 12, QFont::Bold);
55
for(axisId = 0; axisId < axisCnt; axisId++)
57
AxisData &d = *d_axisData[axisId];
59
d.scaleWidget->setFont(fscl);
60
d.scaleWidget->setMargin(2);
64
d.scaleWidget->setTitle(text);
75
d.scaleEngine = new QwtLinearScaleEngine;
77
d.scaleDiv.invalidate();
80
d_axisData[yLeft]->isEnabled = true;
81
d_axisData[yRight]->isEnabled = false;
82
d_axisData[xBottom]->isEnabled = true;
83
d_axisData[xTop]->isEnabled = false;
86
void QwtPlot::deleteAxesData()
88
for( int axisId = 0; axisId < axisCnt; axisId++)
90
delete d_axisData[axisId]->scaleEngine;
91
delete d_axisData[axisId];
92
d_axisData[axisId] = NULL;
97
\return specified axis, or NULL if axisId is invalid.
98
\param axisId axis index
100
const QwtScaleWidget *QwtPlot::axisWidget(int axisId) const
102
if (axisValid(axisId))
103
return d_axisData[axisId]->scaleWidget;
109
\return specified axis, or NULL if axisId is invalid.
110
\param axisId axis index
112
QwtScaleWidget *QwtPlot::axisWidget(int axisId)
114
if (axisValid(axisId))
115
return d_axisData[axisId]->scaleWidget;
121
Change the scale engine for an axis
123
\param axisId axis index
124
\param scaleEngine Scale engine
126
\sa axisScaleEngine()
128
void QwtPlot::setAxisScaleEngine(int axisId, QwtScaleEngine *scaleEngine)
130
if (axisValid(axisId) && scaleEngine != NULL )
132
AxisData &d = *d_axisData[axisId];
134
delete d.scaleEngine;
135
d.scaleEngine = scaleEngine;
137
d.scaleDiv.invalidate();
143
//! \return Scale engine for a specific axis
144
QwtScaleEngine *QwtPlot::axisScaleEngine(int axisId)
146
if (axisValid(axisId))
147
return d_axisData[axisId]->scaleEngine;
152
//! \return Scale engine for a specific axis
153
const QwtScaleEngine *QwtPlot::axisScaleEngine(int axisId) const
155
if (axisValid(axisId))
156
return d_axisData[axisId]->scaleEngine;
161
\return \c true if autoscaling is enabled
162
\param axisId axis index
164
bool QwtPlot::axisAutoScale(int axisId) const
166
if (axisValid(axisId))
167
return d_axisData[axisId]->doAutoScale;
174
\return \c true if a specified axis is enabled
175
\param axisId axis index
177
bool QwtPlot::axisEnabled(int axisId) const
179
if (axisValid(axisId))
180
return d_axisData[axisId]->isEnabled;
186
\return the font of the scale labels for a specified axis
187
\param axisId axis index
189
QFont QwtPlot::axisFont(int axisId) const
191
if (axisValid(axisId))
192
return axisWidget(axisId)->font();
199
\return the maximum number of major ticks for a specified axis
200
\param axisId axis index
203
int QwtPlot::axisMaxMajor(int axisId) const
205
if (axisValid(axisId))
206
return d_axisData[axisId]->maxMajor;
212
\return the maximum number of minor ticks for a specified axis
213
\param axisId axis index
216
int QwtPlot::axisMaxMinor(int axisId) const
218
if (axisValid(axisId))
219
return d_axisData[axisId]->maxMinor;
225
\brief Return the scale division of a specified axis
227
axisScaleDiv(axisId)->lBound(), axisScaleDiv(axisId)->hBound()
228
are the current limits of the axis scale.
230
\param axisId axis index
231
\return Scale division
233
\sa QwtScaleDiv, setAxisScaleDiv
235
const QwtScaleDiv *QwtPlot::axisScaleDiv(int axisId) const
237
if (!axisValid(axisId))
240
return &d_axisData[axisId]->scaleDiv;
244
\brief Return the scale division of a specified axis
246
axisScaleDiv(axisId)->lBound(), axisScaleDiv(axisId)->hBound()
247
are the current limits of the axis scale.
249
\param axisId axis index
250
\return Scale division
252
\sa QwtScaleDiv, setAxisScaleDiv
254
QwtScaleDiv *QwtPlot::axisScaleDiv(int axisId)
256
if (!axisValid(axisId))
259
return &d_axisData[axisId]->scaleDiv;
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.
268
const QwtScaleDraw *QwtPlot::axisScaleDraw(int axisId) const
270
if (!axisValid(axisId))
273
return axisWidget(axisId)->scaleDraw();
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.
282
QwtScaleDraw *QwtPlot::axisScaleDraw(int axisId)
284
if (!axisValid(axisId))
287
return axisWidget(axisId)->scaleDraw();
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.
295
\param axisId axis index
296
\return step size parameter value
300
double QwtPlot::axisStepSize(int axisId) const
302
if (!axisValid(axisId))
305
return d_axisData[axisId]->stepSize;
309
\return the title of a specified axis
310
\param axisId axis index
312
QwtText QwtPlot::axisTitle(int axisId) const
314
if (axisValid(axisId))
315
return axisWidget(axisId)->title();
321
\brief Enable or disable a specified axis
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.
328
Only xBottom and yLeft are enabled by default.
329
\param axisId axis index
330
\param tf \c true (enabled) or \c false (disabled)
332
void QwtPlot::enableAxis(int axisId, bool tf)
334
if (axisValid(axisId) && tf != d_axisData[axisId]->isEnabled)
336
d_axisData[axisId]->isEnabled = tf;
342
Transform the x or y coordinate of a position in the
343
drawing region into a value.
344
\param axisId axis index
346
\warning The position can be an x or a y coordinate,
347
depending on the specified axis.
349
double QwtPlot::invTransform(int axisId, int pos) const
351
if (axisValid(axisId))
352
return(canvasMap(axisId).invTransform(pos));
359
\brief Transform a value into a coordinate in the plotting region
360
\param axisId axis index
362
\return X or y coordinate in the plotting region corresponding
365
int QwtPlot::transform(int axisId, double value) const
367
if (axisValid(axisId))
368
return(canvasMap(axisId).transform(value));
375
\brief Change the font of an axis
376
\param axisId axis index
378
\warning This function changes the font of the tick labels,
379
not of the axis title.
381
void QwtPlot::setAxisFont(int axisId, const QFont &f)
383
if (axisValid(axisId))
384
axisWidget(axisId)->setFont(f);
388
\brief Enable autoscaling for a specified axis
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.
393
\param axisId axis index
394
\sa QwtPlot::setAxisScale(), QwtPlot::setAxisScaleDiv()
396
void QwtPlot::setAxisAutoScale(int axisId)
398
if (axisValid(axisId) && !d_axisData[axisId]->doAutoScale )
400
d_axisData[axisId]->doAutoScale = true;
406
\brief Disable autoscaling and specify a fixed scale for a selected axis.
407
\param axisId axis index
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()
414
void QwtPlot::setAxisScale(int axisId, double min, double max, double stepSize)
416
if (axisValid(axisId))
418
AxisData &d = *d_axisData[axisId];
420
d.doAutoScale = false;
421
d.scaleDiv.invalidate();
425
d.stepSize = stepSize;
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()
437
void QwtPlot::setAxisScaleDiv(int axisId, const QwtScaleDiv &scaleDiv)
439
if (axisValid(axisId))
441
AxisData &d = *d_axisData[axisId];
443
d.doAutoScale = false;
444
d.scaleDiv = scaleDiv;
451
\brief Set a scale draw
452
\param axisId axis index
453
\param scaleDraw object responsible for drawing scales.
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 ).
460
\sa QwtScaleDraw, QwtScaleWidget
461
\warning The attributes of scaleDraw will be overwritten by those of the
462
previous QwtScaleDraw.
465
void QwtPlot::setAxisScaleDraw(int axisId, QwtScaleDraw *scaleDraw)
467
if (axisValid(axisId))
469
axisWidget(axisId)->setScaleDraw(scaleDraw);
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()
480
#if QT_VERSION < 0x040000
481
void QwtPlot::setAxisLabelAlignment(int axisId, int alignment)
483
void QwtPlot::setAxisLabelAlignment(int axisId, Qt::Alignment alignment)
486
if (axisValid(axisId))
487
axisWidget(axisId)->setLabelAlignment(alignment);
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
497
void QwtPlot::setAxisLabelRotation(int axisId, double rotation)
499
if (axisValid(axisId))
500
axisWidget(axisId)->setLabelRotation(rotation);
504
Set the maximum number of minor scale intervals for a specified axis
506
\param axisId axis index
507
\param maxMinor maximum number of minor steps
510
void QwtPlot::setAxisMaxMinor(int axisId, int maxMinor)
512
if (axisValid(axisId))
516
if ( maxMinor > 100 )
519
AxisData &d = *d_axisData[axisId];
521
if ( maxMinor != d.maxMinor )
523
d.maxMinor = maxMinor;
524
d.scaleDiv.invalidate();
531
Set the maximum number of major scale intervals for a specified axis
533
\param axisId axis index
534
\param maxMajor maximum number of major steps
537
void QwtPlot::setAxisMaxMajor(int axisId, int maxMajor)
539
if (axisValid(axisId))
543
if ( maxMajor > 1000 )
546
AxisData &d = *d_axisData[axisId];
547
if ( maxMajor != d.maxMinor )
549
d.maxMajor = maxMajor;
550
d.scaleDiv.invalidate();
557
\brief Change the title of a specified axis
558
\param axisId axis index
559
\param title axis title
561
void QwtPlot::setAxisTitle(int axisId, const QString &title)
563
if (axisValid(axisId))
564
axisWidget(axisId)->setTitle(title);
568
\brief Change the title of a specified axis
569
\param axisId axis index
570
\param title axis title
572
void QwtPlot::setAxisTitle(int axisId, const QwtText &title)
574
if (axisValid(axisId))
575
axisWidget(axisId)->setTitle(title);
578
//! Rebuild the scales
579
void QwtPlot::updateAxes()
581
// Find bounding interval of the item data
582
// for all axes, where autoscaling is enabled
584
QwtDoubleInterval intv[axisCnt];
586
const QwtPlotItemList& itmList = itemList();
588
QwtPlotItemIterator it;
589
for ( it = itmList.begin(); it != itmList.end(); ++it )
591
const QwtPlotItem *item = *it;
593
if ( !item->testItemAttribute(QwtPlotItem::AutoScale) )
596
if ( axisAutoScale(item->xAxis()) || axisAutoScale(item->yAxis()) )
598
const QwtDoubleRect rect = item->boundingRect();
599
intv[item->xAxis()] |= QwtDoubleInterval(rect.left(), rect.right());
600
intv[item->yAxis()] |= QwtDoubleInterval(rect.top(), rect.bottom());
606
for (int axisId = 0; axisId < axisCnt; axisId++)
608
AxisData &d = *d_axisData[axisId];
610
double minValue = d.minValue;
611
double maxValue = d.maxValue;
612
double stepSize = d.stepSize;
614
if ( d.doAutoScale && intv[axisId].isValid() )
616
d.scaleDiv.invalidate();
618
minValue = intv[axisId].minValue();
619
maxValue = intv[axisId].maxValue();
621
d.scaleEngine->autoScale(d.maxMajor,
622
minValue, maxValue, stepSize);
624
if ( !d.scaleDiv.isValid() )
626
d.scaleDiv = d.scaleEngine->divideScale(
628
d.maxMajor, d.maxMinor, stepSize);
631
QwtScaleWidget *scaleWidget = axisWidget(axisId);
632
scaleWidget->setScaleDiv(
633
d.scaleEngine->transformation(), d.scaleDiv);
635
int startDist, endDist;
636
scaleWidget->getBorderDistHint(startDist, endDist);
637
scaleWidget->setBorderDist(startDist, endDist);
640
for ( it = itmList.begin(); it != itmList.end(); ++it )
642
QwtPlotItem *item = *it;
643
item->updateScaleDiv( *axisScaleDiv(item->xAxis()),
644
*axisScaleDiv(item->yAxis()));