23 #include "qgssettings.h" 
   26 #include <QMouseEvent> 
   29 #include <qwt_global.h> 
   30 #include <qwt_plot_canvas.h> 
   32 #include <qwt_plot_curve.h> 
   33 #include <qwt_plot_grid.h> 
   34 #include <qwt_plot_marker.h> 
   35 #include <qwt_plot_picker.h> 
   36 #include <qwt_picker_machine.h> 
   37 #include <qwt_plot_layout.h> 
   38 #include <qwt_plot_renderer.h> 
   39 #include <qwt_plot_histogram.h> 
   44   , mVectorLayer( layer )
 
   45   , mSourceFieldExp( fieldOrExp )
 
   46   , mXAxisTitle( QObject::tr( 
"Value" ) )
 
   47   , mYAxisTitle( QObject::tr( 
"Count" ) )
 
   54   QFrame *plotCanvasFrame = 
dynamic_cast<QFrame *
>( mpPlot->canvas() );
 
   55   if ( plotCanvasFrame )
 
   56     plotCanvasFrame->setFrameStyle( QFrame::NoFrame );
 
   59   mMeanCheckBox->setChecked( settings.value( QStringLiteral( 
"HistogramWidget/showMean" ), 
false ).toBool() );
 
   60   mStdevCheckBox->setChecked( settings.value( QStringLiteral( 
"HistogramWidget/showStdev" ), 
false ).toBool() );
 
   62   connect( mBinsSpinBox, 
static_cast < void ( QSpinBox::* )( 
int ) 
> ( &QSpinBox::valueChanged ), 
this, &
QgsHistogramWidget::refresh );
 
   67   mGridPen = QPen( QColor( 0, 0, 0, 40 ) );
 
   68   mMeanPen = QPen( QColor( 10, 10, 10, 220 ) );
 
   69   mMeanPen.setStyle( Qt::DashLine );
 
   70   mStdevPen = QPen( QColor( 30, 30, 30, 200 ) );
 
   71   mStdevPen.setStyle( Qt::DashLine );
 
   73   if ( 
layer && !mSourceFieldExp.isEmpty() )
 
   82   settings.setValue( QStringLiteral( 
"HistogramWidget/showMean" ), mMeanCheckBox->isChecked() );
 
   83   settings.setValue( QStringLiteral( 
"HistogramWidget/showStdev" ), mStdevCheckBox->isChecked() );
 
  101   if ( !mVectorLayer || mSourceFieldExp.isEmpty() )
 
  104   QApplication::setOverrideCursor( Qt::WaitCursor );
 
  111     QApplication::restoreOverrideCursor();
 
  116   std::sort( mValues.begin(), mValues.end() );
 
  118   mBinsSpinBox->blockSignals( 
true );
 
  120   mBinsSpinBox->blockSignals( 
false );
 
  125   mpPlot->setEnabled( 
true );
 
  126   mMeanCheckBox->setEnabled( 
true );
 
  127   mStdevCheckBox->setEnabled( 
true );
 
  128   mBinsSpinBox->setEnabled( 
true );
 
  130   QApplication::restoreOverrideCursor();
 
  143   if ( 
layer == mVectorLayer )
 
  146   mVectorLayer = 
layer;
 
  150 void QgsHistogramWidget::clearHistogram()
 
  156   mpPlot->setEnabled( 
false );
 
  157   mMeanCheckBox->setEnabled( 
false );
 
  158   mStdevCheckBox->setEnabled( 
false );
 
  159   mBinsSpinBox->setEnabled( 
false );
 
  164   if ( fieldOrExp == mSourceFieldExp )
 
  167   mSourceFieldExp = fieldOrExp;
 
  174   mpPlot->detachItems();
 
  177   mpPlot->setAutoDelete( 
true );
 
  179   if ( !mXAxisTitle.isEmpty() )
 
  180     mpPlot->setAxisTitle( QwtPlot::xBottom, mXAxisTitle );
 
  181   if ( !mYAxisTitle.isEmpty() )
 
  182     mpPlot->setAxisTitle( QwtPlot::yLeft, mYAxisTitle );
 
  183   mpPlot->setAxisFont( QwtPlot::xBottom, this->font() );
 
  184   mpPlot->setAxisFont( QwtPlot::yLeft, this->font() );
 
  185   QFont titleFont = this->font();
 
  186   titleFont.setBold( 
true );
 
  187   QwtText xAxisText = mpPlot->axisTitle( QwtPlot::xBottom );
 
  188   xAxisText.setFont( titleFont );
 
  189   mpPlot->setAxisTitle( QwtPlot::xBottom, xAxisText );
 
  190   QwtText yAxisText = mpPlot->axisTitle( QwtPlot::yLeft );
 
  191   yAxisText.setFont( titleFont );
 
  192   mpPlot->setAxisTitle( QwtPlot::yLeft, yAxisText );
 
  193   mpPlot->setAxisAutoScale( QwtPlot::yLeft );
 
  194   mpPlot->setAxisAutoScale( QwtPlot::xBottom );
 
  197   QwtPlotGrid *grid = 
new QwtPlotGrid();
 
  198   grid->enableX( 
false );
 
  199   grid->setPen( mGridPen );
 
  200   grid->attach( mpPlot );
 
  203   mHistoColors.clear();
 
  206     mHistoColors << ( range.symbol() ? range.symbol()->color() : Qt::black );
 
  210   QwtPlotHistogram *plotHistogram = 
nullptr;
 
  211   plotHistogram = createPlotHistogram( !
mRanges.isEmpty() ? 
mRanges.at( 0 ).label() : QString(),
 
  212                                        !
mRanges.isEmpty() ? QBrush( mHistoColors.at( 0 ) ) : mBrush,
 
  213                                        !
mRanges.isEmpty() ? Qt::NoPen : mPen );
 
  214   QVector<QwtIntervalSample> dataHisto;
 
  216   int bins = mBinsSpinBox->value();
 
  217   QList<double> edges = mHistogram.
