qwt_plot_tradingcurve.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_tradingcurve.h"
11 #include "qwt_scale_map.h"
12 #include "qwt_painter.h"
13 #include "qwt_text.h"
14 #include "qwt_graphic.h"
15 #include "qwt_math.h"
16 
17 #include <qpainter.h>
18 
19 static inline bool qwtIsSampleInside( const QwtOHLCSample &sample,
20  double tMin, double tMax, double vMin, double vMax )
21 {
22  const double t = sample.time;
23  const QwtInterval interval = sample.boundingInterval();
24 
25  const bool isOffScreen = ( t < tMin ) || ( t > tMax )
26  || ( interval.maxValue() < vMin ) || ( interval.minValue() > vMax );
27 
28  return !isOffScreen;
29 }
30 
32 {
33 public:
36  symbolExtent( 0.6 ),
37  minSymbolWidth( 2.0 ),
38  maxSymbolWidth( -1.0 ),
40  {
41  symbolBrush[0] = QBrush( Qt::white );
42  symbolBrush[1] = QBrush( Qt::black );
43  }
44 
46  double symbolExtent;
49 
50  QPen symbolPen;
51  QBrush symbolBrush[2]; // Increasing/Decreasing
52 
54 };
55 
61  QwtPlotSeriesItem( title )
62 {
63  init();
64 }
65 
71  QwtPlotSeriesItem( QwtText( title ) )
72 {
73  init();
74 }
75 
78 {
79  delete d_data;
80 }
81 
84 {
87 
88  d_data = new PrivateData;
90 
91  setZ( 19.0 );
92 }
93 
96 {
98 }
99 
108  PaintAttribute attribute, bool on )
109 {
110  if ( on )
111  d_data->paintAttributes |= attribute;
112  else
113  d_data->paintAttributes &= ~attribute;
114 }
115 
121  PaintAttribute attribute ) const
122 {
123  return ( d_data->paintAttributes & attribute );
124 }
125 
133  const QVector<QwtOHLCSample> &samples )
134 {
135  setData( new QwtTradingChartData( samples ) );
136 }
137 
150 {
151  setData( data );
152 }
153 
163 {
164  if ( style != d_data->symbolStyle )
165  {
166  d_data->symbolStyle = style;
167 
168  legendChanged();
169  itemChanged();
170  }
171 }
172 
178 {
179  return d_data->symbolStyle;
180 }
181 
196  const QColor &color, qreal width, Qt::PenStyle style )
197 {
198  setSymbolPen( QPen( color, width, style ) );
199 }
200 
209 void QwtPlotTradingCurve::setSymbolPen( const QPen &pen )
210 {
211  if ( pen != d_data->symbolPen )
212  {
213  d_data->symbolPen = pen;
214 
215  legendChanged();
216  itemChanged();
217  }
218 }
219 
225 {
226  return d_data->symbolPen;
227 }
228 
239  Direction direction, const QBrush &brush )
240 {
241  // silencing -Wtautological-constant-out-of-range-compare
242  const int index = static_cast< int >( direction );
243  if ( index < 0 || index >= 2 )
244  return;
245 
246  if ( brush != d_data->symbolBrush[ index ] )
247  {
248  d_data->symbolBrush[ index ] = brush;
249 
250  legendChanged();
251  itemChanged();
252  }
253 }
254 
263 {
264  const int index = static_cast< int >( direction );
265  if ( index < 0 || index >= 2 )
266  return QBrush();
267 
268  return d_data->symbolBrush[ index ];
269 }
270 
285 {
286  extent = qwtMaxF( 0.0, extent );
287  if ( extent != d_data->symbolExtent )
288  {
289  d_data->symbolExtent = extent;
290 
291  legendChanged();
292  itemChanged();
293  }
294 }
295 
302 {
303  return d_data->symbolExtent;
304 }
305 
313 {
314  width = qwtMaxF( width, 0.0 );
315  if ( width != d_data->minSymbolWidth )
316  {
317  d_data->minSymbolWidth = width;
318 
319  legendChanged();
320  itemChanged();
321  }
322 }
323 
329 {
330  return d_data->minSymbolWidth;
331 }
332 
342 {
343  if ( width != d_data->maxSymbolWidth )
344  {
345  d_data->maxSymbolWidth = width;
346 
347  legendChanged();
348  itemChanged();
349  }
350 }
351 
357 {
358  return d_data->maxSymbolWidth;
359 }
360 
366 {
367  QRectF rect = QwtPlotSeriesItem::boundingRect();
368  if ( orientation() == Qt::Vertical )
369  rect.setRect( rect.y(), rect.x(), rect.height(), rect.width() );
370 
371  return rect;
372 }
373 
387 void QwtPlotTradingCurve::drawSeries( QPainter *painter,
388  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
389  const QRectF &canvasRect, int from, int to ) const
390 {
391  if ( to < 0 )
392  to = dataSize() - 1;
393 
394  if ( from < 0 )
395  from = 0;
396 
397  if ( from > to )
398  return;
399 
400  painter->save();
401 
403  drawSymbols( painter, xMap, yMap, canvasRect, from, to );
404 
405  painter->restore();
406 }
407 
420 void QwtPlotTradingCurve::drawSymbols( QPainter *painter,
421  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
422  const QRectF &canvasRect, int from, int to ) const
423 {
424  const QRectF tr = QwtScaleMap::invTransform( xMap, yMap, canvasRect );
425 
426  const QwtScaleMap *timeMap, *valueMap;
427  double tMin, tMax, vMin, vMax;
428 
429  const Qt::Orientation orient = orientation();
430  if ( orient == Qt::Vertical )
431  {
432  timeMap = &xMap;
433  valueMap = &yMap;
434 
435  tMin = tr.left();
436  tMax = tr.right();
437  vMin = tr.top();
438  vMax = tr.bottom();
439  }
440  else
441  {
442  timeMap = &yMap;
443  valueMap = &xMap;
444 
445  vMin = tr.left();
446  vMax = tr.right();
447  tMin = tr.top();
448  tMax = tr.bottom();
449  }
450 
451  const bool inverted = timeMap->isInverting();
452  const bool doClip = d_data->paintAttributes & ClipSymbols;
453  const bool doAlign = QwtPainter::roundingAlignment( painter );
454 
455  double symbolWidth = scaledSymbolWidth( xMap, yMap, canvasRect );
456  if ( doAlign )
457  symbolWidth = std::floor( 0.5 * symbolWidth ) * 2.0;
458 
459  QPen pen = d_data->symbolPen;
460  pen.setCapStyle( Qt::FlatCap );
461 
462  painter->setPen( pen );
463 
464  for ( int i = from; i <= to; i++ )
465  {
466  const QwtOHLCSample s = sample( i );
467 
468  if ( !doClip || qwtIsSampleInside( s, tMin, tMax, vMin, vMax ) )
469  {
470  QwtOHLCSample translatedSample;
471 
472  translatedSample.time = timeMap->transform( s.time );
473  translatedSample.open = valueMap->transform( s.open );
474  translatedSample.high = valueMap->transform( s.high );
475  translatedSample.low = valueMap->transform( s.low );
476  translatedSample.close = valueMap->transform( s.close );
477 
478  const int brushIndex = ( s.open < s.close )
481 
482  if ( doAlign )
483  {
484  translatedSample.time = qRound( translatedSample.time );
485  translatedSample.open = qRound( translatedSample.open );
486  translatedSample.high = qRound( translatedSample.high );
487  translatedSample.low = qRound( translatedSample.low );
488  translatedSample.close = qRound( translatedSample.close );
489  }
490 
491  switch( d_data->symbolStyle )
492  {
493  case Bar:
494  {
495  drawBar( painter, translatedSample,
496  orient, inverted, symbolWidth );
497  break;
498  }
499  case CandleStick:
500  {
501  painter->setBrush( d_data->symbolBrush[ brushIndex ] );
502  drawCandleStick( painter, translatedSample,
503  orient, symbolWidth );
504  break;
505  }
506  default:
507  {
508  if ( d_data->symbolStyle >= UserSymbol )
509  {
510  painter->setBrush( d_data->symbolBrush[ brushIndex ] );
511  drawUserSymbol( painter, d_data->symbolStyle,
512  translatedSample, orient, inverted, symbolWidth );
513  }
514  }
515  }
516  }
517  }
518 }
519 
534 void QwtPlotTradingCurve::drawUserSymbol( QPainter *painter,
536  Qt::Orientation orientation, bool inverted, double symbolWidth ) const
537 {
538  Q_UNUSED( painter )
539  Q_UNUSED( symbolStyle )
540  Q_UNUSED( orientation )
541  Q_UNUSED( inverted )
542  Q_UNUSED( symbolWidth )
543  Q_UNUSED( sample )
544 }
545 
562 void QwtPlotTradingCurve::drawBar( QPainter *painter,
563  const QwtOHLCSample &sample, Qt::Orientation orientation,
564  bool inverted, double width ) const
565 {
566  double w2 = 0.5 * width;
567  if ( inverted )
568  w2 *= -1;
569 
570  if ( orientation == Qt::Vertical )
571  {
572  QwtPainter::drawLine( painter,
573  sample.time, sample.low, sample.time, sample.high );
574 
575  QwtPainter::drawLine( painter,
576  sample.time - w2, sample.open, sample.time, sample.open );
577  QwtPainter::drawLine( painter,
578  sample.time + w2, sample.close, sample.time, sample.close );
579  }
580  else
581  {
582  QwtPainter::drawLine( painter, sample.low, sample.time,
583  sample.high, sample.time );
584  QwtPainter::drawLine( painter,
585  sample.open, sample.time - w2, sample.open, sample.time );
586  QwtPainter::drawLine( painter,
587  sample.close, sample.time + w2, sample.close, sample.time );
588  }
589 }
590 
601 void QwtPlotTradingCurve::drawCandleStick( QPainter *painter,
602  const QwtOHLCSample &sample, Qt::Orientation orientation,
603  double width ) const
604 {
605  const double t = sample.time;
606  const double v1 = qwtMinF( sample.low, sample.high );
607  const double v2 = qwtMinF( sample.open, sample.close );
608  const double v3 = qwtMaxF( sample.low, sample.high );
609  const double v4 = qwtMaxF( sample.open, sample.close );
610 
611  if ( orientation == Qt::Vertical )
612  {
613  QwtPainter::drawLine( painter, t, v1, t, v2 );
614  QwtPainter::drawLine( painter, t, v3, t, v4 );
615 
616  QRectF rect( t - 0.5 * width, sample.open,
617  width, sample.close - sample.open );
618 
619  QwtPainter::drawRect( painter, rect );
620  }
621  else
622  {
623  QwtPainter::drawLine( painter, v1, t, v2, t );
624  QwtPainter::drawLine( painter, v3, t, v4, t );
625 
626  const QRectF rect( sample.open, t - 0.5 * width,
627  sample.close - sample.open, width );
628 
629  QwtPainter::drawRect( painter, rect );
630  }
631 }
632 
643  const QSizeF &size ) const
644 {
645  Q_UNUSED( index );
646  return defaultIcon( d_data->symbolPen.color(), size );
647 }
648 
665  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
666  const QRectF &canvasRect ) const
667 {
668  Q_UNUSED( canvasRect );
669 
670  if ( d_data->maxSymbolWidth > 0.0 &&
672  {
673  return d_data->minSymbolWidth;
674  }
675 
676  const QwtScaleMap *map =
677  ( orientation() == Qt::Vertical ) ? &xMap : &yMap;
678 
679  const double pos = map->transform( map->s1() + d_data->symbolExtent );
680 
681  double width = qAbs( pos - map->p1() );
682 
683  width = qwtMaxF( width, d_data->minSymbolWidth );
684  if ( d_data->maxSymbolWidth > 0.0 )
685  width = qwtMinF( width, d_data->maxSymbolWidth );
686 
687  return width;
688 }
virtual void legendChanged()
Qt::Orientation orientation() const
double p1() const
Definition: qwt_scale_map.h:99
Open-High-Low-Close sample used in financial charts.
Definition: qwt_samples.h:147
virtual void drawUserSymbol(QPainter *, SymbolStyle, const QwtOHLCSample &, Qt::Orientation, bool inverted, double symbolWidth) const
Draw a symbol for a symbol style >= UserSymbol.
QwtInterval boundingInterval() const
Calculate the bounding interval of the OHLC values.
Definition: qwt_samples.h:225
QwtPlotTradingCurve(const QString &title=QString())
double s1() const
Definition: qwt_scale_map.h:83
virtual ~QwtPlotTradingCurve()
Destructor.
The closing price is lower than the opening price.
For QwtPlotTradingCurve.
static void drawLine(QPainter *, qreal x1, qreal y1, qreal x2, qreal y2)
Wrapper for QPainter::drawLine()
Definition: qwt_painter.h:152
A class representing an interval.
Definition: qwt_interval.h:22
double open
Opening price.
Definition: qwt_samples.h:165
QWT_CONSTEXPR float qwtMaxF(float a, float b)
Definition: qwt_math.h:123
double minValue() const
Definition: qwt_interval.h:190
virtual int rtti() const QWT_OVERRIDE
void setData(QwtSeriesData< QwtOHLCSample > *series)
void drawBar(QPainter *, const QwtOHLCSample &, Qt::Orientation, bool inverted, double width) const
Draw a bar.
void setSymbolExtent(double)
Set the extent of the symbol.
Direction
Direction of a price movement.
QwtPlotTradingCurve::SymbolStyle symbolStyle
QwtSeriesData< QwtOHLCSample > * data()
QwtGraphic defaultIcon(const QBrush &, const QSizeF &) const
Return a default icon from a brush.
QWT_CONSTEXPR float qwtMinF(float a, float b)
Definition: qwt_math.h:99
bool testPaintAttribute(PaintAttribute) const
double maxValue() const
Definition: qwt_interval.h:196
void setPaintAttribute(PaintAttribute, bool on=true)
virtual double scaledSymbolWidth(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const
double high
Highest price.
Definition: qwt_samples.h:168
The item is represented on the legend.
void setSymbolStyle(SymbolStyle style)
double low
Lowest price.
Definition: qwt_samples.h:171
void drawCandleStick(QPainter *, const QwtOHLCSample &, Qt::Orientation, double width) const
Draw a candle stick.
The closing price is higher than the opening price.
double close
Closing price.
Definition: qwt_samples.h:174
A class representing a text.
Definition: qwt_text.h:51
static bool qwtIsSampleInside(const QwtOHLCSample &sample, double tMin, double tMax, double vMin, double vMax)
virtual QRectF boundingRect() const QWT_OVERRIDE
void setZ(double z)
Set the z value.
A paint device for scalable graphics.
Definition: qwt_graphic.h:75
void setSamples(const QVector< QwtOHLCSample > &)
A scale map.
Definition: qwt_scale_map.h:26
double invTransform(double p) const
QwtOHLCSample sample(int index) const
virtual QwtGraphic legendIcon(int index, const QSizeF &) const QWT_OVERRIDE
virtual void itemChanged()
static void drawRect(QPainter *, qreal x, qreal y, qreal w, qreal h)
Wrapper for QPainter::drawRect()
SymbolStyle symbolStyle() const
QFlags< PaintAttribute > PaintAttributes
Paint attributes.
QBrush symbolBrush(Direction) const
void setSymbolBrush(Direction, const QBrush &)
virtual size_t dataSize() const QWT_OVERRIDE
virtual void drawSymbols(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
Base class for plot items representing a series of samples.
void setItemAttribute(ItemAttribute, bool on=true)
bool isInverting() const
void setSymbolPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
double transform(double s) const
QwtPlotTradingCurve::PaintAttributes paintAttributes
QwtPlotTradingCurve illustrates movements in the price of a financial instrument over time...
void init()
Initialize internal members.
static bool roundingAlignment()
Definition: qwt_painter.h:181
Check if a symbol is on the plot canvas before painting it.
virtual QRectF boundingRect() const QWT_OVERRIDE
virtual void drawSeries(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const QWT_OVERRIDE
const QwtText & title() const


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