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_clipper.h"
13 #include "qwt_painter.h"
14 #include <qpainter.h>
15 
16 static inline bool qwtIsSampleInside( const QwtOHLCSample &sample,
17  double tMin, double tMax, double vMin, double vMax )
18 {
19  const double t = sample.time;
20  const QwtInterval interval = sample.boundingInterval();
21 
22  const bool isOffScreen = ( t < tMin ) || ( t > tMax )
23  || ( interval.maxValue() < vMin ) || ( interval.minValue() > vMax );
24 
25  return !isOffScreen;
26 }
27 
29 {
30 public:
33  symbolExtent( 0.6 ),
34  minSymbolWidth( 2.0 ),
35  maxSymbolWidth( -1.0 ),
37  {
38  symbolBrush[0] = QBrush( Qt::white );
39  symbolBrush[1] = QBrush( Qt::black );
40  }
41 
43  double symbolExtent;
46 
47  QPen symbolPen;
48  QBrush symbolBrush[2]; // Increasing/Decreasing
49 
51 };
52 
58  QwtPlotSeriesItem( title )
59 {
60  init();
61 }
62 
68  QwtPlotSeriesItem( QwtText( title ) )
69 {
70  init();
71 }
72 
75 {
76  delete d_data;
77 }
78 
81 {
84 
85  d_data = new PrivateData;
87 
88  setZ( 19.0 );
89 }
90 
93 {
95 }
96 
105  PaintAttribute attribute, bool on )
106 {
107  if ( on )
108  d_data->paintAttributes |= attribute;
109  else
110  d_data->paintAttributes &= ~attribute;
111 }
112 
118  PaintAttribute attribute ) const
119 {
120  return ( d_data->paintAttributes & attribute );
121 }
122 
130  const QVector<QwtOHLCSample> &samples )
131 {
132  setData( new QwtTradingChartData( samples ) );
133 }
134 
147 {
148  setData( data );
149 }
150 
160 {
161  if ( style != d_data->symbolStyle )
162  {
163  d_data->symbolStyle = style;
164 
165  legendChanged();
166  itemChanged();
167  }
168 }
169 
175 {
176  return d_data->symbolStyle;
177 }
178 
193  const QColor &color, qreal width, Qt::PenStyle style )
194 {
195  setSymbolPen( QPen( color, width, style ) );
196 }
197 
206 void QwtPlotTradingCurve::setSymbolPen( const QPen &pen )
207 {
208  if ( pen != d_data->symbolPen )
209  {
210  d_data->symbolPen = pen;
211 
212  legendChanged();
213  itemChanged();
214  }
215 }
216 
222 {
223  return d_data->symbolPen;
224 }
225 
236  Direction direction, const QBrush &brush )
237 {
238  if ( brush != d_data->symbolBrush[ direction ] )
239  {
240  d_data->symbolBrush[ direction ] = brush;
241 
242  legendChanged();
243  itemChanged();
244  }
245 }
246 
255 {
256  return d_data->symbolBrush[ direction ];
257 }
258 
273 {
274  extent = qMax( 0.0, extent );
275  if ( extent != d_data->symbolExtent )
276  {
277  d_data->symbolExtent = extent;
278 
279  legendChanged();
280  itemChanged();
281  }
282 }
283 
290 {
291  return d_data->symbolExtent;
292 }
293 
301 {
302  width = qMax( width, 0.0 );
303  if ( width != d_data->minSymbolWidth )
304  {
305  d_data->minSymbolWidth = width;
306 
307  legendChanged();
308  itemChanged();
309  }
310 }
311 
317 {
318  return d_data->minSymbolWidth;
319 }
320 
330 {
331  if ( width != d_data->maxSymbolWidth )
332  {
333  d_data->maxSymbolWidth = width;
334 
335  legendChanged();
336  itemChanged();
337  }
338 }
339 
345 {
346  return d_data->maxSymbolWidth;
347 }
348 
354 {
355  QRectF rect = QwtPlotSeriesItem::boundingRect();
356  if ( rect.isValid() && orientation() == Qt::Vertical )
357  rect.setRect( rect.y(), rect.x(), rect.height(), rect.width() );
358 
359  return rect;
360 }
361 
375 void QwtPlotTradingCurve::drawSeries( QPainter *painter,
376  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
377  const QRectF &canvasRect, int from, int to ) const
378 {
379  if ( to < 0 )
380  to = dataSize() - 1;
381 
382  if ( from < 0 )
383  from = 0;
384 
385  if ( from > to )
386  return;
387 
388  painter->save();
389 
391  drawSymbols( painter, xMap, yMap, canvasRect, from, to );
392 
393  painter->restore();
394 }
395 
408 void QwtPlotTradingCurve::drawSymbols( QPainter *painter,
409  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
410  const QRectF &canvasRect, int from, int to ) const
411 {
412  const QRectF tr = QwtScaleMap::invTransform( xMap, yMap, canvasRect );
413 
414  const QwtScaleMap *timeMap, *valueMap;
415  double tMin, tMax, vMin, vMax;
416 
417  const Qt::Orientation orient = orientation();
418  if ( orient == Qt::Vertical )
419  {
420  timeMap = &xMap;
421  valueMap = &yMap;
422 
423  tMin = tr.left();
424  tMax = tr.right();
425  vMin = tr.top();
426  vMax = tr.bottom();
427  }
428  else
429  {
430  timeMap = &yMap;
431  valueMap = &xMap;
432 
433  vMin = tr.left();
434  vMax = tr.right();
435  tMin = tr.top();
436  tMax = tr.bottom();
437  }
438 
439  const bool inverted = timeMap->isInverting();
440  const bool doClip = d_data->paintAttributes & ClipSymbols;
441  const bool doAlign = QwtPainter::roundingAlignment( painter );
442 
443  double symbolWidth = scaledSymbolWidth( xMap, yMap, canvasRect );
444  if ( doAlign )
445  symbolWidth = qFloor( 0.5 * symbolWidth ) * 2.0;
446 
447  QPen pen = d_data->symbolPen;
448  pen.setCapStyle( Qt::FlatCap );
449 
450  painter->setPen( pen );
451 
452  for ( int i = from; i <= to; i++ )
453  {
454  const QwtOHLCSample s = sample( i );
455 
456  if ( !doClip || qwtIsSampleInside( s, tMin, tMax, vMin, vMax ) )
457  {
458  QwtOHLCSample translatedSample;
459 
460  translatedSample.time = timeMap->transform( s.time );
461  translatedSample.open = valueMap->transform( s.open );
462  translatedSample.high = valueMap->transform( s.high );
463  translatedSample.low = valueMap->transform( s.low );
464  translatedSample.close = valueMap->transform( s.close );
465 
466  const int brushIndex = ( s.open < s.close )
469 
470  if ( doAlign )
471  {
472  translatedSample.time = qRound( translatedSample.time );
473  translatedSample.open = qRound( translatedSample.open );
474  translatedSample.high = qRound( translatedSample.high );
475  translatedSample.low = qRound( translatedSample.low );
476  translatedSample.close = qRound( translatedSample.close );
477  }
478 
479  switch( d_data->symbolStyle )
480  {
481  case Bar:
482  {
483  drawBar( painter, translatedSample,
484  orient, inverted, symbolWidth );
485  break;
486  }
487  case CandleStick:
488  {
489  painter->setBrush( d_data->symbolBrush[ brushIndex ] );
490  drawCandleStick( painter, translatedSample,
491  orient, symbolWidth );
492  break;
493  }
494  default:
495  {
496  if ( d_data->symbolStyle >= UserSymbol )
497  {
498  painter->setBrush( d_data->symbolBrush[ brushIndex ] );
499  drawUserSymbol( painter, d_data->symbolStyle,
500  translatedSample, orient, inverted, symbolWidth );
501  }
502  }
503  }
504  }
505  }
506 }
507 
522 void QwtPlotTradingCurve::drawUserSymbol( QPainter *painter,
524  Qt::Orientation orientation, bool inverted, double symbolWidth ) const
525 {
526  Q_UNUSED( painter )
527  Q_UNUSED( symbolStyle )
528  Q_UNUSED( orientation )
529  Q_UNUSED( inverted )
530  Q_UNUSED( symbolWidth )
531  Q_UNUSED( sample )
532 }
533 
550 void QwtPlotTradingCurve::drawBar( QPainter *painter,
551  const QwtOHLCSample &sample, Qt::Orientation orientation,
552  bool inverted, double width ) const
553 {
554  double w2 = 0.5 * width;
555  if ( inverted )
556  w2 *= -1;
557 
558  if ( orientation == Qt::Vertical )
559  {
560  QwtPainter::drawLine( painter,
561  sample.time, sample.low, sample.time, sample.high );
562 
563  QwtPainter::drawLine( painter,
564  sample.time - w2, sample.open, sample.time, sample.open );
565  QwtPainter::drawLine( painter,
566  sample.time + w2, sample.close, sample.time, sample.close );
567  }
568  else
569  {
570  QwtPainter::drawLine( painter, sample.low, sample.time,
571  sample.high, sample.time );
572  QwtPainter::drawLine( painter,
573  sample.open, sample.time - w2, sample.open, sample.time );
574  QwtPainter::drawLine( painter,
575  sample.close, sample.time + w2, sample.close, sample.time );
576  }
577 }
578 
589 void QwtPlotTradingCurve::drawCandleStick( QPainter *painter,
590  const QwtOHLCSample &sample, Qt::Orientation orientation,
591  double width ) const
592 {
593  const double t = sample.time;
594  const double v1 = qMin( sample.low, sample.high );
595  const double v2 = qMin( sample.open, sample.close );
596  const double v3 = qMax( sample.low, sample.high );
597  const double v4 = qMax( sample.open, sample.close );
598 
599  if ( orientation == Qt::Vertical )
600  {
601  QwtPainter::drawLine( painter, t, v1, t, v2 );
602  QwtPainter::drawLine( painter, t, v3, t, v4 );
603 
604  QRectF rect( t - 0.5 * width, sample.open,
605  width, sample.close - sample.open );
606 
607  QwtPainter::drawRect( painter, rect );
608  }
609  else
610  {
611  QwtPainter::drawLine( painter, v1, t, v2, t );
612  QwtPainter::drawLine( painter, v3, t, v4, t );
613 
614  const QRectF rect( sample.open, t - 0.5 * width,
615  sample.close - sample.open, width );
616 
617  QwtPainter::drawRect( painter, rect );
618  }
619 }
620 
631  const QSizeF &size ) const
632 {
633  Q_UNUSED( index );
634  return defaultIcon( d_data->symbolPen.color(), size );
635 }
636 
653  const QwtScaleMap &xMap, const QwtScaleMap &yMap,
654  const QRectF &canvasRect ) const
655 {
656  Q_UNUSED( canvasRect );
657 
658  if ( d_data->maxSymbolWidth > 0.0 &&
660  {
661  return d_data->minSymbolWidth;
662  }
663 
664  const QwtScaleMap *map =
665  ( orientation() == Qt::Vertical ) ? &xMap : &yMap;
666 
667  const double pos = map->transform( map->s1() + d_data->symbolExtent );
668 
669  double width = qAbs( pos - map->p1() );
670 
671  width = qMax( width, d_data->minSymbolWidth );
672  if ( d_data->maxSymbolWidth > 0.0 )
673  width = qMin( width, d_data->maxSymbolWidth );
674 
675  return width;
676 }
virtual void legendChanged()
virtual size_t dataSize() const
Qt::Orientation orientation() const
double p1() const
Open-High-Low-Close sample used in financial charts.
Definition: qwt_samples.h:146
static void drawLine(QPainter *, double x1, double y1, double x2, double y2)
Wrapper for QPainter::drawLine()
Definition: qwt_painter.h:147
QwtInterval boundingInterval() const
Calculate the bounding interval of the OHLC values.
Definition: qwt_samples.h:224
QwtPlotTradingCurve(const QString &title=QString())
double s1() const
Definition: qwt_scale_map.h:85
virtual ~QwtPlotTradingCurve()
Destructor.
The closing price is lower than the opening price.
For QwtPlotTradingCurve.
A class representing an interval.
Definition: qwt_interval.h:26
double open
Opening price.
Definition: qwt_samples.h:164
double minValue() const
Definition: qwt_interval.h:193
XmlRpcServer s
void setData(QwtSeriesData< QwtOHLCSample > *series)
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.
bool testPaintAttribute(PaintAttribute) const
double maxValue() const
Definition: qwt_interval.h:199
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:167
The item is represented on the legend.
void setSymbolStyle(SymbolStyle style)
double low
Lowest price.
Definition: qwt_samples.h:170
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:173
static void drawRect(QPainter *, double x, double y, double w, double h)
Wrapper for QPainter::drawRect()
virtual void drawUserSymbol(QPainter *, SymbolStyle, const QwtOHLCSample &, Qt::Orientation, bool inverted, double width) const
Draw a symbol for a symbol style >= UserSymbol.
A class representing a text.
Definition: qwt_text.h:51
static bool qwtIsSampleInside(const QwtOHLCSample &sample, double tMin, double tMax, double vMin, double vMax)
void setZ(double z)
Set the z value.
A paint device for scalable graphics.
Definition: qwt_graphic.h:74
void setSamples(const QVector< QwtOHLCSample > &)
virtual QRectF boundingRect() const
void setSymbolExtent(double width)
Set the extent of the symbol.
virtual QRectF boundingRect() const
A scale map.
Definition: qwt_scale_map.h:30
double invTransform(double p) const
void drawBar(QPainter *painter, const QwtOHLCSample &, Qt::Orientation, bool inverted, double width) const
Draw a bar.
QwtOHLCSample sample(int index) const
virtual void itemChanged()
virtual QwtGraphic legendIcon(int index, const QSizeF &) const
SymbolStyle symbolStyle() const
QFlags< PaintAttribute > PaintAttributes
Paint attributes.
QBrush symbolBrush(Direction) const
void setSymbolBrush(Direction, const QBrush &)
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
int i
QwtPlotTradingCurve::PaintAttributes paintAttributes
virtual void drawSeries(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
QwtPlotTradingCurve illustrates movements in the price of a financial instrument over time...
virtual int rtti() const
void init()
Initialize internal members.
static bool roundingAlignment()
Definition: qwt_painter.h:176
Check if a symbol is on the plot canvas before painting it.
const QwtText & title() const


plotjuggler
Author(s): Davide Faconti
autogenerated on Sat Jul 6 2019 03:44:17