binEdges( bins );
 
  218   QList<int> counts = mHistogram.
counts( bins );
 
  223   for ( 
int bin = 0; bin < bins; ++bin )
 
  225     int binValue = counts.at( bin );
 
  229     if ( rangeIndex < 
mRanges.count() - 1 && edges.at( bin ) > 
mRanges.at( rangeIndex ).upperValue() )
 
  232       plotHistogram->setSamples( dataHisto );
 
  233       plotHistogram->attach( mpPlot );
 
  234       plotHistogram = createPlotHistogram( 
mRanges.at( rangeIndex ).label(), mHistoColors.at( rangeIndex ) );
 
  236       dataHisto << QwtIntervalSample( lastValue, 
mRanges.at( rangeIndex - 1 ).upperValue(), edges.at( bin ) );
 
  239     double upperEdge = !
mRanges.isEmpty() ? std::min( edges.at( bin + 1 ), 
mRanges.at( rangeIndex ).upperValue() )
 
  240                        : edges.at( bin + 1 );
 
  242     dataHisto << QwtIntervalSample( binValue, edges.at( bin ), upperEdge );
 
  244     lastValue = binValue;
 
  247   plotHistogram->setSamples( dataHisto );
 
  248   plotHistogram->attach( mpPlot );
 
  253     QwtPlotMarker *rangeMarker = 
new QwtPlotMarker();
 
  254     rangeMarker->attach( mpPlot );
 
  255     rangeMarker->setLineStyle( QwtPlotMarker::VLine );
 
  256     rangeMarker->setXValue( range.upperValue() );
 
  257     rangeMarker->setLabel( QString::number( range.upperValue() ) );
 
  258     rangeMarker->setLabelOrientation( Qt::Vertical );
 
  259     rangeMarker->setLabelAlignment( Qt::AlignLeft | Qt::AlignTop );
 
  264   if ( mMeanCheckBox->isChecked() )
 
  266     QwtPlotMarker *meanMarker = 
new QwtPlotMarker();
 
  267     meanMarker->attach( mpPlot );
 
  268     meanMarker->setLineStyle( QwtPlotMarker::VLine );
 
  269     meanMarker->setLinePen( mMeanPen );
 
  270     meanMarker->setXValue( mStats.
mean() );
 
  271     meanMarker->setLabel( QString( QChar( 956 ) ) );
 
  272     meanMarker->setLabelAlignment( Qt::AlignLeft | Qt::AlignTop );
 
  276   if ( mStdevCheckBox->isChecked() )
 
  278     QwtPlotMarker *stdev1Marker = 
new QwtPlotMarker();
 
  279     stdev1Marker->attach( mpPlot );
 
  280     stdev1Marker->setLineStyle( QwtPlotMarker::VLine );
 
  281     stdev1Marker->setLinePen( mStdevPen );
 
  282     stdev1Marker->setXValue( mStats.
mean() - mStats.
stDev() );
 
  283     stdev1Marker->setLabel( QString( QChar( 963 ) ) );
 
  284     stdev1Marker->setLabelAlignment( Qt::AlignLeft | Qt::AlignTop );
 
  285     stdev1Marker->show();
 
  287     QwtPlotMarker *stdev2Marker = 
new QwtPlotMarker();
 
  288     stdev2Marker->attach( mpPlot );
 
  289     stdev2Marker->setLineStyle( QwtPlotMarker::VLine );
 
  290     stdev2Marker->setLinePen( mStdevPen );
 
  291     stdev2Marker->setXValue( mStats.
mean() + mStats.
stDev() );
 
  292     stdev2Marker->setLabel( QString( QChar( 963 ) ) );
 
  293     stdev2Marker->setLabelAlignment( Qt::AlignLeft | Qt::AlignTop );
 
  294     stdev2Marker->show();
 
  297   mpPlot->setEnabled( 
true );
 
  301 QwtPlotHistogram *QgsHistogramWidget::createPlotHistogram( 
const QString &title, 
const QBrush &brush, 
const QPen &pen )
 const 
  303   QwtPlotHistogram *histogram = 
new QwtPlotHistogram( title );
 
  304   histogram->setBrush( 
brush );
 
  305   if ( 
pen != Qt::NoPen )
 
  307     histogram->setPen( 
pen );
 
  309   else if ( 
brush.color().lightness() > 200 )
 
  312     p.setColor( 
brush.color().darker( 150 ) );
 
  314     p.setCosmetic( 
true );
 
  315     histogram->setPen( p );
 
  319     histogram->setPen( QPen( Qt::NoPen ) );
 
QList< int > counts(int bins) const
Returns the calculated list of the counts for the histogram bins.
int optimalNumberBins() const
Returns the optimal number of bins for the source values, calculated using the Freedman-Diaconis rule...
QList< double > binEdges(int bins) const
Returns a list of edges for the histogram for a specified number of bins.
void setValues(const QList< double > &values)
Assigns numeric source values for the histogram.
double lowerValue() const
void calculate(const QList< double > &values)
Calculates summary statistics for a list of values.
@ StDev
Standard deviation of values.
double mean() const
Returns calculated mean of values.
double stDev() const
Returns population standard deviation.
void setStatistics(QgsStatisticalSummary::Statistics stats)
Sets flags which specify which statistics will be calculated.
static QList< double > getDoubleValues(const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly=false, int *nullCount=nullptr, QgsFeedback *feedback=nullptr)
Fetches all double values from a specified field name or expression.
Represents a vector layer which manages a vector based data sets.
QList< QgsRendererRange > QgsRangeList