Проблема с QwtPlotZoomer с логарифмическими c весами - PullRequest
0 голосов
/ 06 апреля 2020

У меня проблема при использовании QwtPlotZoomer с графиком в логарифмических c масштабах. Когда я увеличиваю график, нижняя граница оси y становится 1E-100, тогда как минимальное значение из моих кривых на графике составляет около 1E-25. Я не понимаю почему. Я был бы очень признателен за проверку моего кода, пожалуйста, чтобы помочь мне с этой проблемой, или любое предложение. Пожалуйста, найдите ниже мой код:

#include "graphplot.h"

#include <qwt_abstract_scale_draw.h>

GraphPlot::GraphPlot( QWidget *parent ):
    QwtPlot( parent )
{
    initialize();

    m_legend = new QwtLegend;
    insertLegend( m_legend, QwtPlot::TopLegend);
    m_legend->setDefaultItemMode( QwtLegendData::Checkable );
    connect( m_legend, SIGNAL( checked( const QVariant &, bool, int ) ), SLOT( showItem( const QVariant &, bool ) ) );
}

void GraphPlot::initialize()
{
    QwtPlotCanvas *canvas = new QwtPlotCanvas;
    canvas->setPalette( Qt::white );
    canvas->setBorderRadius( 0 );
    setCanvas( canvas );

    setAxisScaleEngine( QwtPlot::yLeft, new QwtLogScaleEngine() );
    setAxisScaleEngine( QwtPlot::xBottom, new QwtLogScaleEngine() );
//    setAxisScale(QwtPlot::xBottom,1.0e-02,10000.0);
//    setAxisScale(QwtPlot::yLeft,1.0e-24,2.0);

/*    setAxisMaxMajor(QwtPlot::yLeft, 30);
    setAxisMaxMinor(QwtPlot::yLeft, 10);
    setAxisMaxMajor(QwtPlot::xBottom, 30);
    setAxisMaxMinor(QwtPlot::xBottom, 10);
*/
    QwtPlotGrid *grid = new QwtPlotGrid();
    grid->enableXMin( true );
    grid->enableX( true );
    grid->enableYMin( true );
    grid->enableY( true );
    grid->setMajorPen( Qt::black, 0, Qt::SolidLine );
    grid->setMinorPen( Qt::gray, 0 , Qt::DotLine );
    grid->attach( this );

    QwtPlotPanner *panner = new QwtPlotPanner( canvas );
    panner->setMouseButton( Qt::MidButton );
    m_zoom_compteur = 0;
}

void GraphPlot::addCurve(const QList<double>& x, const QList<double>& y, const QString& dataName)
{
    QwtPlotCurve *curve = new QwtPlotCurve;
    curve->setTitle( dataName );
    curve->setPen( Qt::blue, 1.5 );
    curve->setRenderHint( QwtPlotItem::RenderAntialiased, true );
    curve->setStyle(QwtPlotCurve::Lines);

    double min = *std::minmax_element(y.begin(), y.end()).first;
    curve->setBaseline(min);

    curve->setSymbol( new QwtSymbol( QwtSymbol::Ellipse, QBrush( Qt::yellow ), QPen( Qt::black, 1.5 ), QSize( 1, 1 ) ) );
    setAxisAutoScale(QwtPlot::yLeft,true);
    setAxisAutoScale(QwtPlot::xBottom,true);

    QPolygonF points;
    for(QList<double>::size_type i=0; i<x.size();i++)
    {
        if (y[i] !=0 ) points << QPointF( x[i], y[i] );
    }
    curve->setSamples( points );
    curve->attach( this );
}

void GraphPlot::setLegend()
{
    QwtPlotItemList items = itemList( QwtPlotItem::Rtti_PlotCurve );
    for ( int i = 0; i < items.size(); i++ )
    {
        items[i]->setVisible( true );
        const QVariant itemInfo = itemToInfo( items[i] );
        QwtLegendLabel *legendLabel;
        legendLabel = qobject_cast<QwtLegendLabel *>( m_legend->legendWidget( itemInfo ) );
        legendLabel->setChecked( true );
    }
    enableZoomer();
}

void GraphPlot::showItem( const QVariant &itemInfo, bool on )
{
    QwtPlotItem *plotItem = infoToItem( itemInfo );
    if ( plotItem )
    {
        plotItem->setVisible( on );
    }
    setAxisAutoScale(QwtPlot::yLeft,true);
    setAxisAutoScale(QwtPlot::xBottom,true);
    enableZoomer();
}

void GraphPlot::chooseScale(const bool& a)
{
    setAxisAutoScale(QwtPlot::yLeft,true);
    setAxisAutoScale(QwtPlot::xBottom,true);
    if(a)
    {
        setAxisScaleEngine( QwtPlot::yLeft, new QwtLogScaleEngine() );
        setAxisScaleEngine( QwtPlot::xBottom, new QwtLogScaleEngine() );
    }
    else{
        setAxisScaleEngine( QwtPlot::yLeft, new QwtLinearScaleEngine() );
        setAxisScaleEngine( QwtPlot::xBottom, new QwtLinearScaleEngine() );
    }
    enableZoomer();
}

void GraphPlot::enableZoomer()
{
    if (m_zoom_compteur != 0) delete m_zoomer;
    m_zoom_compteur++;
    m_zoomer = new MyZoomer( canvas() );
    m_zoomer->setMousePattern( QwtEventPattern::MouseSelect2, Qt::RightButton, Qt::ControlModifier );
    m_zoomer->setMousePattern( QwtEventPattern::MouseSelect3, Qt::RightButton );
}

Вот файл H

#ifndef GRAPHPLOT_H
#define GRAPHPLOT_H

#include <qwt_abstract_scale_draw.h>
#include <qwt_plot.h>
#include <qwt_legend.h>
#include <qwt_plot_grid.h>
#include <qwt_symbol.h>
#include <qwt_plot_curve.h>
#include <qwt_scale_engine.h>
#include <qwt_plot_canvas.h>
#include <qwt_plot_zoomer.h>
#include <qwt_legend_label.h>
#include <qwt_plot_renderer.h>
#include <qwt_plot_panner.h>
#include <qwt_compat.h>

class MyZoomer: public QwtPlotZoomer
{
    Q_OBJECT
public:
    MyZoomer( QWidget *canvas ):
        QwtPlotZoomer( canvas )
    {
        setTrackerMode( AlwaysOn );
    }

    virtual QwtText trackerTextF( const QPointF &pos ) const
    {
        QColor bg( Qt::black );
        QColor font( Qt::white );
        bg.setAlpha( 200 );
        QwtText text =  QString::number(pos.x()) + "  " + QString::number(pos.y());
        text.setColor(font);
        text.setBackgroundBrush( QBrush( bg ) );
        return text;
    }

};


class GraphPlot: public QwtPlot
{
    Q_OBJECT

public:
    GraphPlot( QWidget *parent );
    void addCurve(const QList<double>&, const QList<double>&, const QString&);
    void setLegend();
    void initialize();

private slots:
    void showItem( const QVariant &, bool );

public slots:
    void chooseScale(const bool&);

private:
    void setupWheelZooming();
    MyZoomer *m_zoomer;
    QwtLegend *m_legend;
    void enableZoomer();
    int m_zoom_compteur;
};


#endif // GRAPHPLOT_H

1 Ответ

0 голосов
/ 06 апреля 2020

Я только что перегрузил QwtPlotZoomer :: minZoomSize (), и это решило проблему

QSizeF minZoomSize() const
{
    return QSizeF( 1e-30, 1e-30);
}
...