00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "qwt_plot_barchart.h"
00011 #include "qwt_scale_map.h"
00012 #include "qwt_column_symbol.h"
00013 #include "qwt_painter.h"
00014 #include <qpainter.h>
00015
00016 class QwtPlotBarChart::PrivateData
00017 {
00018 public:
00019 PrivateData():
00020 symbol( NULL ),
00021 legendMode( QwtPlotBarChart::LegendChartTitle )
00022 {
00023 }
00024
00025 ~PrivateData()
00026 {
00027 delete symbol;
00028 }
00029
00030 QwtColumnSymbol *symbol;
00031 QwtPlotBarChart::LegendMode legendMode;
00032 };
00033
00038 QwtPlotBarChart::QwtPlotBarChart( const QwtText &title ):
00039 QwtPlotAbstractBarChart( title )
00040 {
00041 init();
00042 }
00043
00048 QwtPlotBarChart::QwtPlotBarChart( const QString &title ):
00049 QwtPlotAbstractBarChart( QwtText( title ) )
00050 {
00051 init();
00052 }
00053
00055 QwtPlotBarChart::~QwtPlotBarChart()
00056 {
00057 delete d_data;
00058 }
00059
00060 void QwtPlotBarChart::init()
00061 {
00062 d_data = new PrivateData;
00063 setData( new QwtPointSeriesData() );
00064 }
00065
00067 int QwtPlotBarChart::rtti() const
00068 {
00069 return QwtPlotItem::Rtti_PlotBarChart;
00070 }
00071
00079 void QwtPlotBarChart::setSamples(
00080 const QVector<QPointF> &samples )
00081 {
00082 setData( new QwtPointSeriesData( samples ) );
00083 }
00084
00094 void QwtPlotBarChart::setSamples(
00095 const QVector<double> &samples )
00096 {
00097 QVector<QPointF> points;
00098 for ( int i = 0; i < samples.size(); i++ )
00099 points += QPointF( i, samples[ i ] );
00100
00101 setData( new QwtPointSeriesData( points ) );
00102 }
00103
00114 void QwtPlotBarChart::setSamples( QwtSeriesData<QPointF> *data )
00115 {
00116 setData( data );
00117 }
00118
00129 void QwtPlotBarChart::setSymbol( QwtColumnSymbol *symbol )
00130 {
00131 if ( symbol != d_data->symbol )
00132 {
00133 delete d_data->symbol;
00134 d_data->symbol = symbol;
00135
00136 legendChanged();
00137 itemChanged();
00138 }
00139 }
00140
00145 const QwtColumnSymbol *QwtPlotBarChart::symbol() const
00146 {
00147 return d_data->symbol;
00148 }
00149
00159 void QwtPlotBarChart::setLegendMode( LegendMode mode )
00160 {
00161 if ( mode != d_data->legendMode )
00162 {
00163 d_data->legendMode = mode;
00164 legendChanged();
00165 }
00166 }
00167
00172 QwtPlotBarChart::LegendMode QwtPlotBarChart::legendMode() const
00173 {
00174 return d_data->legendMode;
00175 }
00176
00181 QRectF QwtPlotBarChart::boundingRect() const
00182 {
00183 const size_t numSamples = dataSize();
00184 if ( numSamples == 0 )
00185 return QwtPlotSeriesItem::boundingRect();
00186
00187 QRectF rect = QwtPlotSeriesItem::boundingRect();
00188 if ( rect.height() >= 0 )
00189 {
00190 const double baseLine = baseline();
00191
00192 if ( rect.bottom() < baseLine )
00193 rect.setBottom( baseLine );
00194
00195 if ( rect.top() > baseLine )
00196 rect.setTop( baseLine );
00197 }
00198
00199 if ( orientation() == Qt::Horizontal )
00200 rect.setRect( rect.y(), rect.x(), rect.height(), rect.width() );
00201
00202 return rect;
00203 }
00204
00218 void QwtPlotBarChart::drawSeries( QPainter *painter,
00219 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
00220 const QRectF &canvasRect, int from, int to ) const
00221 {
00222 if ( to < 0 )
00223 to = dataSize() - 1;
00224
00225 if ( from < 0 )
00226 from = 0;
00227
00228 if ( from > to )
00229 return;
00230
00231
00232 const QRectF br = data()->boundingRect();
00233 const QwtInterval interval( br.left(), br.right() );
00234
00235 painter->save();
00236
00237 for ( int i = from; i <= to; i++ )
00238 {
00239 drawSample( painter, xMap, yMap,
00240 canvasRect, interval, i, sample( i ) );
00241 }
00242
00243 painter->restore();
00244 }
00245
00257 QwtColumnRect QwtPlotBarChart::columnRect(
00258 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
00259 const QRectF &canvasRect, const QwtInterval &boundingInterval,
00260 const QPointF &sample ) const
00261 {
00262 QwtColumnRect barRect;
00263
00264 if ( orientation() == Qt::Horizontal )
00265 {
00266 const double barHeight = sampleWidth( yMap, canvasRect.height(),
00267 boundingInterval.width(), sample.y() );
00268
00269 const double x1 = xMap.transform( baseline() );
00270 const double x2 = xMap.transform( sample.y() );
00271
00272 const double y = yMap.transform( sample.x() );
00273 const double y1 = y - 0.5 * barHeight;
00274 const double y2 = y + 0.5 * barHeight;
00275
00276 barRect.direction = ( x1 < x2 ) ?
00277 QwtColumnRect::LeftToRight : QwtColumnRect::RightToLeft;
00278
00279 barRect.hInterval = QwtInterval( x1, x2 ).normalized();
00280 barRect.vInterval = QwtInterval( y1, y2 );
00281 }
00282 else
00283 {
00284 const double barWidth = sampleWidth( xMap, canvasRect.width(),
00285 boundingInterval.width(), sample.y() );
00286
00287 const double x = xMap.transform( sample.x() );
00288 const double x1 = x - 0.5 * barWidth;
00289 const double x2 = x + 0.5 * barWidth;
00290
00291 const double y1 = yMap.transform( baseline() );
00292 const double y2 = yMap.transform( sample.y() );
00293
00294 barRect.direction = ( y1 < y2 ) ?
00295 QwtColumnRect::TopToBottom : QwtColumnRect::BottomToTop;
00296
00297 barRect.hInterval = QwtInterval( x1, x2 );
00298 barRect.vInterval = QwtInterval( y1, y2 ).normalized();
00299 }
00300
00301 return barRect;
00302 }
00303
00317 void QwtPlotBarChart::drawSample( QPainter *painter,
00318 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
00319 const QRectF &canvasRect, const QwtInterval &boundingInterval,
00320 int index, const QPointF &sample ) const
00321 {
00322 const QwtColumnRect barRect = columnRect( xMap, yMap,
00323 canvasRect, boundingInterval, sample );
00324
00325 drawBar( painter, index, sample, barRect );
00326 }
00327
00336 void QwtPlotBarChart::drawBar( QPainter *painter,
00337 int sampleIndex, const QPointF &sample,
00338 const QwtColumnRect &rect ) const
00339 {
00340 const QwtColumnSymbol *specialSym =
00341 specialSymbol( sampleIndex, sample );
00342
00343 const QwtColumnSymbol *sym = specialSym;
00344 if ( sym == NULL )
00345 sym = d_data->symbol;
00346
00347 if ( sym )
00348 {
00349 sym->draw( painter, rect );
00350 }
00351 else
00352 {
00353
00354 QwtColumnSymbol sym( QwtColumnSymbol::Box );
00355 sym.setLineWidth( 1 );
00356 sym.setFrameStyle( QwtColumnSymbol::Plain );
00357 sym.draw( painter, rect );
00358 }
00359
00360 delete specialSym;
00361 }
00362
00372 QwtColumnSymbol *QwtPlotBarChart::specialSymbol(
00373 int sampleIndex, const QPointF &sample ) const
00374 {
00375 Q_UNUSED( sampleIndex );
00376 Q_UNUSED( sample );
00377
00378 return NULL;
00379 }
00380
00394 QwtText QwtPlotBarChart::barTitle( int sampleIndex ) const
00395 {
00396 Q_UNUSED( sampleIndex );
00397 return QwtText();
00398 }
00399
00411 QList<QwtLegendData> QwtPlotBarChart::legendData() const
00412 {
00413 QList<QwtLegendData> list;
00414
00415 if ( d_data->legendMode == LegendBarTitles )
00416 {
00417 const size_t numSamples = dataSize();
00418 for ( size_t i = 0; i < numSamples; i++ )
00419 {
00420 QwtLegendData data;
00421
00422 QVariant titleValue;
00423 qVariantSetValue( titleValue, barTitle( i ) );
00424 data.setValue( QwtLegendData::TitleRole, titleValue );
00425
00426 if ( !legendIconSize().isEmpty() )
00427 {
00428 QVariant iconValue;
00429 qVariantSetValue( iconValue,
00430 legendIcon( i, legendIconSize() ) );
00431
00432 data.setValue( QwtLegendData::IconRole, iconValue );
00433 }
00434
00435 list += data;
00436 }
00437 }
00438 else
00439 {
00440 return QwtPlotAbstractBarChart::legendData();
00441 }
00442
00443 return list;
00444 }
00445
00459 QwtGraphic QwtPlotBarChart::legendIcon(
00460 int index, const QSizeF &size ) const
00461 {
00462 QwtColumnRect column;
00463 column.hInterval = QwtInterval( 0.0, size.width() - 1.0 );
00464 column.vInterval = QwtInterval( 0.0, size.height() - 1.0 );
00465
00466 QwtGraphic icon;
00467 icon.setDefaultSize( size );
00468 icon.setRenderHint( QwtGraphic::RenderPensUnscaled, true );
00469
00470 QPainter painter( &icon );
00471 painter.setRenderHint( QPainter::Antialiasing,
00472 testRenderHint( QwtPlotItem::RenderAntialiased ) );
00473
00474 int barIndex = -1;
00475 if ( d_data->legendMode == QwtPlotBarChart::LegendBarTitles )
00476 barIndex = index;
00477
00478 drawBar( &painter, barIndex, QPointF(), column );
00479
00480 return icon;
00481 }