QwtPlotRescaler takes care of fixed aspect ratios for plot scales. More...
#include <qwt_plot_rescaler.h>
Classes | |
class | AxisData |
class | PrivateData |
Public Types | |
enum | RescalePolicy { Fixed, Expanding, Fitting } |
Rescale Policy. More... | |
enum | ExpandingDirection { ExpandUp, ExpandDown, ExpandBoth } |
Public Member Functions | |
QwtPlotRescaler (QwtPlotCanvas *, int referenceAxis=QwtPlot::xBottom, RescalePolicy=Expanding) | |
virtual | ~QwtPlotRescaler () |
Destructor. | |
void | setEnabled (bool) |
En/disable the rescaler. | |
bool | isEnabled () const |
void | setRescalePolicy (RescalePolicy) |
RescalePolicy | rescalePolicy () const |
void | setExpandingDirection (ExpandingDirection) |
void | setExpandingDirection (int axis, ExpandingDirection) |
ExpandingDirection | expandingDirection (int axis) const |
void | setReferenceAxis (int axis) |
int | referenceAxis () const |
void | setAspectRatio (double ratio) |
void | setAspectRatio (int axis, double ratio) |
double | aspectRatio (int axis) const |
void | setIntervalHint (int axis, const QwtDoubleInterval &) |
QwtDoubleInterval | intervalHint (int axis) const |
QwtPlotCanvas * | canvas () |
const QwtPlotCanvas * | canvas () const |
QwtPlot * | plot () |
const QwtPlot * | plot () const |
virtual bool | eventFilter (QObject *, QEvent *) |
Event filter for the plot canvas. | |
void | rescale () const |
Adjust the plot axes scales. | |
Protected Member Functions | |
virtual void | canvasResizeEvent (QResizeEvent *) |
virtual void | rescale (const QSize &oldSize, const QSize &newSize) const |
virtual QwtDoubleInterval | expandScale (int axis, const QSize &oldSize, const QSize &newSize) const |
virtual QwtDoubleInterval | syncScale (int axis, const QwtDoubleInterval &reference, const QSize &size) const |
virtual void | updateScales (QwtDoubleInterval intervals[QwtPlot::axisCnt]) const |
Qt::Orientation | orientation (int axis) const |
QwtDoubleInterval | interval (int axis) const |
QwtDoubleInterval | expandInterval (const QwtDoubleInterval &, double width, ExpandingDirection) const |
QwtPlotRescaler takes care of fixed aspect ratios for plot scales.
QwtPlotRescaler autoadjusts the axes of a QwtPlot according to fixed aspect ratios.
Definition at line 29 of file qwt_plot_rescaler.h.
Definition at line 65 of file qwt_plot_rescaler.h.
{ ExpandUp, ExpandDown, ExpandBoth };
Rescale Policy.
The rescale policy defines how to rescale the reference axis and their depending axes.
The interval of the reference axis remains unchanged, when the geometry of the canvas changes. All other axes will be adjusted according to their aspect ratio.
The interval of the reference axis will be shrinked/expanded, when the geometry of the canvas changes. All other axes will be adjusted according to their aspect ratio.
The interval, that is represented by one pixel is fixed.
The intervals of the axes are calculated, so that all axes include their minimal interval.
Definition at line 58 of file qwt_plot_rescaler.h.
QwtPlotRescaler::QwtPlotRescaler | ( | QwtPlotCanvas * | canvas, |
int | referenceAxis = QwtPlot::xBottom , |
||
RescalePolicy | policy = Expanding |
||
) | [explicit] |
Constructor
canvas | Canvas |
referenceAxis | Reference axis, see RescalePolicy |
policy | Rescale policy |
Definition at line 62 of file qwt_plot_rescaler.cpp.
References referenceAxis(), QwtPlotRescaler::PrivateData::referenceAxis, QwtPlotRescaler::PrivateData::rescalePolicy, and setEnabled().
: QObject(canvas) { d_data = new PrivateData; d_data->referenceAxis = referenceAxis; d_data->rescalePolicy = policy; setEnabled(true); }
QwtPlotRescaler::~QwtPlotRescaler | ( | ) | [virtual] |
double QwtPlotRescaler::aspectRatio | ( | int | axis ) | const |
Return aspect ratio between an axis and the reference axis.
axis | Axis index ( see QwtPlot::AxisId ) |
Definition at line 232 of file qwt_plot_rescaler.cpp.
References QwtPlotRescaler::AxisData::aspectRatio, QwtPlot::axisCnt, and QwtPlotRescaler::PrivateData::axisData.
Referenced by rescale(), syncScale(), and updateScales().
{ if ( axis >= 0 && axis < QwtPlot::axisCnt ) return d_data->axisData[axis].aspectRatio; return 0.0; }
const QwtPlotCanvas * QwtPlotRescaler::canvas | ( | ) | const |
Definition at line 266 of file qwt_plot_rescaler.cpp.
{ return ((QwtPlotRescaler *)this)->canvas(); }
QwtPlotCanvas * QwtPlotRescaler::canvas | ( | ) |
Definition at line 256 of file qwt_plot_rescaler.cpp.
Referenced by canvasResizeEvent(), eventFilter(), plot(), rescale(), and setEnabled().
{ QObject *o = parent(); if ( o && o->inherits("QwtPlotCanvas") ) return (QwtPlotCanvas *)o; return NULL; }
void QwtPlotRescaler::canvasResizeEvent | ( | QResizeEvent * | e ) | [protected, virtual] |
Definition at line 313 of file qwt_plot_rescaler.cpp.
References canvas(), and rescale().
Referenced by eventFilter().
bool QwtPlotRescaler::eventFilter | ( | QObject * | o, |
QEvent * | e | ||
) | [virtual] |
Event filter for the plot canvas.
Definition at line 292 of file qwt_plot_rescaler.cpp.
References canvas(), canvasResizeEvent(), and rescale().
{ if ( o && o == canvas() ) { switch(e->type()) { case QEvent::Resize: canvasResizeEvent((QResizeEvent *)e); break; #if QT_VERSION >= 0x040000 case QEvent::PolishRequest: rescale(); break; #endif default:; } } return false; }
QwtPlotRescaler::ExpandingDirection QwtPlotRescaler::expandingDirection | ( | int | axis ) | const |
Return direction in which an axis should be expanded
axis | Axis index ( see QwtPlot::AxisId ) |
Definition at line 188 of file qwt_plot_rescaler.cpp.
References QwtPlot::axisCnt, QwtPlotRescaler::PrivateData::axisData, ExpandBoth, and QwtPlotRescaler::AxisData::expandingDirection.
Referenced by expandScale(), and syncScale().
{ if ( axis >= 0 && axis < QwtPlot::axisCnt ) return d_data->axisData[axis].expandingDirection; return ExpandBoth; }
QwtDoubleInterval QwtPlotRescaler::expandInterval | ( | const QwtDoubleInterval & | interval, |
double | width, | ||
ExpandingDirection | direction | ||
) | const [protected] |
Expand the interval
interval | Interval to be expanded |
width | Distance to be added to the interval |
direction | Direction of the expand operation |
Definition at line 510 of file qwt_plot_rescaler.cpp.
References ExpandBoth, ExpandDown, ExpandUp, interval(), QwtDoubleInterval::maxValue(), QwtDoubleInterval::minValue(), QwtDoubleInterval::setMaxValue(), QwtDoubleInterval::setMinValue(), and QwtDoubleInterval::width().
Referenced by expandScale(), and syncScale().
{ QwtDoubleInterval expanded = interval; switch(direction) { case ExpandUp: expanded.setMinValue(interval.minValue()); expanded.setMaxValue(interval.minValue() + width); break; case ExpandDown: expanded.setMaxValue(interval.maxValue()); expanded.setMinValue(interval.maxValue() - width); break; case ExpandBoth: default: expanded.setMinValue(interval.minValue() + interval.width() / 2.0 - width / 2.0); expanded.setMaxValue(expanded.minValue() + width); } return expanded; }
QwtDoubleInterval QwtPlotRescaler::expandScale | ( | int | axis, |
const QSize & | oldSize, | ||
const QSize & | newSize | ||
) | const [protected, virtual] |
Calculate the new scale interval of a plot axis
axis | Axis index ( see QwtPlot::AxisId ) |
oldSize | Previous size of the canvas |
newSize | New size of the canvas |
Definition at line 384 of file qwt_plot_rescaler.cpp.
References QwtPlot::axisCnt, QuadProgPP::dist(), Expanding, expandingDirection(), expandInterval(), Fitting, Fixed, interval(), intervalHint(), orientation(), rescalePolicy(), and QwtDoubleInterval::width().
Referenced by rescale().
{ const QwtDoubleInterval oldInterval = interval(axis); QwtDoubleInterval expanded = oldInterval; switch(rescalePolicy()) { case Fixed: { break; // do nothing } case Expanding: { if ( !oldSize.isEmpty() ) { double width = oldInterval.width(); if ( orientation(axis) == Qt::Horizontal ) width *= double(newSize.width()) / oldSize.width(); else width *= double(newSize.height()) / oldSize.height(); expanded = expandInterval(oldInterval, width, expandingDirection(axis)); } break; } case Fitting: { double dist = 0.0; for ( int ax = 0; ax < QwtPlot::axisCnt; ax++ ) { const double d = pixelDist(ax, newSize); if ( d > dist ) dist = d; } if ( dist > 0.0 ) { double width; if ( orientation(axis) == Qt::Horizontal ) width = newSize.width() * dist; else width = newSize.height() * dist; expanded = expandInterval(intervalHint(axis), width, expandingDirection(axis)); } break; } } return expanded; }
QwtDoubleInterval QwtPlotRescaler::interval | ( | int | axis ) | const [protected] |
Return interval of an axis
axis | Axis index ( see QwtPlot::AxisId ) |
Definition at line 488 of file qwt_plot_rescaler.cpp.
References QwtPlot::axisCnt, QwtPlot::axisScaleDiv(), QwtScaleDiv::lowerBound(), QwtDoubleInterval::normalized(), plot(), and QwtScaleDiv::upperBound().
Referenced by expandInterval(), expandScale(), rescale(), setIntervalHint(), and syncScale().
{ if ( axis < 0 || axis >= QwtPlot::axisCnt ) return QwtDoubleInterval(); const QwtPlot *plt = plot(); const double v1 = plt->axisScaleDiv(axis)->lowerBound(); const double v2 = plt->axisScaleDiv(axis)->upperBound(); return QwtDoubleInterval(v1, v2).normalized(); }
QwtDoubleInterval QwtPlotRescaler::intervalHint | ( | int | axis ) | const |
Definition at line 247 of file qwt_plot_rescaler.cpp.
References QwtPlot::axisCnt, QwtPlotRescaler::PrivateData::axisData, and QwtPlotRescaler::AxisData::intervalHint.
Referenced by expandScale(), rescale(), and syncScale().
{ if ( axis >= 0 && axis < QwtPlot::axisCnt ) return d_data->axisData[axis].intervalHint; return QwtDoubleInterval(); }
bool QwtPlotRescaler::isEnabled | ( | ) | const |
Definition at line 109 of file qwt_plot_rescaler.cpp.
References QwtPlotRescaler::PrivateData::isEnabled.
{ return d_data->isEnabled; }
Qt::Orientation QwtPlotRescaler::orientation | ( | int | axis ) | const [protected] |
Return orientation of an axis
axis | Axis index ( see QwtPlot::AxisId ) |
Definition at line 476 of file qwt_plot_rescaler.cpp.
References QwtPlot::yLeft, and QwtPlot::yRight.
Referenced by expandScale(), and syncScale().
{ if ( axis == QwtPlot::yLeft || axis == QwtPlot::yRight ) return Qt::Vertical; return Qt::Horizontal; }
QwtPlot * QwtPlotRescaler::plot | ( | ) |
Definition at line 272 of file qwt_plot_rescaler.cpp.
References canvas().
Referenced by interval(), rescale(), and updateScales().
const QwtPlot * QwtPlotRescaler::plot | ( | ) | const |
Definition at line 286 of file qwt_plot_rescaler.cpp.
{ return ((QwtPlotRescaler *)this)->plot(); }
int QwtPlotRescaler::referenceAxis | ( | ) | const |
Definition at line 149 of file qwt_plot_rescaler.cpp.
References QwtPlotRescaler::PrivateData::referenceAxis.
Referenced by QwtPlotRescaler(), rescale(), syncScale(), and updateScales().
{ return d_data->referenceAxis; }
void QwtPlotRescaler::rescale | ( | ) | const |
Adjust the plot axes scales.
Definition at line 323 of file qwt_plot_rescaler.cpp.
References QwtPlot::autoReplot(), QwtPlot::axisCnt, canvas(), intervalHint(), QwtDoubleInterval::isNull(), QwtDoubleInterval::maxValue(), QwtDoubleInterval::minValue(), plot(), referenceAxis(), QwtPlot::setAutoReplot(), QwtPlot::setAxisScale(), and QwtPlot::updateAxes().
Referenced by canvasResizeEvent(), and eventFilter().
{ #if 0 const int axis = referenceAxis(); if ( axis < 0 || axis >= QwtPlot::axisCnt ) return; const QwtDoubleInterval hint = intervalHint(axis); if ( !hint.isNull() ) { QwtPlot *plt = (QwtPlot *)plot(); const bool doReplot = plt->autoReplot(); plt->setAutoReplot(false); plt->setAxisScale(axis, hint.minValue(), hint.maxValue()); plt->setAutoReplot(doReplot); plt->updateAxes(); } #endif const QSize size = canvas()->contentsRect().size(); rescale(size, size); }
void QwtPlotRescaler::rescale | ( | const QSize & | oldSize, |
const QSize & | newSize | ||
) | const [protected, virtual] |
Adjust the plot axes scales
oldSize | Previous size of the canvas |
newSize | New size of the canvas |
Definition at line 353 of file qwt_plot_rescaler.cpp.
References aspectRatio(), QwtPlot::axisCnt, expandScale(), interval(), referenceAxis(), syncScale(), and updateScales().
{ if ( newSize.isEmpty() ) return; QwtDoubleInterval intervals[QwtPlot::axisCnt]; for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) intervals[axis] = interval(axis); const int refAxis = referenceAxis(); intervals[refAxis] = expandScale(refAxis, oldSize, newSize); for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) { if ( aspectRatio(axis) > 0.0 && axis != refAxis ) intervals[axis] = syncScale(axis, intervals[refAxis], newSize); } updateScales(intervals); }
QwtPlotRescaler::RescalePolicy QwtPlotRescaler::rescalePolicy | ( | ) | const |
Definition at line 129 of file qwt_plot_rescaler.cpp.
References QwtPlotRescaler::PrivateData::rescalePolicy.
Referenced by expandScale(), and syncScale().
{ return d_data->rescalePolicy; }
void QwtPlotRescaler::setAspectRatio | ( | int | axis, |
double | ratio | ||
) |
Set the aspect ratio between the scale of the reference axis and another scale. The default ratio is 1.0
axis | Axis index ( see QwtPlot::AxisId ) |
ratio | Aspect ratio |
Definition at line 217 of file qwt_plot_rescaler.cpp.
References QwtPlotRescaler::AxisData::aspectRatio, QwtPlot::axisCnt, and QwtPlotRescaler::PrivateData::axisData.
{ if ( ratio < 0.0 ) ratio = 0.0; if ( axis >= 0 && axis < QwtPlot::axisCnt ) d_data->axisData[axis].aspectRatio = ratio; }
void QwtPlotRescaler::setAspectRatio | ( | double | ratio ) |
Set the aspect ratio between the scale of the reference axis and the other scales. The default ratio is 1.0
ratio | Aspect ratio |
Definition at line 203 of file qwt_plot_rescaler.cpp.
References QwtPlot::axisCnt.
{ for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) setAspectRatio(axis, ratio); }
void QwtPlotRescaler::setEnabled | ( | bool | on ) |
En/disable the rescaler.
When enabled is true an event filter is installed for the canvas, otherwise the event filter is removed.
on | true or false |
Definition at line 88 of file qwt_plot_rescaler.cpp.
References canvas(), and QwtPlotRescaler::PrivateData::isEnabled.
Referenced by QwtPlotRescaler().
void QwtPlotRescaler::setExpandingDirection | ( | int | axis, |
ExpandingDirection | direction | ||
) |
Set the direction in which an axis should be expanded
axis | Axis index ( see QwtPlot::AxisId ) |
direction | Direction |
Definition at line 174 of file qwt_plot_rescaler.cpp.
References QwtPlot::axisCnt, QwtPlotRescaler::PrivateData::axisData, and QwtPlotRescaler::AxisData::expandingDirection.
{ if ( axis >= 0 && axis < QwtPlot::axisCnt ) d_data->axisData[axis].expandingDirection = direction; }
void QwtPlotRescaler::setExpandingDirection | ( | ExpandingDirection | direction ) |
Set the direction in which all axis should be expanded
direction | Direction |
Definition at line 160 of file qwt_plot_rescaler.cpp.
References QwtPlot::axisCnt.
{ for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) setExpandingDirection(axis, direction); }
void QwtPlotRescaler::setIntervalHint | ( | int | axis, |
const QwtDoubleInterval & | interval | ||
) |
Definition at line 240 of file qwt_plot_rescaler.cpp.
References QwtPlot::axisCnt, QwtPlotRescaler::PrivateData::axisData, interval(), and QwtPlotRescaler::AxisData::intervalHint.
{ if ( axis >= 0 && axis < QwtPlot::axisCnt ) d_data->axisData[axis].intervalHint = interval; }
void QwtPlotRescaler::setReferenceAxis | ( | int | axis ) |
Set the reference axis ( see RescalePolicy )
axis | Axis index ( QwtPlot::Axis ) |
Definition at line 140 of file qwt_plot_rescaler.cpp.
References QwtPlotRescaler::PrivateData::referenceAxis.
{ d_data->referenceAxis = axis; }
void QwtPlotRescaler::setRescalePolicy | ( | RescalePolicy | policy ) |
Change the rescale policy
policy | Rescale policy |
Definition at line 120 of file qwt_plot_rescaler.cpp.
References QwtPlotRescaler::PrivateData::rescalePolicy.
{ d_data->rescalePolicy = policy; }
QwtDoubleInterval QwtPlotRescaler::syncScale | ( | int | axis, |
const QwtDoubleInterval & | reference, | ||
const QSize & | size | ||
) | const [protected, virtual] |
Synchronize an axis scale according to the scale of the reference axis
axis | Axis index ( see QwtPlot::AxisId ) |
reference | Interval of the reference axis |
size | Size of the canvas |
Definition at line 445 of file qwt_plot_rescaler.cpp.
References aspectRatio(), QuadProgPP::dist(), expandingDirection(), expandInterval(), Fitting, interval(), intervalHint(), orientation(), referenceAxis(), rescalePolicy(), and QwtDoubleInterval::width().
Referenced by rescale().
{ double dist; if ( orientation(referenceAxis()) == Qt::Horizontal ) dist = reference.width() / size.width(); else dist = reference.width() / size.height(); if ( orientation(axis) == Qt::Horizontal ) dist *= size.width(); else dist *= size.height(); dist /= aspectRatio(axis); QwtDoubleInterval intv; if ( rescalePolicy() == Fitting ) intv = intervalHint(axis); else intv = interval(axis); intv = expandInterval(intv, dist, expandingDirection(axis)); return intv; }
void QwtPlotRescaler::updateScales | ( | QwtDoubleInterval | intervals[QwtPlot::axisCnt] ) | const [protected, virtual] |
Update the axes scales
intervals | Scale intervals |
Definition at line 568 of file qwt_plot_rescaler.cpp.
References aspectRatio(), QwtPlot::autoReplot(), QwtPlotRescaler::PrivateData::axisData, QwtPlot::axisScaleDiv(), QwtPlotRescaler::PrivateData::inReplot, QwtScaleDiv::lowerBound(), QwtScaleDiv::NTickTypes, plot(), referenceAxis(), QwtPlot::replot(), QwtPlotRescaler::AxisData::scaleDiv, QwtPlot::setAutoReplot(), QwtPlot::setAxisScale(), QwtPlot::setAxisScaleDiv(), QwtScaleDiv::ticks(), and QwtScaleDiv::upperBound().
Referenced by rescale().
{ if ( d_data->inReplot >= 5 ) { return; } QwtPlot *plt = (QwtPlot *)plot(); const bool doReplot = plt->autoReplot(); plt->setAutoReplot(false); for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ ) { if ( axis == referenceAxis() || aspectRatio(axis) > 0.0 ) { double v1 = intervals[axis].minValue(); double v2 = intervals[axis].maxValue(); if ( plt->axisScaleDiv(axis)->lowerBound() > plt->axisScaleDiv(axis)->upperBound() ) { qSwap(v1, v2); } if ( d_data->inReplot >= 1 ) { d_data->axisData[axis].scaleDiv = *plt->axisScaleDiv(axis); } if ( d_data->inReplot >= 2 ) { QwtValueList ticks[QwtScaleDiv::NTickTypes]; for ( int i = 0; i < QwtScaleDiv::NTickTypes; i++ ) ticks[i] = d_data->axisData[axis].scaleDiv.ticks(i); plt->setAxisScaleDiv(axis, QwtScaleDiv(v1, v2, ticks)); } else { plt->setAxisScale(axis, v1, v2); } } } plt->setAutoReplot(doReplot); d_data->inReplot++; plt->replot(); d_data->inReplot--; }