예제 #1
0
int main(int argc, char **argv)
{
    QApplication a(argc, argv);

    QwtPlot plot;
    plot.setCanvasBackground(QColor(Qt::white));
    plot.setTitle("Histogram");

    QwtPlotGrid *grid = new QwtPlotGrid;
    grid->enableXMin(true);
    grid->enableYMin(true);
    grid->setMajPen(QPen(Qt::black, 0, Qt::DotLine));
    grid->setMinPen(QPen(Qt::gray, 0 , Qt::DotLine));
    grid->attach(&plot);

    HistogramItem *histogram = new HistogramItem();
    histogram->setColor(Qt::darkCyan);

    const int numValues = 20;

    QwtArray<QwtDoubleInterval> intervals(numValues);
    QwtArray<double> values(numValues);

    double pos = 0.0;
    for ( int i = 0; i < (int)intervals.size(); i++ )
    {
        const int width = 5 + rand() % 15;
        const int value = rand() % 100;

        intervals[i] = QwtDoubleInterval(pos, pos + double(width));
        values[i] = value; 

        pos += width;
    }

    histogram->setData(QwtIntervalData(intervals, values));
    histogram->attach(&plot);

    plot.setAxisScale(QwtPlot::yLeft, 0.0, 100.0);
    plot.setAxisScale(QwtPlot::xBottom, 0.0, pos);
    plot.replot();

#if QT_VERSION < 0x040000
    a.setMainWidget(&plot);
#endif

    plot.resize(600,400);
    plot.show();

    return a.exec(); 
}
예제 #2
0
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;
  }