void VectorPlot::setupPlot(const QwtDoubleRect &rect) { QwtScaleDiv *hDiv = plot->axisScaleDiv(QwtPlot::xBottom); QwtScaleDiv *vDiv = plot->axisScaleDiv(QwtPlot::yLeft); // In earlier qwt version some member function names are different from newer version #if QWT_VERSION <= 0x050101 double lLimit = std::min(hDiv->lBound(), rect.left()); double rLimit = std::max(hDiv->hBound(), rect.right()); double bLimit = std::min(vDiv->lBound(), rect.bottom()); double tLimit = std::max(vDiv->hBound(), rect.top()); #else double lLimit = std::min(hDiv->lowerBound(), rect.left()); double rLimit = std::max(hDiv->upperBound(), rect.right()); double bLimit = std::min(vDiv->lowerBound(), rect.bottom()); double tLimit = std::max(vDiv->upperBound(), rect.top()); #endif plot->setAxisScale(QwtPlot::xBottom, lLimit, rLimit); plot->setAxisScale(QwtPlot::yLeft, bLimit, tLimit); double xMargin = plot->invTransform(QwtPlot::xBottom, plot->margin()); double yMargin = plot->invTransform(QwtPlot::yLeft, plot->margin()); mBoundingRect = QwtDoubleRect(QwtDoublePoint(lLimit - xMargin, tLimit + yMargin), QwtDoublePoint(rLimit + xMargin, bLimit - yMargin)); qDebug() << "xMargin:" << xMargin; qDebug() << "yMargin:" << yMargin; qDebug() << "mBoundingRect:" << mBoundingRect; // mBoundingRect = rect; }
void Spectrogram::showColorScale(int axis, bool on) { if (hasColorScale() == on && color_axis == axis) return; QwtPlot *plot = this->plot(); if (!plot) return; QwtScaleWidget *colorAxis = plot->axisWidget(color_axis); colorAxis->setColorBarEnabled(false); color_axis = axis; // We must switch main and the color scale axes and their respective scales int xAxis = this->xAxis(); int yAxis = this->yAxis(); int oldMainAxis = yAxis; if (axis == QwtPlot::xBottom || axis == QwtPlot::xTop) { oldMainAxis = xAxis; xAxis = 5 - color_axis; } else if (axis == QwtPlot::yLeft || axis == QwtPlot::yRight) { oldMainAxis = yAxis; yAxis = 1 - color_axis; } // First we switch axes setAxis(xAxis, yAxis); // Next we switch axes scales QwtScaleDiv *scDiv = plot->axisScaleDiv(oldMainAxis); if (axis == QwtPlot::xBottom || axis == QwtPlot::xTop) plot->setAxisScale(xAxis, scDiv->lBound(), scDiv->hBound()); else if (axis == QwtPlot::yLeft || color_axis == QwtPlot::yRight) plot->setAxisScale(yAxis, scDiv->lBound(), scDiv->hBound()); colorAxis = plot->axisWidget(color_axis); plot->setAxisScale(color_axis, data().range().minValue(), data().range().maxValue()); colorAxis->setColorBarEnabled(on); colorAxis->setColorMap(data().range(), colorMap()); if (!plot->axisEnabled(color_axis)) plot->enableAxis(color_axis); colorAxis->show(); plot->updateLayout(); }
/** * Set the scale of the horizontal axis * @param from :: Minimum value * @param to :: Maximum value */ void OneCurvePlot::setXScale(double from, double to) { QFontMetrics fm(axisFont(QwtPlot::xBottom)); int n = from != 0.0 ? abs(static_cast<int>(floor(log10(fabs(from))))) : 0; int n1 = to != 0.0 ? abs(static_cast<int>(floor(log10(fabs(to))))) : 0; if (n1 > n) n = n1; n += 4; // approxiamte width of a tick label in pixels int labelWidth = n * fm.width("0"); // calculate number of major ticks int nMajorTicks = this->width() / labelWidth; if ( nMajorTicks > 6 ) nMajorTicks = 6; // try creating a scale const QwtScaleDiv div = axisScaleEngine(QwtPlot::xBottom)->divideScale(from,to,nMajorTicks,nMajorTicks); // Major ticks are placed at round numbers so the first or last tick could be missing making // scale look ugly. Trying to fix it if possible bool rescaled = false; // get actual tick positions const QwtValueList& ticks = div.ticks(QwtScaleDiv::MajorTick); if (!ticks.empty() && ticks.size() < nMajorTicks) { // how much first tick is shifted from the lower bound double firstShift = ticks.front() - div.lBound(); // how much last tick is shifted from the upper bound double lastShift = div.hBound() - ticks.back(); // range of the scale double range = fabs(div.hBound() - div.lBound()); // we say that 1st tick is missing if first tick is father away from its end of the scale // than the last tick is from its end bool isFirstMissing = fabs(firstShift) > fabs(lastShift) ; // if first tick is missing if (isFirstMissing) { // distance between nearest major ticks double tickSize = 0; if (ticks.size() == 1) { // guess the tick size in case of only one visible double tickLog = log10(firstShift); tickLog = tickLog > 0 ? ceil(tickLog) : floor(tickLog); tickSize = pow(10.,tickLog); } else if (ticks.size() > 1) { // take the difference between the two first ticks tickSize = ticks[1] - ticks[0]; } // claculate how much lower bound must be moved to make the missing tick visible double shift = (ticks.front() - tickSize) - from; // if the shift is not very big rescale the axis if (fabs(shift/range) < 0.1) { from += shift; const QwtScaleDiv updatedDiv = axisScaleEngine(QwtPlot::xBottom)->divideScale(from,to,nMajorTicks,nMajorTicks); setAxisScaleDiv(xBottom,updatedDiv); rescaled = true; } } else // last tick is missing { // distance between nearest major ticks double tickSize = 0; if (ticks.size() == 1) { // guess the tick size in case of only one visible double tickLog = log10(lastShift); tickLog = tickLog > 0 ? ceil(tickLog) : floor(tickLog); tickSize = pow(10.,tickLog); } else if (ticks.size() > 1) { // take the difference between the two first ticks tickSize = ticks[1] - ticks[0]; } // claculate how much upper bound must be moved to make the missing tick visible double shift = (ticks.back() + tickSize) - to; // if the shift is not very big rescale the axis if (fabs(shift/range) < 0.1) { to += shift; const QwtScaleDiv updatedDiv = axisScaleEngine(QwtPlot::xBottom)->divideScale(from,to,nMajorTicks,nMajorTicks); setAxisScaleDiv(xBottom,updatedDiv); rescaled = true; } } } if (!rescaled) { setAxisScaleDiv(xBottom,div); } m_zoomer->setZoomBase(); }
void QwtPolarGrid::updateScaleDiv( const QwtScaleDiv &azimuthScaleDiv, const QwtScaleDiv &radialScaleDiv, const QwtDoubleInterval &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; QwtValueList &ticks = ( QwtValueList & )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 QWT_VERSION < 0x050200 if ( ticks.size() > 0 && ticks.first() == sd.lBound() ) #else if ( ticks.size() > 0 && ticks.first() == sd.lowerBound() ) #endif { if ( skipOrigin ) { #if QT_VERSION < 0x040000 ticks.pop_front(); #else ticks.removeFirst(); #endif } else hasOrigin = true; } } if ( testDisplayFlag( HideMaxRadiusLabel ) ) { #if QWT_VERSION < 0x050200 if ( ticks.size() > 0 && ticks.last() == sd.hBound() ) #else if ( ticks.size() > 0 && ticks.last() == sd.upperBound() ) #endif #if QT_VERSION < 0x040000 ticks.pop_back(); #else ticks.removeLast(); #endif } axis.scaleDraw->setScaleDiv( sd ); if ( testDisplayFlag( SmartScaleDraw ) ) { axis.scaleDraw->enableComponent( QwtAbstractScaleDraw::Ticks, !radialGrid.isVisible ); } } } } }
/*! Change the scale division \param sd New scale division */ void QwtAbstractScaleDraw::setScaleDiv(const QwtScaleDiv &sd) { d_data->scldiv = sd; d_data->map.setScaleInterval(sd.lBound(), sd.hBound()); d_data->labelCache.clear(); }