void QgsHistogramWidget::drawHistogram() { // clear plot mpPlot->detachItems(); //ensure all children get removed mpPlot->setAutoDelete( true ); // Set axis titles if ( !mXAxisTitle.isEmpty() ) mpPlot->setAxisTitle( QwtPlot::xBottom, mXAxisTitle ); if ( !mYAxisTitle.isEmpty() ) mpPlot->setAxisTitle( QwtPlot::yLeft, mYAxisTitle ); mpPlot->setAxisFont( QwtPlot::xBottom, this->font() ); mpPlot->setAxisFont( QwtPlot::yLeft, this->font() ); QFont titleFont = this->font(); titleFont.setBold( true ); QwtText xAxisText = mpPlot->axisTitle( QwtPlot::xBottom ); xAxisText.setFont( titleFont ); mpPlot->setAxisTitle( QwtPlot::xBottom, xAxisText ); QwtText yAxisText = mpPlot->axisTitle( QwtPlot::yLeft ); yAxisText.setFont( titleFont ); mpPlot->setAxisTitle( QwtPlot::yLeft, yAxisText ); mpPlot->setAxisAutoScale( QwtPlot::yLeft ); mpPlot->setAxisAutoScale( QwtPlot::xBottom ); // add a grid QwtPlotGrid *grid = new QwtPlotGrid(); grid->enableX( false ); grid->setPen( mGridPen ); grid->attach( mpPlot ); // make colors list mHistoColors.clear(); Q_FOREACH ( const QgsRendererRange &range, mRanges ) { mHistoColors << ( range.symbol() ? range.symbol()->color() : Qt::black ); } //draw histogram QwtPlotHistogram *plotHistogram = nullptr; plotHistogram = createPlotHistogram( !mRanges.isEmpty() ? mRanges.at( 0 ).label() : QString(), !mRanges.isEmpty() ? QBrush( mHistoColors.at( 0 ) ) : mBrush, !mRanges.isEmpty() ? Qt::NoPen : mPen ); QVector<QwtIntervalSample> dataHisto; int bins = mBinsSpinBox->value(); QList<double> edges = mHistogram.binEdges( bins ); QList<int> counts = mHistogram.counts( bins ); int rangeIndex = 0; int lastValue = 0; for ( int bin = 0; bin < bins; ++bin ) { int binValue = counts.at( bin ); //current bin crosses two graduated ranges, so we split between //two histogram items if ( rangeIndex < mRanges.count() - 1 && edges.at( bin ) > mRanges.at( rangeIndex ).upperValue() ) { rangeIndex++; plotHistogram->setSamples( dataHisto ); plotHistogram->attach( mpPlot ); plotHistogram = createPlotHistogram( mRanges.at( rangeIndex ).label(), mHistoColors.at( rangeIndex ) ); dataHisto.clear(); dataHisto << QwtIntervalSample( lastValue, mRanges.at( rangeIndex - 1 ).upperValue(), edges.at( bin ) ); } double upperEdge = !mRanges.isEmpty() ? qMin( edges.at( bin + 1 ), mRanges.at( rangeIndex ).upperValue() ) : edges.at( bin + 1 ); dataHisto << QwtIntervalSample( binValue, edges.at( bin ), upperEdge ); lastValue = binValue; } plotHistogram->setSamples( dataHisto ); plotHistogram->attach( mpPlot ); mRangeMarkers.clear(); Q_FOREACH ( const QgsRendererRange &range, mRanges ) { QwtPlotMarker *rangeMarker = new QwtPlotMarker(); rangeMarker->attach( mpPlot ); rangeMarker->setLineStyle( QwtPlotMarker::VLine ); rangeMarker->setXValue( range.upperValue() ); rangeMarker->setLabel( QString::number( range.upperValue() ) ); rangeMarker->setLabelOrientation( Qt::Vertical ); rangeMarker->setLabelAlignment( Qt::AlignLeft | Qt::AlignTop ); rangeMarker->show(); mRangeMarkers << rangeMarker; }
void QgsHistogramWidget::drawHistogram() { if ( !mVectorLayer || mSourceFieldExp.isEmpty() ) return; QApplication::setOverrideCursor( Qt::WaitCursor ); if ( mValues.empty() ) { bool ok; mValues = mVectorLayer->getDoubleValues( mSourceFieldExp, ok ); if ( ! ok ) { QApplication::restoreOverrideCursor(); return; } qSort( mValues.begin(), mValues.end() ); mHistogram.setValues( mValues ); mBinsSpinBox->blockSignals( true ); mBinsSpinBox->setValue( qMax( mHistogram.optimalNumberBins(), 30 ) ); mBinsSpinBox->blockSignals( false ); mStats.setStatistics( QgsStatisticalSummary::StDev ); mStats.calculate( mValues ); } // clear plot mpPlot->detachItems(); //ensure all children get removed mpPlot->setAutoDelete( true ); // Set axis titles mpPlot->setAxisTitle( QwtPlot::xBottom, QObject::tr( "Value" ) ); mpPlot->setAxisTitle( QwtPlot::yLeft, QObject::tr( "Count" ) ); mpPlot->setAxisAutoScale( QwtPlot::yLeft ); mpPlot->setAxisAutoScale( QwtPlot::xBottom ); // add a grid QwtPlotGrid * grid = new QwtPlotGrid(); grid->enableX( false ); grid->setPen( mGridPen ); grid->attach( mpPlot ); // make colors list mHistoColors.clear(); foreach ( QgsRendererRangeV2 range, mRanges ) { mHistoColors << ( range.symbol() ? range.symbol()->color() : Qt::black ); } //draw histogram #if defined(QWT_VERSION) && QWT_VERSION>=0x060000 QwtPlotHistogram * plotHistogram = 0; plotHistogram = createPlotHistogram( mRanges.count() > 0 ? mRanges.at( 0 ).label() : QString(), mRanges.count() > 0 ? QBrush( mHistoColors.at( 0 ) ) : mBrush, mRanges.count() > 0 ? Qt::NoPen : mPen ); #else HistogramItem *plotHistogramItem = 0; plotHistogramItem = createHistoItem( mRanges.count() > 0 ? mRanges.at( 0 ).label() : QString(), mRanges.count() > 0 ? QBrush( mHistoColors.at( 0 ) ) : mBrush, mRanges.count() > 0 ? Qt::NoPen : mPen ); #endif #if defined(QWT_VERSION) && QWT_VERSION>=0x060000 QVector<QwtIntervalSample> dataHisto; #else // we safely assume that QT>=4.0 (min version is 4.7), therefore QwtArray is a QVector, so don't set size here QwtArray<QwtDoubleInterval> intervalsHisto; QwtArray<double> valuesHisto; #endif int bins = mBinsSpinBox->value(); QList<double> edges = mHistogram.binEdges( bins ); QList<int> counts = mHistogram.counts( bins ); int rangeIndex = 0; int lastValue = 0; for ( int bin = 0; bin < bins; ++bin ) { int binValue = counts.at( bin ); //current bin crosses two graduated ranges, so we split between //two histogram items if ( rangeIndex < mRanges.count() - 1 && edges.at( bin ) > mRanges.at( rangeIndex ).upperValue() ) { rangeIndex++; #if defined(QWT_VERSION) && QWT_VERSION>=0x060000 plotHistogram->setSamples( dataHisto ); plotHistogram->attach( mpPlot ); plotHistogram = createPlotHistogram( mRanges.at( rangeIndex ).label(), mHistoColors.at( rangeIndex ) ); dataHisto.clear(); dataHisto << QwtIntervalSample( lastValue, mRanges.at( rangeIndex - 1 ).upperValue(), edges.at( bin ) ); #else plotHistogramItem->setData( QwtIntervalData( intervalsHisto, valuesHisto ) ); plotHistogramItem->attach( mpPlot ); plotHistogramItem = createHistoItem( mRanges.at( rangeIndex ).label(), mHistoColors.at( rangeIndex ) ); intervalsHisto.clear(); valuesHisto.clear(); intervalsHisto.append( QwtDoubleInterval( mRanges.at( rangeIndex - 1 ).upperValue(), edges.at( bin ) ) ); valuesHisto.append( lastValue ); #endif } double upperEdge = mRanges.count() > 0 ? qMin( edges.at( bin + 1 ), mRanges.at( rangeIndex ).upperValue() ) : edges.at( bin + 1 ); #if defined(QWT_VERSION) && QWT_VERSION>=0x060000 dataHisto << QwtIntervalSample( binValue, edges.at( bin ), upperEdge ); #else intervalsHisto.append( QwtDoubleInterval( edges.at( bin ), upperEdge ) ); valuesHisto.append( double( binValue ) ); #endif lastValue = binValue; } #if defined(QWT_VERSION) && QWT_VERSION>=0x060000 plotHistogram->setSamples( dataHisto ); plotHistogram->attach( mpPlot ); #else plotHistogramItem->setData( QwtIntervalData( intervalsHisto, valuesHisto ) ); plotHistogramItem->attach( mpPlot ); #endif mRangeMarkers.clear(); foreach ( QgsRendererRangeV2 range, mRanges ) { QwtPlotMarker* rangeMarker = new QwtPlotMarker(); rangeMarker->attach( mpPlot ); rangeMarker->setLineStyle( QwtPlotMarker::VLine ); rangeMarker->setXValue( range.upperValue() ); rangeMarker->setLabel( QString::number( range.upperValue() ) ); rangeMarker->setLabelOrientation( Qt::Vertical ); rangeMarker->setLabelAlignment( Qt::AlignLeft | Qt::AlignTop ); rangeMarker->show(); mRangeMarkers << rangeMarker; }