Qwt User's Guide: qwt_plot_histogram.cpp Source File

Qwt User's Guide 6.3.0

Loading...
Searching...
No Matches
qwt_plot_histogram.cpp
1/******************************************************************************
2 * Qwt Widget Library
3 * Copyright (C) 1997 Josef Wilgen
4 * Copyright (C) 2002 Uwe Rathmann
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the Qwt License, Version 1.0
8 *****************************************************************************/
9
10#include "qwt_plot_histogram.h"
11#include "qwt_painter.h"
12#include "qwt_column_symbol.h"
13#include "qwt_scale_map.h"
14#include "qwt_graphic.h"
15
16#include <qstring.h>
17#include <qpainter.h>
18
19static inline bool qwtIsCombinable( const QwtInterval& d1,
20 const QwtInterval& d2 )
21{
22 if ( d1.isValid() && d2.isValid() )
23 {
24 if ( d1.maxValue() == d2.minValue() )
25 {
26 if ( !( d1.borderFlags() & QwtInterval::ExcludeMaximum
27 && d2.borderFlags() & QwtInterval::ExcludeMinimum ) )
28 {
29 return true;
30 }
31 }
32 }
33
34 return false;
35}
36
37class QwtPlotHistogram::PrivateData
38{
39 public:
40 PrivateData()
41 : baseline( 0.0 )
42 , style( Columns )
43 , symbol( NULL )
44 {
45 }
46
47 ~PrivateData()
48 {
49 delete symbol;
50 }
51
52 double baseline;
53
54 QPen pen;
55 QBrush brush;
56 QwtPlotHistogram::HistogramStyle style;
57 const QwtColumnSymbol* symbol;
58};
59
64 QwtPlotHistogram::QwtPlotHistogram( const QwtText& title )
65 : QwtPlotSeriesItem( title )
66{
67 init();
68}
69
74QwtPlotHistogram::QwtPlotHistogram( const QString& title )
75 : QwtPlotSeriesItem( title )
76{
77 init();
78}
79
81QwtPlotHistogram::~QwtPlotHistogram()
82{
83 delete m_data;
84}
85
87void QwtPlotHistogram::init()
88{
89 m_data = new PrivateData();
90 setData( new QwtIntervalSeriesData() );
91
92 setItemAttribute( QwtPlotItem::AutoScale, true );
93 setItemAttribute( QwtPlotItem::Legend, true );
94
95 setZ( 20.0 );
96}
97
104 void QwtPlotHistogram::setStyle( HistogramStyle style )
105{
106 if ( style != m_data->style )
107 {
108 m_data->style = style;
109
110 legendChanged();
111 itemChanged();
112 }
113}
114
119 QwtPlotHistogram::HistogramStyle QwtPlotHistogram::style() const
120{
121 return m_data->style;
122}
123
137 void QwtPlotHistogram::setPen( const QColor& color, qreal width, Qt::PenStyle style )
138{
139 setPen( QPen( color, width, style ) );
140}
141
148 void QwtPlotHistogram::setPen( const QPen& pen )
149{
150 if ( pen != m_data->pen )
151 {
152 m_data->pen = pen;
153
154 legendChanged();
155 itemChanged();
156 }
157}
158
163 const QPen& QwtPlotHistogram::pen() const
164{
165 return m_data->pen;
166}
167
174 void QwtPlotHistogram::setBrush( const QBrush& brush )
175{
176 if ( brush != m_data->brush )
177 {
178 m_data->brush = brush;
179
180 legendChanged();
181 itemChanged();
182 }
183}
184
189 const QBrush& QwtPlotHistogram::brush() const
190{
191 return m_data->brush;
192}
193
208 void QwtPlotHistogram::setSymbol( const QwtColumnSymbol* symbol )
209{
210 if ( symbol != m_data->symbol )
211 {
212 delete m_data->symbol;
213 m_data->symbol = symbol;
214
215 legendChanged();
216 itemChanged();
217 }
218}
219
224 const QwtColumnSymbol* QwtPlotHistogram::symbol() const
225{
226 return m_data->symbol;
227}
228
240 void QwtPlotHistogram::setBaseline( double value )
241{
242 if ( m_data->baseline != value )
243 {
244 m_data->baseline = value;
245 itemChanged();
246 }
247}
248
253 double QwtPlotHistogram::baseline() const
254{
255 return m_data->baseline;
256}
257
262QRectF QwtPlotHistogram::boundingRect() const
263{
264 QRectF rect = data()->boundingRect();
265 if ( !rect.isValid() )
266 return rect;
267
268 if ( orientation() == Qt::Horizontal )
269 {
270 rect = QRectF( rect.y(), rect.x(),
271 rect.height(), rect.width() );
272
273 if ( rect.left() > m_data->baseline )
274 rect.setLeft( m_data->baseline );
275 else if ( rect.right() < m_data->baseline )
276 rect.setRight( m_data->baseline );
277 }
278 else
279 {
280 if ( rect.bottom() < m_data->baseline )
281 rect.setBottom( m_data->baseline );
282 else if ( rect.top() > m_data->baseline )
283 rect.setTop( m_data->baseline );
284 }
285
286 return rect;
287}
288
290 int QwtPlotHistogram::rtti() const
291{
292 return QwtPlotItem::Rtti_PlotHistogram;
293}
294
299 void QwtPlotHistogram::setSamples(
300 const QVector< QwtIntervalSample >& samples )
301{
302 setData( new QwtIntervalSeriesData( samples ) );
303}
304
315 void QwtPlotHistogram::setSamples(
316 QwtSeriesData< QwtIntervalSample >* data )
317{
318 setData( data );
319}
320
334 void QwtPlotHistogram::drawSeries( QPainter* painter,
335 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
336 const QRectF& canvasRect, int from, int to ) const
337{
338 Q_UNUSED( canvasRect )
339
340 if ( !painter || dataSize() <= 0 )
341 return;
342
343 if ( to < 0 )
344 to = dataSize() - 1;
345
346 switch ( m_data->style )
347 {
348 case Outline:
349 drawOutline( painter, xMap, yMap, from, to );
350 break;
351 case Lines:
352 drawLines( painter, xMap, yMap, from, to );
353 break;
354 case Columns:
355 drawColumns( painter, xMap, yMap, from, to );
356 break;
357 default:
358 break;
359 }
360}
361
376 void QwtPlotHistogram::drawOutline( QPainter* painter,
377 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
378 int from, int to ) const
379{
380 const bool doAlign = QwtPainter::roundingAlignment( painter );
381
382 double v0 = ( orientation() == Qt::Horizontal ) ?
383 xMap.transform( baseline() ) : yMap.transform( baseline() );
384 if ( doAlign )
385 v0 = qRound( v0 );
386
387 QwtIntervalSample previous;
388
389 QPolygonF polygon;
390 for ( int i = from; i <= to; i++ )
391 {
392 const QwtIntervalSample sample = this->sample( i );
393
394 if ( !sample.interval.isValid() )
395 {
396 flushPolygon( painter, v0, polygon );
397 previous = sample;
398 continue;
399 }
400
401 if ( previous.interval.isValid() )
402 {
403 if ( !qwtIsCombinable( previous.interval, sample.interval ) )
404 flushPolygon( painter, v0, polygon );
405 }
406
407 if ( orientation() == Qt::Vertical )
408 {
409 double x1 = xMap.transform( sample.interval.minValue() );
410 double x2 = xMap.transform( sample.interval.maxValue() );
411 double y = yMap.transform( sample.value );
412 if ( doAlign )
413 {
414 x1 = qRound( x1 );
415 x2 = qRound( x2 );
416 y = qRound( y );
417 }
418
419 if ( polygon.size() == 0 )
420 polygon += QPointF( x1, v0 );
421
422 polygon += QPointF( x1, y );
423 polygon += QPointF( x2, y );
424 }
425 else
426 {
427 double y1 = yMap.transform( sample.interval.minValue() );
428 double y2 = yMap.transform( sample.interval.maxValue() );
429 double x = xMap.transform( sample.value );
430 if ( doAlign )
431 {
432 y1 = qRound( y1 );
433 y2 = qRound( y2 );
434 x = qRound( x );
435 }
436
437 if ( polygon.size() == 0 )
438 polygon += QPointF( v0, y1 );
439
440 polygon += QPointF( x, y1 );
441 polygon += QPointF( x, y2 );
442 }
443 previous = sample;
444 }
445
446 flushPolygon( painter, v0, polygon );
447}
448
461 void QwtPlotHistogram::drawColumns( QPainter* painter,
462 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
463 int from, int to ) const
464{
465 painter->setPen( m_data->pen );
466 painter->setBrush( m_data->brush );
467
468 const QwtSeriesData< QwtIntervalSample >* series = data();
469
470 for ( int i = from; i <= to; i++ )
471 {
472 const QwtIntervalSample sample = series->sample( i );
473 if ( !sample.interval.isNull() )
474 {
475 const QwtColumnRect rect = columnRect( sample, xMap, yMap );
476 drawColumn( painter, rect, sample );
477 }
478 }
479}
480
493 void QwtPlotHistogram::drawLines( QPainter* painter,
494 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
495 int from, int to ) const
496{
497 const bool doAlign = QwtPainter::roundingAlignment( painter );
498
499 painter->setPen( m_data->pen );
500 painter->setBrush( Qt::NoBrush );
501
502 const QwtSeriesData< QwtIntervalSample >* series = data();
503
504 for ( int i = from; i <= to; i++ )
505 {
506 const QwtIntervalSample sample = series->sample( i );
507 if ( !sample.interval.isNull() )
508 {
509 const QwtColumnRect rect = columnRect( sample, xMap, yMap );
510
511 QRectF r = rect.toRect();
512 if ( doAlign )
513 {
514 r.setLeft( qRound( r.left() ) );
515 r.setRight( qRound( r.right() ) );
516 r.setTop( qRound( r.top() ) );
517 r.setBottom( qRound( r.bottom() ) );
518 }
519
520 switch ( rect.direction )
521 {
522 case QwtColumnRect::LeftToRight:
523 {
524 QwtPainter::drawLine( painter,
525 r.topRight(), r.bottomRight() );
526 break;
527 }
528 case QwtColumnRect::RightToLeft:
529 {
530 QwtPainter::drawLine( painter,
531 r.topLeft(), r.bottomLeft() );
532 break;
533 }
534 case QwtColumnRect::TopToBottom:
535 {
536 QwtPainter::drawLine( painter,
537 r.bottomRight(), r.bottomLeft() );
538 break;
539 }
540 case QwtColumnRect::BottomToTop:
541 {
542 QwtPainter::drawLine( painter,
543 r.topRight(), r.topLeft() );
544 break;
545 }
546 }
547 }
548 }
549}
550
552void QwtPlotHistogram::flushPolygon( QPainter* painter,
553 double baseLine, QPolygonF& polygon ) const
554{
555 if ( polygon.size() == 0 )
556 return;
557
558 if ( orientation() == Qt::Horizontal )
559 polygon += QPointF( baseLine, polygon.last().y() );
560 else
561 polygon += QPointF( polygon.last().x(), baseLine );
562
563 if ( m_data->brush.style() != Qt::NoBrush )
564 {
565 painter->setPen( Qt::NoPen );
566 painter->setBrush( m_data->brush );
567
568 if ( orientation() == Qt::Horizontal )
569 {
570 polygon += QPointF( polygon.last().x(), baseLine );
571 polygon += QPointF( polygon.first().x(), baseLine );
572 }
573 else
574 {
575 polygon += QPointF( baseLine, polygon.last().y() );
576 polygon += QPointF( baseLine, polygon.first().y() );
577 }
578
579 QwtPainter::drawPolygon( painter, polygon );
580
581 polygon.pop_back();
582 polygon.pop_back();
583 }
584 if ( m_data->pen.style() != Qt::NoPen )
585 {
586 painter->setBrush( Qt::NoBrush );
587 painter->setPen( m_data->pen );
588 QwtPainter::drawPolyline( painter, polygon );
589 }
590 polygon.clear();
591}
592
602 QwtColumnRect QwtPlotHistogram::columnRect( const QwtIntervalSample& sample,
603 const QwtScaleMap& xMap, const QwtScaleMap& yMap ) const
604{
605 QwtColumnRect rect;
606
607 const QwtInterval& iv = sample.interval;
608 if ( !iv.isValid() )
609 return rect;
610
611 if ( orientation() == Qt::Horizontal )
612 {
613 const double x0 = xMap.transform( baseline() );
614 const double x = xMap.transform( sample.value );
615 const double y1 = yMap.transform( iv.minValue() );
616 const double y2 = yMap.transform( iv.maxValue() );
617
618 rect.hInterval.setInterval( x0, x );
619 rect.vInterval.setInterval( y1, y2, iv.borderFlags() );
620 rect.direction = ( x < x0 ) ? QwtColumnRect::RightToLeft :
621 QwtColumnRect::LeftToRight;
622 }
623 else
624 {
625 const double x1 = xMap.transform( iv.minValue() );
626 const double x2 = xMap.transform( iv.maxValue() );
627 const double y0 = yMap.transform( baseline() );
628 const double y = yMap.transform( sample.value );
629
630 rect.hInterval.setInterval( x1, x2, iv.borderFlags() );
631 rect.vInterval.setInterval( y0, y );
632 rect.direction = ( y < y0 ) ? QwtColumnRect::BottomToTop :
633 QwtColumnRect::TopToBottom;
634 }
635
636 return rect;
637}
638
653 void QwtPlotHistogram::drawColumn( QPainter* painter,
654 const QwtColumnRect& rect, const QwtIntervalSample& sample ) const
655{
656 Q_UNUSED( sample );
657
658 if ( m_data->symbol &&
659 ( m_data->symbol->style() != QwtColumnSymbol::NoStyle ) )
660 {
661 m_data->symbol->draw( painter, rect );
662 }
663 else
664 {
665 QRectF r = rect.toRect();
666 if ( QwtPainter::roundingAlignment( painter ) )
667 {
668 r.setLeft( qRound( r.left() ) );
669 r.setRight( qRound( r.right() ) );
670 r.setTop( qRound( r.top() ) );
671 r.setBottom( qRound( r.bottom() ) );
672 }
673
674 QwtPainter::drawRect( painter, r );
675 }
676}
677
688 QwtGraphic QwtPlotHistogram::legendIcon( int index, const QSizeF& size ) const
689{
690 Q_UNUSED( index );
691 return defaultIcon( m_data->brush, size );
692}
QVector
Definition qwt_clipper.h:23
QwtArraySeriesData
Template class for data, that is organized as QVector.
Definition qwt_series_data.h:153
QwtColumnRect
Directed rectangle representing bounding rectangle and orientation of a column.
Definition qwt_column_symbol.h:27
QwtColumnRect::vInterval
QwtInterval vInterval
Interval for the vertical coordinates.
Definition qwt_column_symbol.h:67
QwtColumnRect::hInterval
QwtInterval hInterval
Interval for the horizontal coordinates.
Definition qwt_column_symbol.h:64
QwtColumnRect::LeftToRight
@ LeftToRight
From left to right.
Definition qwt_column_symbol.h:33
QwtColumnRect::TopToBottom
@ TopToBottom
From top to bottom.
Definition qwt_column_symbol.h:42
QwtColumnRect::BottomToTop
@ BottomToTop
From bottom to top.
Definition qwt_column_symbol.h:39
QwtColumnRect::RightToLeft
@ RightToLeft
From right to left.
Definition qwt_column_symbol.h:36
QwtColumnRect::direction
Direction direction
Direction.
Definition qwt_column_symbol.h:70
QwtColumnRect::toRect
QRectF toRect() const
Definition qwt_column_symbol.cpp:296
QwtColumnSymbol
A drawing primitive for columns.
Definition qwt_column_symbol.h:75
QwtColumnSymbol::draw
virtual void draw(QPainter *, const QwtColumnRect &) const
Definition qwt_column_symbol.cpp:238
QwtColumnSymbol::NoStyle
@ NoStyle
No Style, the symbol draws nothing.
Definition qwt_column_symbol.h:84
QwtColumnSymbol::style
Style style() const
Definition qwt_column_symbol.cpp:162
QwtGraphic
A paint device for scalable graphics.
Definition qwt_graphic.h:76
QwtInterval
A class representing an interval.
Definition qwt_interval.h:23
QwtInterval::setInterval
void setInterval(double minValue, double maxValue, BorderFlags=IncludeBorders)
Definition qwt_interval.h:143
QwtInterval::minValue
double minValue() const
Definition qwt_interval.h:192
QwtInterval::ExcludeMaximum
@ ExcludeMaximum
Max value is not included in the interval.
Definition qwt_interval.h:38
QwtInterval::ExcludeMinimum
@ ExcludeMinimum
Min value is not included in the interval.
Definition qwt_interval.h:35
QwtInterval::maxValue
double maxValue() const
Definition qwt_interval.h:198
QwtInterval::borderFlags
BorderFlags borderFlags() const
Definition qwt_interval.h:166
QwtInterval::isNull
bool isNull() const
Definition qwt_interval.h:314
QwtInterval::isValid
bool isValid() const
Definition qwt_interval.h:210
QwtIntervalSample
A sample of the types (x1-x2, y) or (x, y1-y2)
Definition qwt_samples.h:21
QwtIntervalSample::interval
QwtInterval interval
Interval.
Definition qwt_samples.h:34
QwtIntervalSample::value
double value
Value.
Definition qwt_samples.h:31
QwtPainter::drawPolygon
static void drawPolygon(QPainter *, const QPolygonF &)
Wrapper for QPainter::drawPolygon()
Definition qwt_painter.cpp:551
QwtPainter::drawPolyline
static void drawPolyline(QPainter *, const QPolygonF &)
Wrapper for QPainter::drawPolyline()
Definition qwt_painter.cpp:568
QwtPainter::drawRect
static void drawRect(QPainter *, qreal x, qreal y, qreal w, qreal h)
Wrapper for QPainter::drawRect()
Definition qwt_painter.cpp:337
QwtPainter::roundingAlignment
static bool roundingAlignment()
Definition qwt_painter.h:183
QwtPainter::drawLine
static void drawLine(QPainter *, qreal x1, qreal y1, qreal x2, qreal y2)
Wrapper for QPainter::drawLine()
Definition qwt_painter.h:154
QwtPlotHistogram::columnRect
virtual QwtColumnRect columnRect(const QwtIntervalSample &, const QwtScaleMap &, const QwtScaleMap &) const
Definition qwt_plot_histogram.cpp:602
QwtPlotHistogram::setBrush
void setBrush(const QBrush &)
Definition qwt_plot_histogram.cpp:174
QwtPlotHistogram::style
HistogramStyle style() const
Definition qwt_plot_histogram.cpp:119
QwtPlotHistogram::QwtPlotHistogram
QwtPlotHistogram(const QString &title=QString())
Definition qwt_plot_histogram.cpp:74
QwtPlotHistogram::HistogramStyle
HistogramStyle
Definition qwt_plot_histogram.h:53
QwtPlotHistogram::Lines
@ Lines
Definition qwt_plot_histogram.h:72
QwtPlotHistogram::Columns
@ Columns
Definition qwt_plot_histogram.h:67
QwtPlotHistogram::Outline
@ Outline
Definition qwt_plot_histogram.h:60
QwtPlotHistogram::legendIcon
virtual QwtGraphic legendIcon(int index, const QSizeF &) const override
Definition qwt_plot_histogram.cpp:688
QwtPlotHistogram::setStyle
void setStyle(HistogramStyle style)
Definition qwt_plot_histogram.cpp:104
QwtPlotHistogram::setBaseline
void setBaseline(double)
Set the value of the baseline.
Definition qwt_plot_histogram.cpp:240
QwtPlotHistogram::setPen
void setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
Definition qwt_plot_histogram.cpp:137
QwtPlotHistogram::~QwtPlotHistogram
virtual ~QwtPlotHistogram()
Destructor.
Definition qwt_plot_histogram.cpp:81
QwtPlotHistogram::setSamples
void setSamples(const QVector< QwtIntervalSample > &)
Definition qwt_plot_histogram.cpp:299
QwtPlotHistogram::drawLines
void drawLines(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, int from, int to) const
Definition qwt_plot_histogram.cpp:493
QwtPlotHistogram::drawOutline
void drawOutline(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, int from, int to) const
Definition qwt_plot_histogram.cpp:376
QwtPlotHistogram::rtti
virtual int rtti() const override
Definition qwt_plot_histogram.cpp:290
QwtPlotHistogram::pen
const QPen & pen() const
Definition qwt_plot_histogram.cpp:163
QwtPlotHistogram::boundingRect
virtual QRectF boundingRect() const override
Definition qwt_plot_histogram.cpp:262
QwtPlotHistogram::baseline
double baseline() const
Definition qwt_plot_histogram.cpp:253
QwtPlotHistogram::setSymbol
void setSymbol(const QwtColumnSymbol *)
Assign a symbol.
Definition qwt_plot_histogram.cpp:208
QwtPlotHistogram::symbol
const QwtColumnSymbol * symbol() const
Definition qwt_plot_histogram.cpp:224
QwtPlotHistogram::drawColumns
void drawColumns(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, int from, int to) const
Definition qwt_plot_histogram.cpp:461
QwtPlotHistogram::brush
const QBrush & brush() const
Definition qwt_plot_histogram.cpp:189
QwtPlotHistogram::drawColumn
virtual void drawColumn(QPainter *, const QwtColumnRect &, const QwtIntervalSample &) const
Definition qwt_plot_histogram.cpp:653
QwtPlotHistogram::drawSeries
virtual void drawSeries(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const override
Definition qwt_plot_histogram.cpp:334
QwtPlotItem::legendChanged
virtual void legendChanged()
Definition qwt_plot_item.cpp:491
QwtPlotItem::setZ
void setZ(double z)
Set the z value.
Definition qwt_plot_item.cpp:165
QwtPlotItem::setItemAttribute
void setItemAttribute(ItemAttribute, bool on=true)
Definition qwt_plot_item.cpp:228
QwtPlotItem::defaultIcon
QwtGraphic defaultIcon(const QBrush &, const QSizeF &) const
Return a default icon from a brush.
Definition qwt_plot_item.cpp:422
QwtPlotItem::Rtti_PlotHistogram
@ Rtti_PlotHistogram
For QwtPlotHistogram.
Definition qwt_plot_item.h:102
QwtPlotItem::itemChanged
virtual void itemChanged()
Definition qwt_plot_item.cpp:481
QwtPlotItem::Legend
@ Legend
The item is represented on the legend.
Definition qwt_plot_item.h:150
QwtPlotItem::AutoScale
@ AutoScale
Definition qwt_plot_item.h:157
QwtPlotSeriesItem
Base class for plot items representing a series of samples.
Definition qwt_plot_seriesitem.h:26
QwtPlotSeriesItem::orientation
Qt::Orientation orientation() const
Definition qwt_plot_seriesitem.cpp:77
QwtScaleMap
A scale map.
Definition qwt_scale_map.h:27
QwtScaleMap::transform
double transform(double s) const
Definition qwt_scale_map.h:137
QwtSeriesData< QwtIntervalSample >
QwtSeriesData::boundingRect
virtual QRectF boundingRect() const
Definition qwt_series_data.h:100
QwtSeriesData::sample
virtual T sample(size_t i) const =0
QwtSeriesStore< QwtIntervalSample >::sample
QwtIntervalSample sample(int index) const
Definition qwt_series_store.h:158
QwtSeriesStore< QwtIntervalSample >::dataSize
virtual size_t dataSize() const override
Definition qwt_series_store.h:175
QwtSeriesStore< QwtIntervalSample >::data
QwtSeriesData< QwtIntervalSample > * data()
Definition qwt_series_store.h:146
QwtSeriesStore< QwtIntervalSample >::setData
void setData(QwtSeriesData< QwtIntervalSample > *series)
Definition qwt_series_store.h:164
QwtText
A class representing a text.
Definition qwt_text.h:52