void QwtPlotScaleItem::updateBorders() { const QwtPlot *plt = plot(); if ( plt == NULL || !d_data->scaleDivFromAxis ) return; const QRect r = plt->canvas()->contentsRect(); d_data->canvasRectCache = r; QwtDoubleInterval interval; if ( d_data->scaleDraw->orientation() == Qt::Horizontal ) { const QwtScaleMap map = plt->canvasMap(xAxis()); interval.setMinValue(map.invTransform(r.left())); interval.setMaxValue(map.invTransform(r.right())); } else { const QwtScaleMap map = plt->canvasMap(yAxis()); interval.setMinValue(map.invTransform(r.bottom())); interval.setMaxValue(map.invTransform(r.top())); } QwtScaleDiv scaleDiv = d_data->scaleDraw->scaleDiv(); scaleDiv.setInterval(interval); d_data->scaleDraw->setScaleDiv(scaleDiv); }
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(); }
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; }
void QwtPlotScaleItem::updateScaleDiv( const QwtScaleDiv& xScaleDiv, const QwtScaleDiv& yScaleDiv ) { QwtScaleDraw *scaleDraw = d_data->scaleDraw; if ( d_data->scaleDivFromAxis && scaleDraw ) { const QwtScaleDiv &scaleDiv = scaleDraw->orientation() == Qt::Horizontal ? xScaleDiv : yScaleDiv; const QwtPlot *plt = plot(); if ( plt != NULL ) { const QRectF canvasRect = plt->canvas()->contentsRect(); const QwtInterval interval = d_data->scaleInterval( canvasRect, plt->canvasMap( xAxis() ), plt->canvasMap( yAxis() ) ); QwtScaleDiv sd = scaleDiv; sd.setInterval( interval ); if ( sd != scaleDraw->scaleDiv() ) { // the internal label cache of QwtScaleDraw // is cleared here, so better avoid pointless // assignments. scaleDraw->setScaleDiv( sd ); } } else { scaleDraw->setScaleDiv( scaleDiv ); } } }
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; }
/*! \brief Draw the scale */ void QwtPlotScaleItem::draw( QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect ) const { QwtScaleDraw *sd = d_data->scaleDraw; if ( d_data->scaleDivFromAxis ) { const QwtInterval interval = d_data->scaleInterval( canvasRect, xMap, yMap ); if ( interval != sd->scaleDiv().interval() ) { QwtScaleDiv scaleDiv = sd->scaleDiv(); scaleDiv.setInterval( interval ); sd->setScaleDiv( scaleDiv ); } } QPen pen = painter->pen(); pen.setStyle( Qt::SolidLine ); painter->setPen( pen ); if ( sd->orientation() == Qt::Horizontal ) { double y; if ( d_data->borderDistance >= 0 ) { if ( sd->alignment() == QwtScaleDraw::BottomScale ) y = canvasRect.top() + d_data->borderDistance; else { y = canvasRect.bottom() - d_data->borderDistance; } } else { y = yMap.transform( d_data->position ); } if ( y < canvasRect.top() || y > canvasRect.bottom() ) return; sd->move( canvasRect.left(), y ); sd->setLength( canvasRect.width() - 1 ); QwtTransform *transform = NULL; if ( xMap.transformation() ) transform = xMap.transformation()->copy(); sd->setTransformation( transform ); } else // == Qt::Vertical { double x; if ( d_data->borderDistance >= 0 ) { if ( sd->alignment() == QwtScaleDraw::RightScale ) x = canvasRect.left() + d_data->borderDistance; else { x = canvasRect.right() - d_data->borderDistance; } } else { x = xMap.transform( d_data->position ); } if ( x < canvasRect.left() || x > canvasRect.right() ) return; sd->move( x, canvasRect.top() ); sd->setLength( canvasRect.height() - 1 ); QwtTransform *transform = NULL; if ( yMap.transformation() ) transform = yMap.transformation()->copy(); sd->setTransformation( transform ); } painter->setFont( d_data->font ); sd->draw( painter, d_data->palette ); }