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>
45 , mVectorLayer( layer )
46 , mSourceFieldExp( fieldOrExp )
47 , mXAxisTitle( QObject::tr(
"Value" ) )
48 , mYAxisTitle( QObject::tr(
"Count" ) )
55 QFrame *plotCanvasFrame =
dynamic_cast<QFrame *
>( mpPlot->canvas() );
56 if ( plotCanvasFrame )
57 plotCanvasFrame->setFrameStyle( QFrame::NoFrame );
60 mMeanCheckBox->setChecked( settings.
value( QStringLiteral(
"HistogramWidget/showMean" ),
false ).toBool() );
61 mStdevCheckBox->setChecked( settings.
value( QStringLiteral(
"HistogramWidget/showStdev" ),
false ).toBool() );
63 connect( mBinsSpinBox,
static_cast < void ( QSpinBox::* )(
int )
> ( &QSpinBox::valueChanged ),
this, &
QgsHistogramWidget::refresh );
68 mGridPen = QPen( QColor( 0, 0, 0, 40 ) );
69 mMeanPen = QPen( QColor( 10, 10, 10, 220 ) );
70 mMeanPen.setStyle( Qt::DashLine );
71 mStdevPen = QPen( QColor( 30, 30, 30, 200 ) );
72 mStdevPen.setStyle( Qt::DashLine );
74 if (
layer && !mSourceFieldExp.isEmpty() )
83 settings.
setValue( QStringLiteral(
"HistogramWidget/showMean" ), mMeanCheckBox->isChecked() );
84 settings.
setValue( QStringLiteral(
"HistogramWidget/showStdev" ), mStdevCheckBox->isChecked() );
102 if ( !mVectorLayer || mSourceFieldExp.isEmpty() )
105 QApplication::setOverrideCursor( Qt::WaitCursor );
112 QApplication::restoreOverrideCursor();
117 std::sort( mValues.begin(), mValues.end() );
119 mBinsSpinBox->blockSignals(
true );
121 mBinsSpinBox->blockSignals(
false );
126 mpPlot->setEnabled(
true );
127 mMeanCheckBox->setEnabled(
true );
128 mStdevCheckBox->setEnabled(
true );
129 mBinsSpinBox->setEnabled(
true );
131 QApplication::restoreOverrideCursor();
144 if (
layer == mVectorLayer )
147 mVectorLayer =
layer;
151 void QgsHistogramWidget::clearHistogram()
157 mpPlot->setEnabled(
false );
158 mMeanCheckBox->setEnabled(
false );
159 mStdevCheckBox->setEnabled(
false );
160 mBinsSpinBox->setEnabled(
false );
165 if ( fieldOrExp == mSourceFieldExp )
168 mSourceFieldExp = fieldOrExp;
175 mpPlot->detachItems();
178 mpPlot->setAutoDelete(
true );
180 if ( !mXAxisTitle.isEmpty() )
181 mpPlot->setAxisTitle( QwtPlot::xBottom, mXAxisTitle );
182 if ( !mYAxisTitle.isEmpty() )
183 mpPlot->setAxisTitle( QwtPlot::yLeft, mYAxisTitle );
184 mpPlot->setAxisFont( QwtPlot::xBottom, this->font() );
185 mpPlot->setAxisFont( QwtPlot::yLeft, this->font() );
186 QFont titleFont = this->font();
187 titleFont.setBold(
true );
188 QwtText xAxisText = mpPlot->axisTitle( QwtPlot::xBottom );
189 xAxisText.setFont( titleFont );
190 mpPlot->setAxisTitle( QwtPlot::xBottom, xAxisText );
191 QwtText yAxisText = mpPlot->axisTitle( QwtPlot::yLeft );
192 yAxisText.setFont( titleFont );
193 mpPlot->setAxisTitle( QwtPlot::yLeft, yAxisText );
194 mpPlot->setAxisAutoScale( QwtPlot::yLeft );
195 mpPlot->setAxisAutoScale( QwtPlot::xBottom );
198 QwtPlotGrid *grid =
new QwtPlotGrid();
199 grid->enableX(
false );
200 grid->setPen( mGridPen );
201 grid->attach( mpPlot );
204 mHistoColors.clear();
207 mHistoColors << ( range.symbol() ? range.symbol()->color() : Qt::black );
211 QwtPlotHistogram *plotHistogram =
nullptr;
212 plotHistogram = createPlotHistogram( !
mRanges.isEmpty() ?
mRanges.at( 0 ).label() : QString(),
213 !
mRanges.isEmpty() ? QBrush( mHistoColors.at( 0 ) ) : mBrush,
214 !
mRanges.isEmpty() ? Qt::NoPen : mPen );
215 QVector<QwtIntervalSample> dataHisto;
217 int bins = mBinsSpinBox->value();
218 QList<double> edges = mHistogram.
binEdges( bins );
219 QList<int> counts = mHistogram.
counts( bins );
224 for (
int bin = 0; bin < bins; ++bin )
226 int binValue = counts.at( bin );
230 if ( rangeIndex <
mRanges.count() - 1 && edges.at( bin ) >
mRanges.at( rangeIndex ).upperValue() )
233 plotHistogram->setSamples( dataHisto );
234 plotHistogram->attach( mpPlot );
235 plotHistogram = createPlotHistogram(
mRanges.at( rangeIndex ).label(), mHistoColors.at( rangeIndex ) );
237 dataHisto << QwtIntervalSample( lastValue,
mRanges.at( rangeIndex - 1 ).upperValue(), edges.at( bin ) );
240 double upperEdge = !
mRanges.isEmpty() ? std::min( edges.at( bin + 1 ),
mRanges.at( rangeIndex ).upperValue() )
241 : edges.at( bin + 1 );
243 dataHisto << QwtIntervalSample( binValue, edges.at( bin ), upperEdge );
245 lastValue = binValue;
248 plotHistogram->setSamples( dataHisto );
249 plotHistogram->attach( mpPlot );
254 QwtPlotMarker *rangeMarker =
new QwtPlotMarker();
255 rangeMarker->attach( mpPlot );
256 rangeMarker->setLineStyle( QwtPlotMarker::VLine );
257 rangeMarker->setXValue( range.upperValue() );
258 rangeMarker->setLabel( QLocale().toString( range.upperValue() ) );
259 rangeMarker->setLabelOrientation( Qt::Vertical );
260 rangeMarker->setLabelAlignment( Qt::AlignLeft | Qt::AlignTop );
265 if ( mMeanCheckBox->isChecked() )
267 QwtPlotMarker *meanMarker =
new QwtPlotMarker();
268 meanMarker->attach( mpPlot );
269 meanMarker->setLineStyle( QwtPlotMarker::VLine );
270 meanMarker->setLinePen( mMeanPen );
271 meanMarker->setXValue( mStats.
mean() );
272 meanMarker->setLabel( QString( QChar( 956 ) ) );
273 meanMarker->setLabelAlignment( Qt::AlignLeft | Qt::AlignTop );
277 if ( mStdevCheckBox->isChecked() )
279 QwtPlotMarker *stdev1Marker =
new QwtPlotMarker();
280 stdev1Marker->attach( mpPlot );
281 stdev1Marker->setLineStyle( QwtPlotMarker::VLine );
282 stdev1Marker->setLinePen( mStdevPen );
283 stdev1Marker->setXValue( mStats.
mean() - mStats.
stDev() );
284 stdev1Marker->setLabel( QString( QChar( 963 ) ) );
285 stdev1Marker->setLabelAlignment( Qt::AlignLeft | Qt::AlignTop );
286 stdev1Marker->show();
288 QwtPlotMarker *stdev2Marker =
new QwtPlotMarker();
289 stdev2Marker->attach( mpPlot );
290 stdev2Marker->setLineStyle( QwtPlotMarker::VLine );
291 stdev2Marker->setLinePen( mStdevPen );
292 stdev2Marker->setXValue( mStats.
mean() + mStats.
stDev() );
293 stdev2Marker->setLabel( QString( QChar( 963 ) ) );
294 stdev2Marker->setLabelAlignment( Qt::AlignLeft | Qt::AlignTop );
295 stdev2Marker->show();
298 mpPlot->setEnabled(
true );
302 QwtPlotHistogram *QgsHistogramWidget::createPlotHistogram(
const QString &title,
const QBrush &brush,
const QPen &pen )
const
304 QwtPlotHistogram *histogram =
new QwtPlotHistogram( title );
305 histogram->setBrush(
brush );
306 if (
pen != Qt::NoPen )
308 histogram->setPen(
pen );
310 else if (
brush.color().lightness() > 200 )
313 p.setColor(
brush.color().darker( 150 ) );
315 p.setCosmetic(
true );
316 histogram->setPen( p );
320 histogram->setPen( QPen( Qt::NoPen ) );