void OscilloscopePlot::incrementInterval() { d_interval = QwtInterval( d_interval.maxValue(), d_interval.maxValue() + d_interval.width() ); CurveData *data = static_cast<CurveData *>( d_curve->data() ); data->values().clearStaleValues( d_interval.minValue() ); // To avoid, that the grid is jumping, we disable // the autocalculation of the ticks and shift them // manually instead. QwtScaleDiv scaleDiv = axisScaleDiv( QwtPlot::xBottom ); scaleDiv.setInterval( d_interval ); for ( int i = 0; i < QwtScaleDiv::NTickTypes; i++ ) { QList<double> ticks = scaleDiv.ticks( i ); for ( int j = 0; j < ticks.size(); j++ ) ticks[j] += d_interval.width(); scaleDiv.setTicks( i, ticks ); } setAxisScaleDiv( QwtPlot::xBottom, scaleDiv ); d_origin->setValue( d_interval.minValue() + d_interval.width() / 2.0, 0.0 ); d_paintedPoints = 0; replot(); }
Knob::Knob(const QString &title, double min, double max, QWidget *parent): QWidget(parent) { QFont font("Helvetica", 10); d_knob = new QwtKnob(this); d_knob->setFont(font); d_knob->setRange(min, max); QwtScaleDiv scaleDiv = d_knob->scaleEngine()->divideScale(min, max, 5, 3); QList<double> ticks = scaleDiv.ticks(QwtScaleDiv::MajorTick); if ( ticks.size() > 0 && ticks[0] > min ) { if ( ticks.first() > min ) ticks.prepend(min); if ( ticks.last() < max ) ticks.append(max); } scaleDiv.setTicks(QwtScaleDiv::MajorTick, ticks); d_knob->setScale(scaleDiv); d_knob->setKnobWidth(50); font.setBold(true); d_label = new QLabel(title, this); d_label->setFont(font); d_label->setAlignment(Qt::AlignTop | Qt::AlignHCenter); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); connect(d_knob, SIGNAL(valueChanged(double)), this, SIGNAL(valueChanged(double))); }
void Plot::incrementInterval() { d_interval = QwtInterval(d_interval.maxValue(), d_interval.maxValue() + d_interval.width()); CurveData *data0 = static_cast<CurveData *>( d_curve0->data() ); CurveData *data1 = static_cast<CurveData *>( d_curve1->data() ); data0->clearStaleVal(d_interval.minValue()); data1->clearStaleVal(d_interval.minValue()); QwtScaleDiv scaleDiv = *axisScaleDiv(QwtPlot::xBottom); scaleDiv.setInterval(d_interval); for ( int i = 0; i < QwtScaleDiv::NTickTypes; i++ ) { QList<double> ticks = scaleDiv.ticks(i); for ( int j = 0; j < ticks.size(); j++ ) ticks[j] += d_interval.width(); scaleDiv.setTicks(i, ticks); } setAxisScaleDiv(QwtPlot::xBottom, scaleDiv); d_origin->setValue(d_interval.minValue() + d_interval.width() / 2.0, 0.0); d_paintedPoints0 = 0; d_paintedPoints1 = 0; replot(); }
/*! Return a scale division with an interval [lowerBound, upperBound] where all ticks outside this interval are removed \param lowerBound Lower bound \param upperBound Upper bound \note lowerBound might be greater than upperBound for inverted scales */ QwtScaleDiv QwtScaleDiv::bounded( double lowerBound, double upperBound ) const { const double min = qMin( lowerBound, upperBound ); const double max = qMax( lowerBound, upperBound ); QwtScaleDiv sd; sd.setInterval( lowerBound, upperBound ); for ( int tickType = 0; tickType < QwtScaleDiv::NTickTypes; tickType++ ) { const QList<double> &ticks = d_ticks[ tickType ]; QList<double> boundedTicks; for ( int i = 0; i < ticks.size(); i++ ) { const double tick = ticks[i]; if ( tick >= min && tick <= max ) boundedTicks += tick; } sd.setTicks( tickType, boundedTicks ); } return sd; }
KnobSpin::KnobSpin(const QString &title, double min, double max, double step, QWidget *parent): QWidget(parent) { QFont font("Helvetica", 10); knob_ = new QwtKnob(this); knob_->setFont(font); knob_->setRange(min, max); QwtScaleDiv scaleDiv = knob_->scaleEngine()->divideScale(min, max, 5, 3); QList<double> ticks = scaleDiv.ticks(QwtScaleDiv::MajorTick); if ( ticks.size() > 0 && ticks[0] > min ) { if ( ticks.first() > min ) ticks.prepend(min); if ( ticks.last() < max ) ticks.append(max); } scaleDiv.setTicks(QwtScaleDiv::MajorTick, ticks); knob_->setScale(scaleDiv); knob_->setKnobWidth(150); knob_->setStep(step); spin_ = new QDoubleSpinBox(this); spin_->setRange(min, max); spin_->setSingleStep(step); font.setBold(true); label_ = new QLabel(title, this); label_->setFont(font); label_->setAlignment(Qt::AlignTop | Qt::AlignHCenter); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); connect(spin_, SIGNAL(valueChanged(double)), this, SIGNAL(valueChanged(double))); connect(knob_, SIGNAL(valueChanged(double)), spin_, SLOT(setValue(double)) ); connect(spin_, SIGNAL(valueChanged(double)), knob_, SLOT(setValue(double)) ); }
void Plot::setTransformation( QwtTransform *transform ) { QwtLinearScaleEngine *scaleEngine = new QwtLinearScaleEngine(); scaleEngine->setTransformation( transform ); setAxisScaleEngine( QwtAxis::xBottom, scaleEngine ); // we have to reassign the axis settinge, because they are // invalidated, when the scale engine has changed QwtScaleDiv scaleDiv = axisScaleEngine( QwtAxis::xBottom )->divideScale( 10.0, 1000.0, 8, 10 ); QList<double> ticks; ticks += 10.0; ticks += scaleDiv.ticks( QwtScaleDiv::MajorTick ); scaleDiv.setTicks( QwtScaleDiv::MajorTick, ticks ); setAxisScaleDiv( QwtAxis::xBottom, scaleDiv ); replot(); }
static QwtScaleDiv qwtDivideToYears( const QDateTime &minDate, const QDateTime &maxDate, double stepSize, int maxMinSteps ) { QList<double> majorTicks; QList<double> mediumTicks; QList<double> minorTicks; double minStepSize = 0.0; if ( maxMinSteps > 1 ) { minStepSize = qwtDivideMajorStep( stepSize, maxMinSteps, QwtDate::Year ); } int numMinorSteps = 0; if ( minStepSize > 0.0 ) numMinorSteps = qFloor( stepSize / minStepSize ); bool dateBC = minDate.date().year() < -1; for ( QDateTime dt = minDate; dt <= maxDate; dt = dt.addYears( stepSize ) ) { if ( dateBC && dt.date().year() > 1 ) { // there is no year 0 in the Julian calendar dt = dt.addYears( -1 ); dateBC = false; } if ( !dt.isValid() ) break; majorTicks += QwtDate::toDouble( dt ); for ( int i = 1; i < numMinorSteps; i++ ) { QDateTime tickDate; const double years = qRound( i * minStepSize ); if ( years >= INT_MAX / 12 ) { tickDate = dt.addYears( years ); } else { tickDate = dt.addMonths( qRound( years * 12 ) ); } const bool isMedium = ( numMinorSteps > 2 ) && ( numMinorSteps % 2 == 0 ) && ( i == numMinorSteps / 2 ); const double minorValue = QwtDate::toDouble( tickDate ); if ( isMedium ) mediumTicks += minorValue; else minorTicks += minorValue; } if ( QwtDate::maxDate().addYears( -stepSize ) < dt.date() ) { break; } } QwtScaleDiv scaleDiv; scaleDiv.setInterval( QwtDate::toDouble( minDate ), QwtDate::toDouble( maxDate ) ); scaleDiv.setTicks( QwtScaleDiv::MajorTick, majorTicks ); scaleDiv.setTicks( QwtScaleDiv::MediumTick, mediumTicks ); scaleDiv.setTicks( QwtScaleDiv::MinorTick, minorTicks ); return scaleDiv; }
static QwtScaleDiv qwtDivideToMonths( QDateTime &minDate, const QDateTime &maxDate, double stepSize, int maxMinSteps ) { // months are intervals with non // equidistant ( in ms ) steps: we have to build the // scale division manually int minStepDays = 0; int minStepSize = 0.0; if ( maxMinSteps > 1 ) { if ( stepSize == 1 ) { if ( maxMinSteps >= 30 ) minStepDays = 1; else if ( maxMinSteps >= 6 ) minStepDays = 5; else if ( maxMinSteps >= 3 ) minStepDays = 10; minStepDays = 15; } else { minStepSize = qwtDivideMajorStep( stepSize, maxMinSteps, QwtDate::Month ); } } QList<double> majorTicks; QList<double> mediumTicks; QList<double> minorTicks; for ( QDateTime dt = minDate; dt <= maxDate; dt = dt.addMonths( stepSize ) ) { if ( !dt.isValid() ) break; majorTicks += QwtDate::toDouble( dt ); if ( minStepDays > 0 ) { for ( int days = minStepDays; days < 30; days += minStepDays ) { const double tick = QwtDate::toDouble( dt.addDays( days ) ); if ( days == 15 && minStepDays != 15 ) mediumTicks += tick; else minorTicks += tick; } } else if ( minStepSize > 0.0 ) { const int numMinorSteps = qRound( stepSize / (double) minStepSize ); for ( int i = 1; i < numMinorSteps; i++ ) { const double minorValue = QwtDate::toDouble( dt.addMonths( i * minStepSize ) ); if ( ( numMinorSteps % 2 == 0 ) && ( i == numMinorSteps / 2 ) ) mediumTicks += minorValue; else minorTicks += minorValue; } } } QwtScaleDiv scaleDiv; scaleDiv.setInterval( QwtDate::toDouble( minDate ), QwtDate::toDouble( maxDate ) ); scaleDiv.setTicks( QwtScaleDiv::MajorTick, majorTicks ); scaleDiv.setTicks( QwtScaleDiv::MediumTick, mediumTicks ); scaleDiv.setTicks( QwtScaleDiv::MinorTick, minorTicks ); return scaleDiv; }
static QwtScaleDiv qwtDivideToSeconds( const QDateTime &minDate, const QDateTime &maxDate, double stepSize, int maxMinSteps, QwtDate::IntervalType intervalType ) { // calculate the min step size double minStepSize = 0; if ( maxMinSteps > 1 ) { minStepSize = qwtDivideMajorStep( stepSize, maxMinSteps, intervalType ); } bool daylightSaving = false; if ( minDate.timeSpec() == Qt::LocalTime ) { daylightSaving = intervalType > QwtDate::Hour; if ( intervalType == QwtDate::Hour ) { daylightSaving = stepSize > 1; } } const double s = qwtMsecsForType( intervalType ) / 1000; const int secondsMajor = static_cast<int>( stepSize * s ); const double secondsMinor = minStepSize * s; // UTC excludes daylight savings. So from the difference // of a date and its UTC counterpart we can find out // the daylight saving hours const double utcOffset = QwtDate::utcOffset( minDate ); double dstOff = 0; QList<double> majorTicks; QList<double> mediumTicks; QList<double> minorTicks; for ( QDateTime dt = minDate; dt <= maxDate; dt = dt.addSecs( secondsMajor ) ) { if ( !dt.isValid() ) break; double majorValue = QwtDate::toDouble( dt ); if ( daylightSaving ) { const double offset = utcOffset - QwtDate::utcOffset( dt ); majorValue += offset * 1000.0; if ( offset > dstOff ) { // we add some minor ticks for the DST hour, // otherwise the ticks will be unaligned: 0, 2, 3, 5 ... minorTicks += qwtDstTicks( dt, secondsMajor, qRound( secondsMinor ) ); } dstOff = offset; } if ( majorTicks.isEmpty() || majorTicks.last() != majorValue ) majorTicks += majorValue; if ( secondsMinor > 0.0 ) { const int numMinorSteps = qFloor( secondsMajor / secondsMinor ); for ( int i = 1; i < numMinorSteps; i++ ) { const QDateTime mt = dt.addMSecs( qRound64( i * secondsMinor * 1000 ) ); double minorValue = QwtDate::toDouble( mt ); if ( daylightSaving ) { const double offset = utcOffset - QwtDate::utcOffset( mt ); minorValue += offset * 1000.0; } if ( minorTicks.isEmpty() || minorTicks.last() != minorValue ) { const bool isMedium = ( numMinorSteps % 2 == 0 ) && ( i != 1 ) && ( i == numMinorSteps / 2 ); if ( isMedium ) mediumTicks += minorValue; else minorTicks += minorValue; } } } } QwtScaleDiv scaleDiv; scaleDiv.setInterval( QwtDate::toDouble( minDate ), QwtDate::toDouble( maxDate ) ); scaleDiv.setTicks( QwtScaleDiv::MajorTick, majorTicks ); scaleDiv.setTicks( QwtScaleDiv::MediumTick, mediumTicks ); scaleDiv.setTicks( QwtScaleDiv::MinorTick, minorTicks ); return scaleDiv; }
void QwtPolarGrid::updateScaleDiv( const QwtScaleDiv &azimuthScaleDiv, const QwtScaleDiv &radialScaleDiv, const QwtInterval &interval ) { GridData &radialGrid = d_data->gridData[QwtPolar::Radius]; const QwtPolarPlot *plt = plot(); if ( plt && testGridAttribute( AutoScaling ) ) { const QwtScaleEngine *se = plt->scaleEngine( QwtPolar::Radius ); radialGrid.scaleDiv = se->divideScale( interval.minValue(), interval.maxValue(), plt->scaleMaxMajor( QwtPolar::Radius ), plt->scaleMaxMinor( QwtPolar::Radius ), 0 ); } else { if ( radialGrid.scaleDiv != radialScaleDiv ) radialGrid.scaleDiv = radialScaleDiv; } GridData &azimuthGrid = d_data->gridData[QwtPolar::Azimuth]; if ( azimuthGrid.scaleDiv != azimuthScaleDiv ) { azimuthGrid.scaleDiv = azimuthScaleDiv; } bool hasOrigin = false; for ( int axisId = 0; axisId < QwtPolar::AxesCount; axisId++ ) { AxisData &axis = d_data->axisData[axisId]; if ( axis.isVisible && axis.scaleDraw ) { if ( axisId == QwtPolar::AxisAzimuth ) { axis.scaleDraw->setScaleDiv( azimuthGrid.scaleDiv ); if ( testDisplayFlag( SmartScaleDraw ) ) { axis.scaleDraw->enableComponent( QwtAbstractScaleDraw::Ticks, !azimuthGrid.isVisible ); } } else { QwtScaleDiv sd = radialGrid.scaleDiv; QList<double> ticks = sd.ticks( QwtScaleDiv::MajorTick ); if ( testDisplayFlag( SmartOriginLabel ) ) { bool skipOrigin = hasOrigin; if ( !skipOrigin ) { if ( axisId == QwtPolar::AxisLeft || axisId == QwtPolar::AxisRight ) { if ( d_data->axisData[QwtPolar::AxisBottom].isVisible ) skipOrigin = true; } else { if ( d_data->axisData[QwtPolar::AxisLeft].isVisible ) skipOrigin = true; } } if ( ticks.size() > 0 && ticks.first() == sd.lowerBound() ) { if ( skipOrigin ) ticks.removeFirst(); else hasOrigin = true; } } if ( testDisplayFlag( HideMaxRadiusLabel ) ) { if ( ticks.size() > 0 && ticks.last() == sd.upperBound() ) ticks.removeLast(); } sd.setTicks( QwtScaleDiv::MajorTick, ticks ); axis.scaleDraw->setScaleDiv( sd ); if ( testDisplayFlag( SmartScaleDraw ) ) { axis.scaleDraw->enableComponent( QwtAbstractScaleDraw::Ticks, !radialGrid.isVisible ); } } } } }