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 points.reserve( samples.size() );
00099
00100 for ( int i = 0; i < samples.size(); i++ )
00101 points += QPointF( i, samples[ i ] );
00102
00103 setData( new QwtPointSeriesData( points ) );
00104 }
00105
00116 void QwtPlotBarChart::setSamples( QwtSeriesData<QPointF> *data )
00117 {
00118 setData( data );
00119 }
00120
00131 void QwtPlotBarChart::setSymbol( QwtColumnSymbol *symbol )
00132 {
00133 if ( symbol != d_data->symbol )
00134 {
00135 delete d_data->symbol;
00136 d_data->symbol = symbol;
00137
00138 legendChanged();
00139 itemChanged();
00140 }
00141 }
00142
00147 const QwtColumnSymbol *QwtPlotBarChart::symbol() const
00148 {
00149 return d_data->symbol;
00150 }
00151
00161 void QwtPlotBarChart::setLegendMode( LegendMode mode )
00162 {
00163 if ( mode != d_data->legendMode )
00164 {
00165 d_data->legendMode = mode;
00166 legendChanged();
00167 }
00168 }
00169
00174 QwtPlotBarChart::LegendMode QwtPlotBarChart::legendMode() const
00175 {
00176 return d_data->legendMode;
00177 }
00178
00183 QRectF QwtPlotBarChart::boundingRect() const
00184 {
00185 const size_t numSamples = dataSize();
00186 if ( numSamples == 0 )
00187 return QwtPlotSeriesItem::boundingRect();
00188
00189 QRectF rect = QwtPlotSeriesItem::boundingRect();
00190 if ( rect.height() >= 0 )
00191 {
00192 const double baseLine = baseline();
00193
00194 if ( rect.bottom() < baseLine )
00195 rect.setBottom( baseLine );
00196
00197 if ( rect.top() > baseLine )
00198 rect.setTop( baseLine );
00199 }
00200
00201 if ( orientation() == Qt::Horizontal )
00202 rect.setRect( rect.y(), rect.x(), rect.height(), rect.width() );
00203
00204 return rect;
00205 }
00206
00220 void QwtPlotBarChart::drawSeries( QPainter *painter,
00221 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
00222 const QRectF &canvasRect, int from, int to ) const
00223 {
00224 if ( to < 0 )
00225 to = dataSize() - 1;
00226
00227 if ( from < 0 )
00228 from = 0;
00229
00230 if ( from > to )
00231 return;
00232
00233
00234 const QRectF br = data()->boundingRect();
00235 const QwtInterval interval( br.left(), br.right() );
00236
00237 painter->save();
00238
00239 for ( int i = from; i <= to; i++ )
00240 {
00241 drawSample( painter, xMap, yMap,
00242 canvasRect, interval, i, sample( i ) );
00243 }
00244
00245 painter->restore();
00246 }
00247
00259 QwtColumnRect QwtPlotBarChart::columnRect(
00260 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
00261 const QRectF &canvasRect, const QwtInterval &boundingInterval,
00262 const QPointF &sample ) const
00263 {
00264 QwtColumnRect barRect;
00265
00266 if ( orientation() == Qt::Horizontal )
00267 {
00268 const double barHeight = sampleWidth( yMap, canvasRect.height(),
00269 boundingInterval.width(), sample.y() );
00270
00271 const double x1 = xMap.transform( baseline() );
00272 const double x2 = xMap.transform( sample.y() );
00273
00274 const double y = yMap.transform( sample.x() );
00275 const double y1 = y - 0.5 * barHeight;
00276 const double y2 = y + 0.5 * barHeight;
00277
00278 barRect.direction = ( x1 < x2 ) ?
00279 QwtColumnRect::LeftToRight : QwtColumnRect::RightToLeft;
00280
00281 barRect.hInterval = QwtInterval( x1, x2 ).normalized();
00282 barRect.vInterval = QwtInterval( y1, y2 );
00283 }
00284 else
00285 {
00286 const double barWidth = sampleWidth( xMap, canvasRect.width(),
00287 boundingInterval.width(), sample.y() );
00288
00289 const double x = xMap.transform( sample.x() );
00290 const double x1 = x - 0.5 * barWidth;
00291 const double x2 = x + 0.5 * barWidth;
00292
00293 const double y1 = yMap.transform( baseline() );
00294 const double y2 = yMap.transform( sample.y() );
00295
00296 barRect.direction = ( y1 < y2 ) ?
00297 QwtColumnRect::TopToBottom : QwtColumnRect::BottomToTop;
00298
00299 barRect.hInterval = QwtInterval( x1, x2 );
00300 barRect.vInterval = QwtInterval( y1, y2 ).normalized();
00301 }
00302
00303 return barRect;
00304 }
00305
00319 void QwtPlotBarChart::drawSample( QPainter *painter,
00320 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
00321 const QRectF &canvasRect, const QwtInterval &boundingInterval,
00322 int index, const QPointF &sample ) const
00323 {
00324 const QwtColumnRect barRect = columnRect( xMap, yMap,
00325 canvasRect, boundingInterval, sample );
00326
00327 drawBar( painter, index, sample, barRect );
00328 }
00329
00338 void QwtPlotBarChart::drawBar( QPainter *painter,
00339 int sampleIndex, const QPointF &sample,
00340 const QwtColumnRect &rect ) const
00341 {
00342 const QwtColumnSymbol *specialSym =
00343 specialSymbol( sampleIndex, sample );
00344
00345 const QwtColumnSymbol *sym = specialSym;
00346 if ( sym == NULL )
00347 sym = d_data->symbol;
00348
00349 if ( sym )
00350 {
00351 sym->draw( painter, rect );
00352 }
00353 else
00354 {
00355
00356 QwtColumnSymbol sym( QwtColumnSymbol::Box );
00357 sym.setLineWidth( 1 );
00358 sym.setFrameStyle( QwtColumnSymbol::Plain );
00359 sym.draw( painter, rect );
00360 }
00361
00362 delete specialSym;
00363 }
00364
00374 QwtColumnSymbol *QwtPlotBarChart::specialSymbol(
00375 int sampleIndex, const QPointF &sample ) const
00376 {
00377 Q_UNUSED( sampleIndex );
00378 Q_UNUSED( sample );
00379
00380 return NULL;
00381 }
00382
00396 QwtText QwtPlotBarChart::barTitle( int sampleIndex ) const
00397 {
00398 Q_UNUSED( sampleIndex );
00399 return QwtText();
00400 }
00401
00413 QList<QwtLegendData> QwtPlotBarChart::legendData() const
00414 {
00415 QList<QwtLegendData> list;
00416
00417 if ( d_data->legendMode == LegendBarTitles )
00418 {
00419 const size_t numSamples = dataSize();
00420 #if QT_VERSION >= 0x040700
00421 list.reserve( numSamples );
00422 #endif
00423
00424 for ( size_t i = 0; i < numSamples; i++ )
00425 {
00426 QwtLegendData data;
00427
00428 QVariant titleValue;
00429 qVariantSetValue( titleValue, barTitle( i ) );
00430 data.setValue( QwtLegendData::TitleRole, titleValue );
00431
00432 if ( !legendIconSize().isEmpty() )
00433 {
00434 QVariant iconValue;
00435 qVariantSetValue( iconValue,
00436 legendIcon( i, legendIconSize() ) );
00437
00438 data.setValue( QwtLegendData::IconRole, iconValue );
00439 }
00440
00441 list += data;
00442 }
00443 }
00444 else
00445 {
00446 return QwtPlotAbstractBarChart::legendData();
00447 }
00448
00449 return list;
00450 }
00451
00465 QwtGraphic QwtPlotBarChart::legendIcon(
00466 int index, const QSizeF &size ) const
00467 {
00468 QwtColumnRect column;
00469 column.hInterval = QwtInterval( 0.0, size.width() - 1.0 );
00470 column.vInterval = QwtInterval( 0.0, size.height() - 1.0 );
00471
00472 QwtGraphic icon;
00473 icon.setDefaultSize( size );
00474 icon.setRenderHint( QwtGraphic::RenderPensUnscaled, true );
00475
00476 QPainter painter( &icon );
00477 painter.setRenderHint( QPainter::Antialiasing,
00478 testRenderHint( QwtPlotItem::RenderAntialiased ) );
00479
00480 int barIndex = -1;
00481 if ( d_data->legendMode == QwtPlotBarChart::LegendBarTitles )
00482 barIndex = index;
00483
00484 drawBar( &painter, barIndex, QPointF(), column );
00485
00486 return icon;
00487 }