Qwt User's Guide 6.2.0

qwt_plot_intervalcurve.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_intervalcurve.h"
11 #include "qwt_interval_symbol.h"
12 #include "qwt_scale_map.h"
13 #include "qwt_clipper.h"
14 #include "qwt_painter.h"
15 #include "qwt_graphic.h"
16 #include "qwt_text.h"
17
18 #include <qpainter.h>
19 #include <cstring>
20
21 static inline bool qwtIsHSampleInside( const QwtIntervalSample& sample,
22 double xMin, double xMax, double yMin, double yMax )
23 {
24 const double y = sample.value;
25 const double x1 = sample.interval.minValue();
26 const double x2 = sample.interval.maxValue();
27
28 const bool isOffScreen = ( y < yMin ) || ( y > yMax )
29 || ( x1 < xMin && x2 < xMin ) || ( x1 > xMax && x2 > xMax );
30
31 return !isOffScreen;
32 }
33
34 static inline bool qwtIsVSampleInside( const QwtIntervalSample& sample,
35 double xMin, double xMax, double yMin, double yMax )
36 {
37 const double x = sample.value;
38 const double y1 = sample.interval.minValue();
39 const double y2 = sample.interval.maxValue();
40
41 const bool isOffScreen = ( x < xMin ) || ( x > xMax )
42 || ( y1 < yMin && y2 < yMin ) || ( y1 > yMax && y2 > yMax );
43
44 return !isOffScreen;
45 }
46
47 class QwtPlotIntervalCurve::PrivateData
48 {
49 public:
50 PrivateData():
51 style( QwtPlotIntervalCurve::Tube ),
52 symbol( NULL ),
53 pen( Qt::black ),
54 brush( Qt::white )
55 {
56 paintAttributes = QwtPlotIntervalCurve::ClipPolygons;
57 paintAttributes |= QwtPlotIntervalCurve::ClipSymbol;
58
59 pen.setCapStyle( Qt::FlatCap );
60 }
61
62 ~PrivateData()
63 {
64 delete symbol;
65 }
66
67 QwtPlotIntervalCurve::CurveStyle style;
68 const QwtIntervalSymbol* symbol;
69
70 QPen pen;
71 QBrush brush;
72
73 QwtPlotIntervalCurve::PaintAttributes paintAttributes;
74 };
75
80 QwtPlotIntervalCurve::QwtPlotIntervalCurve( const QwtText& title )
81 : QwtPlotSeriesItem( title )
82 {
83 init();
84 }
85
90 QwtPlotIntervalCurve::QwtPlotIntervalCurve( const QString& title )
91 : QwtPlotSeriesItem( QwtText( title ) )
92 {
93 init();
94 }
95
97 QwtPlotIntervalCurve::~QwtPlotIntervalCurve()
98 {
99 delete m_data;
100 }
101
103 void QwtPlotIntervalCurve::init()
104 {
105 setItemAttribute( QwtPlotItem::Legend, true );
106 setItemAttribute( QwtPlotItem::AutoScale, true );
107
108 m_data = new PrivateData;
109 setData( new QwtIntervalSeriesData() );
110
111 setZ( 19.0 );
112 }
113
115 int QwtPlotIntervalCurve::rtti() const
116 {
117 return QwtPlotIntervalCurve::Rtti_PlotIntervalCurve;
118 }
119
127 void QwtPlotIntervalCurve::setPaintAttribute(
128 PaintAttribute attribute, bool on )
129 {
130 if ( on )
131 m_data->paintAttributes |= attribute;
132 else
133 m_data->paintAttributes &= ~attribute;
134 }
135
140 bool QwtPlotIntervalCurve::testPaintAttribute(
141 PaintAttribute attribute ) const
142 {
143 return ( m_data->paintAttributes & attribute );
144 }
145
150 void QwtPlotIntervalCurve::setSamples(
151 const QVector< QwtIntervalSample >& samples )
152 {
153 setData( new QwtIntervalSeriesData( samples ) );
154 }
155
166 void QwtPlotIntervalCurve::setSamples(
167 QwtSeriesData< QwtIntervalSample >* data )
168 {
169 setData( data );
170 }
171
178 void QwtPlotIntervalCurve::setStyle( CurveStyle style )
179 {
180 if ( style != m_data->style )
181 {
182 m_data->style = style;
183
184 legendChanged();
185 itemChanged();
186 }
187 }
188
193 QwtPlotIntervalCurve::CurveStyle QwtPlotIntervalCurve::style() const
194 {
195 return m_data->style;
196 }
197
204 void QwtPlotIntervalCurve::setSymbol( const QwtIntervalSymbol* symbol )
205 {
206 if ( symbol != m_data->symbol )
207 {
208 delete m_data->symbol;
209 m_data->symbol = symbol;
210
211 legendChanged();
212 itemChanged();
213 }
214 }
215
220 const QwtIntervalSymbol* QwtPlotIntervalCurve::symbol() const
221 {
222 return m_data->symbol;
223 }
224
238 void QwtPlotIntervalCurve::setPen( const QColor& color, qreal width, Qt::PenStyle style )
239 {
240 setPen( QPen( color, width, style ) );
241 }
242
248 void QwtPlotIntervalCurve::setPen( const QPen& pen )
249 {
250 if ( pen != m_data->pen )
251 {
252 m_data->pen = pen;
253
254 legendChanged();
255 itemChanged();
256 }
257 }
258
263 const QPen& QwtPlotIntervalCurve::pen() const
264 {
265 return m_data->pen;
266 }
267
276 void QwtPlotIntervalCurve::setBrush( const QBrush& brush )
277 {
278 if ( brush != m_data->brush )
279 {
280 m_data->brush = brush;
281
282 legendChanged();
283 itemChanged();
284 }
285 }
286
291 const QBrush& QwtPlotIntervalCurve::brush() const
292 {
293 return m_data->brush;
294 }
295
300 QRectF QwtPlotIntervalCurve::boundingRect() const
301 {
302 QRectF rect = QwtPlotSeriesItem::boundingRect();
303 if ( orientation() == Qt::Vertical )
304 rect.setRect( rect.y(), rect.x(), rect.height(), rect.width() );
305
306 return rect;
307 }
308
322 void QwtPlotIntervalCurve::drawSeries( QPainter* painter,
323 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
324 const QRectF& canvasRect, int from, int to ) const
325 {
326 if ( to < 0 )
327 to = dataSize() - 1;
328
329 if ( from < 0 )
330 from = 0;
331
332 if ( from > to )
333 return;
334
335 switch ( m_data->style )
336 {
337 case Tube:
338 drawTube( painter, xMap, yMap, canvasRect, from, to );
339 break;
340
341 case NoCurve:
342 default:
343 break;
344 }
345
346 if ( m_data->symbol &&
347 ( m_data->symbol->style() != QwtIntervalSymbol::NoSymbol ) )
348 {
349 drawSymbols( painter, *m_data->symbol,
350 xMap, yMap, canvasRect, from, to );
351 }
352 }
353
371 void QwtPlotIntervalCurve::drawTube( QPainter* painter,
372 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
373 const QRectF& canvasRect, int from, int to ) const
374 {
375 const bool doAlign = QwtPainter::roundingAlignment( painter );
376
377 painter->save();
378
379 const size_t size = to - from + 1;
380 QPolygonF polygon( 2 * size );
381 QPointF* points = polygon.data();
382
383 for ( uint i = 0; i < size; i++ )
384 {
385 QPointF& minValue = points[i];
386 QPointF& maxValue = points[2 * size - 1 - i];
387
388 const QwtIntervalSample intervalSample = sample( from + i );
389 if ( orientation() == Qt::Vertical )
390 {
391 double x = xMap.transform( intervalSample.value );
392 double y1 = yMap.transform( intervalSample.interval.minValue() );
393 double y2 = yMap.transform( intervalSample.interval.maxValue() );
394 if ( doAlign )
395 {
396 x = qRound( x );
397 y1 = qRound( y1 );
398 y2 = qRound( y2 );
399 }
400
401 minValue.rx() = x;
402 minValue.ry() = y1;
403 maxValue.rx() = x;
404 maxValue.ry() = y2;
405 }
406 else
407 {
408 double y = yMap.transform( intervalSample.value );
409 double x1 = xMap.transform( intervalSample.interval.minValue() );
410 double x2 = xMap.transform( intervalSample.interval.maxValue() );
411 if ( doAlign )
412 {
413 y = qRound( y );
414 x1 = qRound( x1 );
415 x2 = qRound( x2 );
416 }
417
418 minValue.rx() = x1;
419 minValue.ry() = y;
420 maxValue.rx() = x2;
421 maxValue.ry() = y;
422 }
423 }
424
425 if ( m_data->brush.style() != Qt::NoBrush )
426 {
427 painter->setPen( QPen( Qt::NoPen ) );
428 painter->setBrush( m_data->brush );
429
430 if ( m_data->paintAttributes & ClipPolygons )
431 {
432 const qreal m = 1.0;
433 const QPolygonF p = QwtClipper::clippedPolygonF(
434 canvasRect.adjusted( -m, -m, m, m ), polygon, true );
435
436 QwtPainter::drawPolygon( painter, p );
437 }
438 else
439 {
440 QwtPainter::drawPolygon( painter, polygon );
441 }
442 }
443
444 if ( m_data->pen.style() != Qt::NoPen )
445 {
446 painter->setPen( m_data->pen );
447 painter->setBrush( Qt::NoBrush );
448
449 if ( m_data->paintAttributes & ClipPolygons )
450 {
451 qreal pw = QwtPainter::effectivePenWidth( painter->pen() );
452 const QRectF clipRect = canvasRect.adjusted( -pw, -pw, pw, pw );
453
454 QPolygonF p( size );
455
456 std::memcpy( p.data(), points, size * sizeof( QPointF ) );
457 QwtPainter::drawPolyline( painter,
458 QwtClipper::clippedPolygonF( clipRect, p ) );
459
460 std::memcpy( p.data(), points + size, size * sizeof( QPointF ) );
461 QwtPainter::drawPolyline( painter,
462 QwtClipper::clippedPolygonF( clipRect, p ) );
463 }
464 else
465 {
466 QwtPainter::drawPolyline( painter, points, size );
467 QwtPainter::drawPolyline( painter, points + size, size );
468 }
469 }
470
471 painter->restore();
472 }
473
487 void QwtPlotIntervalCurve::drawSymbols(
488 QPainter* painter, const QwtIntervalSymbol& symbol,
489 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
490 const QRectF& canvasRect, int from, int to ) const
491 {
492 painter->save();
493
494 QPen pen = symbol.pen();
495 pen.setCapStyle( Qt::FlatCap );
496
497 painter->setPen( pen );
498 painter->setBrush( symbol.brush() );
499
500 const QRectF tr = QwtScaleMap::invTransform( xMap, yMap, canvasRect );
501
502 const double xMin = tr.left();
503 const double xMax = tr.right();
504 const double yMin = tr.top();
505 const double yMax = tr.bottom();
506
507 const bool doClip = m_data->paintAttributes & ClipSymbol;
508
509 for ( int i = from; i <= to; i++ )
510 {
511 const QwtIntervalSample s = sample( i );
512
513 if ( orientation() == Qt::Vertical )
514 {
515 if ( !doClip || qwtIsVSampleInside( s, xMin, xMax, yMin, yMax ) )
516 {
517 const double x = xMap.transform( s.value );
518 const double y1 = yMap.transform( s.interval.minValue() );
519 const double y2 = yMap.transform( s.interval.maxValue() );
520
521 symbol.draw( painter, orientation(),
522 QPointF( x, y1 ), QPointF( x, y2 ) );
523 }
524 }
525 else
526 {
527 if ( !doClip || qwtIsHSampleInside( s, xMin, xMax, yMin, yMax ) )
528 {
529 const double y = yMap.transform( s.value );
530 const double x1 = xMap.transform( s.interval.minValue() );
531 const double x2 = xMap.transform( s.interval.maxValue() );
532
533 symbol.draw( painter, orientation(),
534 QPointF( x1, y ), QPointF( x2, y ) );
535 }
536 }
537 }
538
539 painter->restore();
540 }
541
554 QwtGraphic QwtPlotIntervalCurve::legendIcon(
555 int index, const QSizeF& size ) const
556 {
557 Q_UNUSED( index );
558
559 if ( size.isEmpty() )
560 return QwtGraphic();
561
562 QwtGraphic icon;
563 icon.setDefaultSize( size );
564 icon.setRenderHint( QwtGraphic::RenderPensUnscaled, true );
565
566 QPainter painter( &icon );
567 painter.setRenderHint( QPainter::Antialiasing,
568 testRenderHint( QwtPlotItem::RenderAntialiased ) );
569
570 if ( m_data->style == Tube )
571 {
572 QRectF r( 0, 0, size.width(), size.height() );
573 painter.fillRect( r, m_data->brush );
574 }
575
576 if ( m_data->symbol &&
577 ( m_data->symbol->style() != QwtIntervalSymbol::NoSymbol ) )
578 {
579 QPen pen = m_data->symbol->pen();
580 pen.setWidthF( pen.widthF() );
581 pen.setCapStyle( Qt::FlatCap );
582
583 painter.setPen( pen );
584 painter.setBrush( m_data->symbol->brush() );
585
586 if ( orientation() == Qt::Vertical )
587 {
588 const double x = 0.5 * size.width();
589
590 m_data->symbol->draw( &painter, orientation(),
591 QPointF( x, 0 ), QPointF( x, size.height() - 1.0 ) );
592 }
593 else
594 {
595 const double y = 0.5 * size.height();
596
597 m_data->symbol->draw( &painter, orientation(),
598 QPointF( 0.0, y ), QPointF( size.width() - 1.0, y ) );
599 }
600 }
601
602 return icon;
603 }
QVector
Definition: qwt_clipper.h:23
QwtGraphic
A paint device for scalable graphics.
Definition: qwt_graphic.h:76
QwtGraphic::RenderPensUnscaled
@ RenderPensUnscaled
Definition: qwt_graphic.h:96
QwtGraphic::setRenderHint
void setRenderHint(RenderHint, bool on=true)
Definition: qwt_graphic.cpp:443
QwtGraphic::setDefaultSize
void setDefaultSize(const QSizeF &)
Set a default size.
Definition: qwt_graphic.cpp:553
QwtInterval::minValue
double minValue() const
Definition: qwt_interval.h:192
QwtInterval::maxValue
double maxValue() const
Definition: qwt_interval.h:198
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
QwtIntervalSeriesData
Interface for iterating over an array of intervals.
Definition: qwt_series_data.h:230
QwtIntervalSymbol
A drawing primitive for displaying an interval like an error bar.
Definition: qwt_interval_symbol.h:28
QwtIntervalSymbol::draw
virtual void draw(QPainter *, Qt::Orientation, const QPointF &from, const QPointF &to) const
Definition: qwt_interval_symbol.cpp:200
QwtIntervalSymbol::pen
const QPen & pen() const
Definition: qwt_interval_symbol.cpp:185
QwtIntervalSymbol::NoSymbol
@ NoSymbol
No Style. The symbol cannot be drawn.
Definition: qwt_interval_symbol.h:34
QwtIntervalSymbol::brush
const QBrush & brush() const
Definition: qwt_interval_symbol.cpp:146
QwtPainter::drawPolygon
static void drawPolygon(QPainter *, const QPolygonF &)
Wrapper for QPainter::drawPolygon()
Definition: qwt_painter.cpp:561
QwtPainter::drawPolyline
static void drawPolyline(QPainter *, const QPolygonF &)
Wrapper for QPainter::drawPolyline()
Definition: qwt_painter.cpp:578
QwtPainter::effectivePenWidth
static qreal effectivePenWidth(const QPen &)
Definition: qwt_painter.h:201
QwtPainter::roundingAlignment
static bool roundingAlignment()
Definition: qwt_painter.h:183
QwtPlotIntervalCurve
QwtPlotIntervalCurve represents a series of samples, where each value is associated with an interval ...
Definition: qwt_plot_intervalcurve.h:30
QwtPlotIntervalCurve::rtti
virtual int rtti() const override
Definition: qwt_plot_intervalcurve.cpp:115
QwtPlotIntervalCurve::~QwtPlotIntervalCurve
virtual ~QwtPlotIntervalCurve()
Destructor.
Definition: qwt_plot_intervalcurve.cpp:97
QwtPlotIntervalCurve::PaintAttributes
QFlags< PaintAttribute > PaintAttributes
Definition: qwt_plot_intervalcurve.h:77
QwtPlotIntervalCurve::setBrush
void setBrush(const QBrush &)
Definition: qwt_plot_intervalcurve.cpp:276
QwtPlotIntervalCurve::QwtPlotIntervalCurve
QwtPlotIntervalCurve(const QString &title=QString())
Definition: qwt_plot_intervalcurve.cpp:90
QwtPlotIntervalCurve::PaintAttribute
PaintAttribute
Definition: qwt_plot_intervalcurve.h:65
QwtPlotIntervalCurve::ClipSymbol
@ ClipSymbol
Check if a symbol is on the plot canvas before painting it.
Definition: qwt_plot_intervalcurve.h:74
QwtPlotIntervalCurve::ClipPolygons
@ ClipPolygons
Definition: qwt_plot_intervalcurve.h:71
QwtPlotIntervalCurve::setPen
void setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
Definition: qwt_plot_intervalcurve.cpp:238
QwtPlotIntervalCurve::legendIcon
virtual QwtGraphic legendIcon(int index, const QSizeF &) const override
Definition: qwt_plot_intervalcurve.cpp:554
QwtPlotIntervalCurve::boundingRect
virtual QRectF boundingRect() const override
Definition: qwt_plot_intervalcurve.cpp:300
QwtPlotIntervalCurve::setSymbol
void setSymbol(const QwtIntervalSymbol *)
Definition: qwt_plot_intervalcurve.cpp:204
QwtPlotIntervalCurve::style
CurveStyle style() const
Definition: qwt_plot_intervalcurve.cpp:193
QwtPlotIntervalCurve::setStyle
void setStyle(CurveStyle style)
Definition: qwt_plot_intervalcurve.cpp:178
QwtPlotIntervalCurve::init
void init()
Initialize internal members.
Definition: qwt_plot_intervalcurve.cpp:103
QwtPlotIntervalCurve::brush
const QBrush & brush() const
Definition: qwt_plot_intervalcurve.cpp:291
QwtPlotIntervalCurve::drawSymbols
virtual void drawSymbols(QPainter *, const QwtIntervalSymbol &, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
Definition: qwt_plot_intervalcurve.cpp:487
QwtPlotIntervalCurve::CurveStyle
CurveStyle
Curve styles. The default setting is QwtPlotIntervalCurve::Tube.
Definition: qwt_plot_intervalcurve.h:39
QwtPlotIntervalCurve::NoCurve
@ NoCurve
Definition: qwt_plot_intervalcurve.h:43
QwtPlotIntervalCurve::Tube
@ Tube
Definition: qwt_plot_intervalcurve.h:50
QwtPlotIntervalCurve::symbol
const QwtIntervalSymbol * symbol() const
Definition: qwt_plot_intervalcurve.cpp:220
QwtPlotIntervalCurve::pen
const QPen & pen() const
Definition: qwt_plot_intervalcurve.cpp:263
QwtPlotIntervalCurve::setPaintAttribute
void setPaintAttribute(PaintAttribute, bool on=true)
Definition: qwt_plot_intervalcurve.cpp:127
QwtPlotIntervalCurve::setSamples
void setSamples(const QVector< QwtIntervalSample > &)
Definition: qwt_plot_intervalcurve.cpp:150
QwtPlotIntervalCurve::drawTube
virtual void drawTube(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
Definition: qwt_plot_intervalcurve.cpp:371
QwtPlotIntervalCurve::drawSeries
virtual void drawSeries(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const override
Definition: qwt_plot_intervalcurve.cpp:322
QwtPlotIntervalCurve::testPaintAttribute
bool testPaintAttribute(PaintAttribute) const
Definition: qwt_plot_intervalcurve.cpp:140
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::Rtti_PlotIntervalCurve
@ Rtti_PlotIntervalCurve
For QwtPlotIntervalCurve.
Definition: qwt_plot_item.h:99
QwtPlotItem::RenderAntialiased
@ RenderAntialiased
Enable antialiasing.
Definition: qwt_plot_item.h:206
QwtPlotItem::testRenderHint
bool testRenderHint(RenderHint) const
Definition: qwt_plot_item.cpp:332
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
QwtPlotSeriesItem::boundingRect
virtual QRectF boundingRect() const override
Definition: qwt_plot_seriesitem.cpp:97
QwtScaleMap
A scale map.
Definition: qwt_scale_map.h:27
QwtScaleMap::transform
double transform(double s) const
Definition: qwt_scale_map.h:137
QwtScaleMap::invTransform
double invTransform(double p) const
Definition: qwt_scale_map.h:154
QwtSeriesData
Abstract interface for iterating over samples.
Definition: qwt_series_data.h:50
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
QwtClipper::clippedPolygonF
QWT_EXPORT QPolygonF clippedPolygonF(const QRectF &, const QPolygonF &, bool closePolygon=false)
Definition: qwt_clipper.cpp:455