qwt_plot_intervalcurve.cpp
Go to the documentation of this file.
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
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 
48 {
49 public:
52  symbol( NULL ),
53  pen( Qt::black ),
54  brush( Qt::white )
55  {
58 
59  pen.setCapStyle( Qt::FlatCap );
60  }
61 
63  {
64  delete symbol;
65  }
66 
69 
70  QPen pen;
71  QBrush brush;
72 
74 };
75 
81  QwtPlotSeriesItem( title )
82 {
83  init();
84 }
85 
91  QwtPlotSeriesItem( QwtText( title ) )
92 {
93  init();
94 }
95 
98 {
99  delete d_data;
100 }
101 
104 {
107 
108  d_data = new PrivateData;
110 
111  setZ( 19.0 );
112 }
113 
116 {
118 }
119 
128  PaintAttribute attribute, bool on )
129 {
130  if ( on )
131  d_data->paintAttributes |= attribute;
132  else
133  d_data->paintAttributes &= ~attribute;
134 }
135 
141  PaintAttribute attribute ) const
142 {
143  return ( d_data->paintAttributes & attribute );
144 }
145 
151  const QVector<QwtIntervalSample> &samples )
152 {
153  setData( new QwtIntervalSeriesData( samples ) );
154 }
155 
168 {
169  setData( data );
170 }
171 
179 {
180  if ( style != d_data->style )
181  {
182  d_data->style = style;
183 
184  legendChanged();
185  itemChanged();
186  }
187 }
188 
194 {
195  return d_data->style;
196 }
197 
205 {
206  if ( symbol != d_data->symbol )
207  {
208  delete d_data->symbol;
209  d_data->symbol = symbol;
210 
211  legendChanged();
212  itemChanged();
213  }
214 }
215 
221 {
222  return d_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 
249 {
250  if ( pen != d_data->pen )
251  {
252  d_data->pen = pen;
253 
254  legendChanged();
255  itemChanged();
256  }
257 }
258 
263 const QPen& QwtPlotIntervalCurve::pen() const
264 {
265  return d_data->pen;
266 }
267 
277 {
278  if ( brush != d_data->brush )
279  {
280  d_data->brush = brush;
281 
282  legendChanged();
283  itemChanged();
284  }
285 }
286 
291 const QBrush& QwtPlotIntervalCurve::brush() const
292 {
293  return d_data->brush;
294 }
295 
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 ( d_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 ( d_data->symbol &&
348  {
349  drawSymbols( painter, *d_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 ( d_data->brush.style() != Qt::NoBrush )
426  {
427  painter->setPen( QPen( Qt::NoPen ) );
428  painter->setBrush( d_data->brush );
429 
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 ( d_data->pen.style() != Qt::NoPen )
445  {
446  painter->setPen( d_data->pen );
447  painter->setBrush( Qt::NoBrush );
448 
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 
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 = d_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 
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 );
565 
566  QPainter painter( &icon );
567  painter.setRenderHint( QPainter::Antialiasing,
569 
570  if ( d_data->style == Tube )
571  {
572  QRectF r( 0, 0, size.width(), size.height() );
573  painter.fillRect( r, d_data->brush );
574  }
575 
576  if ( d_data->symbol &&
578  {
579  QPen pen = d_data->symbol->pen();
580  pen.setWidthF( pen.widthF() );
581  pen.setCapStyle( Qt::FlatCap );
582 
583  painter.setPen( pen );
584  painter.setBrush( d_data->symbol->brush() );
585 
586  if ( orientation() == Qt::Vertical )
587  {
588  const double x = 0.5 * size.width();
589 
590  d_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  d_data->symbol->draw( &painter, orientation(),
598  QPointF( 0.0, y ), QPointF( size.width() - 1.0, y ) );
599  }
600  }
601 
602  return icon;
603 }
virtual void legendChanged()
Qt::Orientation orientation() const
Enable antialiasing.
virtual void drawSymbols(QPainter *, const QwtIntervalSymbol &, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
void setSamples(const QVector< QwtIntervalSample > &)
double minValue() const
Definition: qwt_interval.h:190
virtual ~QwtPlotIntervalCurve()
Destructor.
QwtPlotIntervalCurve(const QString &title=QString())
QwtPlotIntervalCurve::PaintAttributes paintAttributes
const QPen & pen() const
static bool qwtIsHSampleInside(const QwtIntervalSample &sample, double xMin, double xMax, double yMin, double yMax)
void setData(QwtSeriesData< QwtIntervalSample > *series)
void setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
QwtSeriesData< QwtIntervalSample > * data()
static QPolygonF clippedPolygonF(const QRectF &, const QPolygonF &, bool closePolygon=false)
double maxValue() const
Definition: qwt_interval.h:196
void setRenderHint(RenderHint, bool on=true)
static qreal effectivePenWidth(const QPen &)
Definition: qwt_painter.h:199
void setDefaultSize(const QSizeF &)
Set a default size.
void setPaintAttribute(PaintAttribute, bool on=true)
The item is represented on the legend.
static bool qwtIsVSampleInside(const QwtIntervalSample &sample, double xMin, double xMax, double yMin, double yMax)
void setStyle(CurveStyle style)
const QBrush & brush() const
static void drawPolygon(QPainter *, const QPolygonF &)
Wrapper for QPainter::drawPolygon()
virtual void drawSeries(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QWT_OVERRIDE
bool testRenderHint(RenderHint) const
A sample of the types (x1-x2, y) or (x, y1-y2)
Definition: qwt_samples.h:20
virtual int rtti() const QWT_OVERRIDE
const QBrush & brush() const
A class representing a text.
Definition: qwt_text.h:51
A drawing primitive for displaying an interval like an error bar.
virtual void drawTube(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
void setZ(double z)
Set the z value.
bool testPaintAttribute(PaintAttribute) const
virtual QRectF boundingRect() const QWT_OVERRIDE
A paint device for scalable graphics.
Definition: qwt_graphic.h:75
For QwtPlotIntervalCurve.
Definition: qwt_plot_item.h:98
A scale map.
Definition: qwt_scale_map.h:26
double invTransform(double p) const
QwtIntervalSample sample(int index) const
virtual void itemChanged()
virtual QwtGraphic legendIcon(int index, const QSizeF &) const QWT_OVERRIDE
Interface for iterating over an array of intervals.
static void drawPolyline(QPainter *, const QPolygonF &)
Wrapper for QPainter::drawPolyline()
const QPen & pen() const
Check if a symbol is on the plot canvas before painting it.
void setBrush(const QBrush &)
double value
Value.
Definition: qwt_samples.h:31
virtual size_t dataSize() const QWT_OVERRIDE
QwtPlotIntervalCurve::CurveStyle style
void init()
Initialize internal members.
Base class for plot items representing a series of samples.
void setItemAttribute(ItemAttribute, bool on=true)
double transform(double s) const
void setSymbol(const QwtIntervalSymbol *)
virtual void draw(QPainter *, Qt::Orientation, const QPointF &from, const QPointF &to) const
QFlags< PaintAttribute > PaintAttributes
Paint attributes.
const QwtIntervalSymbol * symbol() const
No Style. The symbol cannot be drawn.
QwtPlotIntervalCurve represents a series of samples, where each value is associated with an interval ...
static bool roundingAlignment()
Definition: qwt_painter.h:181
virtual QRectF boundingRect() const QWT_OVERRIDE
const QwtText & title() const
QwtInterval interval
Interval.
Definition: qwt_samples.h:34
CurveStyle
Curve styles. The default setting is QwtPlotIntervalCurve::Tube.


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:48:10