qwt_plot_tradingcurve.cpp
/******************************************************************************
* Qwt Widget Library
* Copyright (C) 1997 Josef Wilgen
* Copyright (C) 2002 Uwe Rathmann
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Qwt License, Version 1.0
*****************************************************************************/
#include "qwt_plot_tradingcurve.h"
#include "qwt_scale_map.h"
#include "qwt_painter.h"
#include "qwt_text.h"
#include "qwt_graphic.h"
#include "qwt_math.h"
#include <qpainter.h>
static inline bool qwtIsSampleInside( const QwtOHLCSample& sample,
double tMin, double tMax, double vMin, double vMax )
{
const double t = sample.time;
const QwtInterval interval = sample.boundingInterval();
const bool isOffScreen = ( t < tMin ) || ( t > tMax )
|| ( interval.maxValue() < vMin ) || ( interval.minValue() > vMax );
return !isOffScreen;
}
class QwtPlotTradingCurve::PrivateData
{
public:
PrivateData()
: symbolStyle( QwtPlotTradingCurve::CandleStick )
, symbolExtent( 0.6 )
, minSymbolWidth( 2.0 )
, maxSymbolWidth( -1.0 )
, paintAttributes( QwtPlotTradingCurve::ClipSymbols )
{
symbolBrush[0] = QBrush( Qt::white );
symbolBrush[1] = QBrush( Qt::black );
}
QwtPlotTradingCurve::SymbolStyle symbolStyle;
double symbolExtent;
double minSymbolWidth;
double maxSymbolWidth;
QPen symbolPen;
QBrush symbolBrush[2]; // Increasing/Decreasing
QwtPlotTradingCurve::PaintAttributes paintAttributes;
};
QwtPlotTradingCurve::QwtPlotTradingCurve( const QwtText& title )
: QwtPlotSeriesItem( title )
{
init();
}
QwtPlotTradingCurve::QwtPlotTradingCurve( const QString& title )
: QwtPlotSeriesItem( QwtText( title ) )
{
init();
}
QwtPlotTradingCurve::~QwtPlotTradingCurve()
{
delete m_data;
}
void QwtPlotTradingCurve::init()
{
setItemAttribute( QwtPlotItem::Legend, true );
setItemAttribute( QwtPlotItem::AutoScale, true );
m_data = new PrivateData;
setData( new QwtTradingChartData() );
setZ( 19.0 );
}
int QwtPlotTradingCurve::rtti() const
{
return QwtPlotTradingCurve::Rtti_PlotTradingCurve;
}
void QwtPlotTradingCurve::setPaintAttribute(
PaintAttribute attribute, bool on )
{
if ( on )
m_data->paintAttributes |= attribute;
else
m_data->paintAttributes &= ~attribute;
}
bool QwtPlotTradingCurve::testPaintAttribute(
PaintAttribute attribute ) const
{
return ( m_data->paintAttributes & attribute );
}
void QwtPlotTradingCurve::setSamples(
const QVector< QwtOHLCSample >& samples )
{
setData( new QwtTradingChartData( samples ) );
}
void QwtPlotTradingCurve::setSamples(
QwtSeriesData< QwtOHLCSample >* data )
{
setData( data );
}
void QwtPlotTradingCurve::setSymbolStyle( SymbolStyle style )
{
if ( style != m_data->symbolStyle )
{
m_data->symbolStyle = style;
legendChanged();
itemChanged();
}
}
QwtPlotTradingCurve::SymbolStyle QwtPlotTradingCurve::symbolStyle() const
{
return m_data->symbolStyle;
}
void QwtPlotTradingCurve::setSymbolPen(
const QColor& color, qreal width, Qt::PenStyle style )
{
setSymbolPen( QPen( color, width, style ) );
}
void QwtPlotTradingCurve::setSymbolPen( const QPen& pen )
{
if ( pen != m_data->symbolPen )
{
m_data->symbolPen = pen;
legendChanged();
itemChanged();
}
}
QPen QwtPlotTradingCurve::symbolPen() const
{
return m_data->symbolPen;
}
void QwtPlotTradingCurve::setSymbolBrush(
Direction direction, const QBrush& brush )
{
// silencing -Wtautological-constant-out-of-range-compare
const int index = static_cast< int >( direction );
if ( index < 0 || index >= 2 )
return;
if ( brush != m_data->symbolBrush[ index ] )
{
m_data->symbolBrush[ index ] = brush;
legendChanged();
itemChanged();
}
}
QBrush QwtPlotTradingCurve::symbolBrush( Direction direction ) const
{
const int index = static_cast< int >( direction );
if ( index < 0 || index >= 2 )
return QBrush();
return m_data->symbolBrush[ index ];
}
void QwtPlotTradingCurve::setSymbolExtent( double extent )
{
extent = qwtMaxF( 0.0, extent );
if ( extent != m_data->symbolExtent )
{
m_data->symbolExtent = extent;
legendChanged();
itemChanged();
}
}
double QwtPlotTradingCurve::symbolExtent() const
{
return m_data->symbolExtent;
}
void QwtPlotTradingCurve::setMinSymbolWidth( double width )
{
width = qwtMaxF( width, 0.0 );
if ( width != m_data->minSymbolWidth )
{
m_data->minSymbolWidth = width;
legendChanged();
itemChanged();
}
}
double QwtPlotTradingCurve::minSymbolWidth() const
{
return m_data->minSymbolWidth;
}
void QwtPlotTradingCurve::setMaxSymbolWidth( double width )
{
if ( width != m_data->maxSymbolWidth )
{
m_data->maxSymbolWidth = width;
legendChanged();
itemChanged();
}
}
double QwtPlotTradingCurve::maxSymbolWidth() const
{
return m_data->maxSymbolWidth;
}
QRectF QwtPlotTradingCurve::boundingRect() const
{
QRectF rect = QwtPlotSeriesItem::boundingRect();
if ( orientation() == Qt::Vertical )
rect.setRect( rect.y(), rect.x(), rect.height(), rect.width() );
return rect;
}
void QwtPlotTradingCurve::drawSeries( QPainter* painter,
const QwtScaleMap& xMap, const QwtScaleMap& yMap,
const QRectF& canvasRect, int from, int to ) const
{
if ( to < 0 )
to = dataSize() - 1;
if ( from < 0 )
from = 0;
if ( from > to )
return;
painter->save();
if ( m_data->symbolStyle != QwtPlotTradingCurve::NoSymbol )
drawSymbols( painter, xMap, yMap, canvasRect, from, to );
painter->restore();
}
void QwtPlotTradingCurve::drawSymbols( QPainter* painter,
const QwtScaleMap& xMap, const QwtScaleMap& yMap,
const QRectF& canvasRect, int from, int to ) const
{
const QRectF tr = QwtScaleMap::invTransform( xMap, yMap, canvasRect );
const QwtScaleMap* timeMap, * valueMap;
double tMin, tMax, vMin, vMax;
const Qt::Orientation orient = orientation();
if ( orient == Qt::Vertical )
{
timeMap = &xMap;
valueMap = &yMap;
tMin = tr.left();
tMax = tr.right();
vMin = tr.top();
vMax = tr.bottom();
}
else
{
timeMap = &yMap;
valueMap = &xMap;
vMin = tr.left();
vMax = tr.right();
tMin = tr.top();
tMax = tr.bottom();
}
const bool inverted = timeMap->isInverting();
const bool doClip = m_data->paintAttributes & ClipSymbols;
const bool doAlign = QwtPainter::roundingAlignment( painter );
double symbolWidth = scaledSymbolWidth( xMap, yMap, canvasRect );
if ( doAlign )
symbolWidth = std::floor( 0.5 * symbolWidth ) * 2.0;
QPen pen = m_data->symbolPen;
pen.setCapStyle( Qt::FlatCap );
painter->setPen( pen );
for ( int i = from; i <= to; i++ )
{
const QwtOHLCSample s = sample( i );
if ( !doClip || qwtIsSampleInside( s, tMin, tMax, vMin, vMax ) )
{
QwtOHLCSample translatedSample;
translatedSample.time = timeMap->transform( s.time );
translatedSample.open = valueMap->transform( s.open );
translatedSample.high = valueMap->transform( s.high );
translatedSample.low = valueMap->transform( s.low );
translatedSample.close = valueMap->transform( s.close );
const int brushIndex = ( s.open < s.close )
? QwtPlotTradingCurve::Increasing
: QwtPlotTradingCurve::Decreasing;
if ( doAlign )
{
translatedSample.time = qRound( translatedSample.time );
translatedSample.open = qRound( translatedSample.open );
translatedSample.high = qRound( translatedSample.high );
translatedSample.low = qRound( translatedSample.low );
translatedSample.close = qRound( translatedSample.close );
}
switch( m_data->symbolStyle )
{
case Bar:
{
drawBar( painter, translatedSample,
orient, inverted, symbolWidth );
break;
}
case CandleStick:
{
painter->setBrush( m_data->symbolBrush[ brushIndex ] );
drawCandleStick( painter, translatedSample,
orient, symbolWidth );
break;
}
default:
{
if ( m_data->symbolStyle >= UserSymbol )
{
painter->setBrush( m_data->symbolBrush[ brushIndex ] );
drawUserSymbol( painter, m_data->symbolStyle,
translatedSample, orient, inverted, symbolWidth );
}
}
}
}
}
}
void QwtPlotTradingCurve::drawUserSymbol( QPainter* painter,
SymbolStyle symbolStyle, const QwtOHLCSample& sample,
Qt::Orientation orientation, bool inverted, double symbolWidth ) const
{
Q_UNUSED( painter )
Q_UNUSED( symbolStyle )
Q_UNUSED( orientation )
Q_UNUSED( inverted )
Q_UNUSED( symbolWidth )
Q_UNUSED( sample )
}
void QwtPlotTradingCurve::drawBar( QPainter* painter,
const QwtOHLCSample& sample, Qt::Orientation orientation,
bool inverted, double width ) const
{
double w2 = 0.5 * width;
if ( inverted )
w2 *= -1;
if ( orientation == Qt::Vertical )
{
QwtPainter::drawLine( painter,
sample.time, sample.low, sample.time, sample.high );
QwtPainter::drawLine( painter,
sample.time - w2, sample.open, sample.time, sample.open );
QwtPainter::drawLine( painter,
sample.time + w2, sample.close, sample.time, sample.close );
}
else
{
QwtPainter::drawLine( painter, sample.low, sample.time,
sample.high, sample.time );
QwtPainter::drawLine( painter,
sample.open, sample.time - w2, sample.open, sample.time );
QwtPainter::drawLine( painter,
sample.close, sample.time + w2, sample.close, sample.time );
}
}
void QwtPlotTradingCurve::drawCandleStick( QPainter* painter,
const QwtOHLCSample& sample, Qt::Orientation orientation,
double width ) const
{
const double t = sample.time;
const double v1 = qwtMinF( sample.low, sample.high );
const double v2 = qwtMinF( sample.open, sample.close );
const double v3 = qwtMaxF( sample.low, sample.high );
const double v4 = qwtMaxF( sample.open, sample.close );
if ( orientation == Qt::Vertical )
{
QwtPainter::drawLine( painter, t, v1, t, v2 );
QwtPainter::drawLine( painter, t, v3, t, v4 );
QRectF rect( t - 0.5 * width, sample.open,
width, sample.close - sample.open );
QwtPainter::drawRect( painter, rect );
}
else
{
QwtPainter::drawLine( painter, v1, t, v2, t );
QwtPainter::drawLine( painter, v3, t, v4, t );
const QRectF rect( sample.open, t - 0.5 * width,
sample.close - sample.open, width );
QwtPainter::drawRect( painter, rect );
}
}
QwtGraphic QwtPlotTradingCurve::legendIcon( int index,
const QSizeF& size ) const
{
Q_UNUSED( index );
return defaultIcon( m_data->symbolPen.color(), size );
}
double QwtPlotTradingCurve::scaledSymbolWidth(
const QwtScaleMap& xMap, const QwtScaleMap& yMap,
const QRectF& canvasRect ) const
{
Q_UNUSED( canvasRect );
if ( m_data->maxSymbolWidth > 0.0 &&
m_data->minSymbolWidth >= m_data->maxSymbolWidth )
{
return m_data->minSymbolWidth;
}
const QwtScaleMap* map =
( orientation() == Qt::Vertical ) ? &xMap : &yMap;
const double pos = map->transform( map->s1() + m_data->symbolExtent );
double width = qAbs( pos - map->p1() );
width = qwtMaxF( width, m_data->minSymbolWidth );
if ( m_data->maxSymbolWidth > 0.0 )
width = qwtMinF( width, m_data->maxSymbolWidth );
return width;
}
QVector
Definition: qwt_clipper.h:23
QwtGraphic
A paint device for scalable graphics.
Definition: qwt_graphic.h:76
QwtInterval
A class representing an interval.
Definition: qwt_interval.h:23
QwtInterval::minValue
double minValue() const
Definition: qwt_interval.h:192
QwtInterval::maxValue
double maxValue() const
Definition: qwt_interval.h:198
QwtOHLCSample
Open-High-Low-Close sample used in financial charts.
Definition: qwt_samples.h:144
QwtOHLCSample::high
double high
Highest price.
Definition: qwt_samples.h:164
QwtOHLCSample::open
double open
Opening price.
Definition: qwt_samples.h:161
QwtOHLCSample::close
double close
Closing price.
Definition: qwt_samples.h:170
QwtOHLCSample::time
double time
Definition: qwt_samples.h:158
QwtOHLCSample::boundingInterval
QwtInterval boundingInterval() const
Calculate the bounding interval of the OHLC values.
Definition: qwt_samples.h:220
QwtOHLCSample::low
double low
Lowest price.
Definition: qwt_samples.h:167
QwtPainter::drawRect
static void drawRect(QPainter *, qreal x, qreal y, qreal w, qreal h)
Wrapper for QPainter::drawRect()
Definition: qwt_painter.cpp:347
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
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_PlotTradingCurve
@ Rtti_PlotTradingCurve
For QwtPlotTradingCurve.
Definition: qwt_plot_item.h:111
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
QwtPlotTradingCurve
QwtPlotTradingCurve illustrates movements in the price of a financial instrument over time.
Definition: qwt_plot_tradingcurve.h:40
QwtPlotTradingCurve::setSymbolStyle
void setSymbolStyle(SymbolStyle style)
Definition: qwt_plot_tradingcurve.cpp:162
QwtPlotTradingCurve::symbolBrush
QBrush symbolBrush(Direction) const
Definition: qwt_plot_tradingcurve.cpp:262
QwtPlotTradingCurve::symbolPen
QPen symbolPen() const
Definition: qwt_plot_tradingcurve.cpp:224
QwtPlotTradingCurve::testPaintAttribute
bool testPaintAttribute(PaintAttribute) const
Definition: qwt_plot_tradingcurve.cpp:120
QwtPlotTradingCurve::drawBar
void drawBar(QPainter *, const QwtOHLCSample &, Qt::Orientation, bool inverted, double width) const
Draw a bar.
Definition: qwt_plot_tradingcurve.cpp:562
QwtPlotTradingCurve::symbolStyle
SymbolStyle symbolStyle() const
Definition: qwt_plot_tradingcurve.cpp:177
QwtPlotTradingCurve::drawCandleStick
void drawCandleStick(QPainter *, const QwtOHLCSample &, Qt::Orientation, double width) const
Draw a candle stick.
Definition: qwt_plot_tradingcurve.cpp:601
QwtPlotTradingCurve::PaintAttributes
QFlags< PaintAttribute > PaintAttributes
Definition: qwt_plot_tradingcurve.h:101
QwtPlotTradingCurve::minSymbolWidth
double minSymbolWidth() const
Definition: qwt_plot_tradingcurve.cpp:328
QwtPlotTradingCurve::drawUserSymbol
virtual void drawUserSymbol(QPainter *, SymbolStyle, const QwtOHLCSample &, Qt::Orientation, bool inverted, double symbolWidth) const
Draw a symbol for a symbol style >= UserSymbol.
Definition: qwt_plot_tradingcurve.cpp:534
QwtPlotTradingCurve::setSamples
void setSamples(const QVector< QwtOHLCSample > &)
Definition: qwt_plot_tradingcurve.cpp:132
QwtPlotTradingCurve::legendIcon
virtual QwtGraphic legendIcon(int index, const QSizeF &) const override
Definition: qwt_plot_tradingcurve.cpp:642
QwtPlotTradingCurve::boundingRect
virtual QRectF boundingRect() const override
Definition: qwt_plot_tradingcurve.cpp:365
QwtPlotTradingCurve::drawSymbols
virtual void drawSymbols(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const
Definition: qwt_plot_tradingcurve.cpp:420
QwtPlotTradingCurve::drawSeries
virtual void drawSeries(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const override
Definition: qwt_plot_tradingcurve.cpp:387
QwtPlotTradingCurve::setMinSymbolWidth
void setMinSymbolWidth(double)
Definition: qwt_plot_tradingcurve.cpp:312
QwtPlotTradingCurve::maxSymbolWidth
double maxSymbolWidth() const
Definition: qwt_plot_tradingcurve.cpp:356
QwtPlotTradingCurve::~QwtPlotTradingCurve
virtual ~QwtPlotTradingCurve()
Destructor.
Definition: qwt_plot_tradingcurve.cpp:77
QwtPlotTradingCurve::init
void init()
Initialize internal members.
Definition: qwt_plot_tradingcurve.cpp:83
QwtPlotTradingCurve::setSymbolPen
void setSymbolPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
Definition: qwt_plot_tradingcurve.cpp:195
QwtPlotTradingCurve::setSymbolExtent
void setSymbolExtent(double)
Set the extent of the symbol.
Definition: qwt_plot_tradingcurve.cpp:284
QwtPlotTradingCurve::Direction
Direction
Direction of a price movement.
Definition: qwt_plot_tradingcurve.h:83
QwtPlotTradingCurve::Increasing
@ Increasing
The closing price is higher than the opening price.
Definition: qwt_plot_tradingcurve.h:85
QwtPlotTradingCurve::Decreasing
@ Decreasing
The closing price is lower than the opening price.
Definition: qwt_plot_tradingcurve.h:88
QwtPlotTradingCurve::setPaintAttribute
void setPaintAttribute(PaintAttribute, bool on=true)
Definition: qwt_plot_tradingcurve.cpp:107
QwtPlotTradingCurve::scaledSymbolWidth
virtual double scaledSymbolWidth(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const
Definition: qwt_plot_tradingcurve.cpp:664
QwtPlotTradingCurve::setSymbolBrush
void setSymbolBrush(Direction, const QBrush &)
Definition: qwt_plot_tradingcurve.cpp:238
QwtPlotTradingCurve::symbolExtent
double symbolExtent() const
Definition: qwt_plot_tradingcurve.cpp:301
QwtPlotTradingCurve::SymbolStyle
SymbolStyle
Symbol styles.
Definition: qwt_plot_tradingcurve.h:49
QwtPlotTradingCurve::Bar
@ Bar
Definition: qwt_plot_tradingcurve.h:59
QwtPlotTradingCurve::CandleStick
@ CandleStick
Definition: qwt_plot_tradingcurve.h:67
QwtPlotTradingCurve::UserSymbol
@ UserSymbol
Definition: qwt_plot_tradingcurve.h:76
QwtPlotTradingCurve::NoSymbol
@ NoSymbol
Nothing is displayed.
Definition: qwt_plot_tradingcurve.h:51
QwtPlotTradingCurve::rtti
virtual int rtti() const override
Definition: qwt_plot_tradingcurve.cpp:95
QwtPlotTradingCurve::setMaxSymbolWidth
void setMaxSymbolWidth(double)
Definition: qwt_plot_tradingcurve.cpp:341
QwtPlotTradingCurve::QwtPlotTradingCurve
QwtPlotTradingCurve(const QString &title=QString())
Definition: qwt_plot_tradingcurve.cpp:70
QwtPlotTradingCurve::PaintAttribute
PaintAttribute
Definition: qwt_plot_tradingcurve.h:96
QwtPlotTradingCurve::ClipSymbols
@ ClipSymbols
Check if a symbol is on the plot canvas before painting it.
Definition: qwt_plot_tradingcurve.h:98
QwtScaleMap
A scale map.
Definition: qwt_scale_map.h:27
QwtScaleMap::isInverting
bool isInverting() const
Definition: qwt_scale_map.h:164
QwtScaleMap::p1
double p1() const
Definition: qwt_scale_map.h:99
QwtScaleMap::transform
double transform(double s) const
Definition: qwt_scale_map.h:137
QwtScaleMap::s1
double s1() const
Definition: qwt_scale_map.h:83
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< QwtOHLCSample >::sample
QwtOHLCSample sample(int index) const
Definition: qwt_series_store.h:158
QwtSeriesStore< QwtOHLCSample >::dataSize
virtual size_t dataSize() const override
Definition: qwt_series_store.h:175
QwtSeriesStore< QwtOHLCSample >::data
QwtSeriesData< QwtOHLCSample > * data()
Definition: qwt_series_store.h:146
QwtSeriesStore< QwtOHLCSample >::setData
void setData(QwtSeriesData< QwtOHLCSample > *series)
Definition: qwt_series_store.h:164
QwtText
A class representing a text.
Definition: qwt_text.h:52
QwtTradingChartData
Definition: qwt_series_data.h:262