KD Chart 2  [rev.2.6]
KDChartStockDiagram.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 ** Copyright (C) 2001-2019 Klaralvdalens Datakonsult AB. All rights reserved.
3 **
4 ** This file is part of the KD Chart library.
5 **
6 ** Licensees holding valid commercial KD Chart licenses may use this file in
7 ** accordance with the KD Chart Commercial License Agreement provided with
8 ** the Software.
9 **
10 **
11 ** This file may be distributed and/or modified under the terms of the
12 ** GNU General Public License version 2 and version 3 as published by the
13 ** Free Software Foundation and appearing in the file LICENSE.GPL.txt included.
14 **
15 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 **
18 ** Contact info@kdab.com if any conditions of this licensing are not
19 ** clear to you.
20 **
21 **********************************************************************/
22 
23 #include "KDChartStockDiagram.h"
24 #include "KDChartStockDiagram_p.h"
25 
26 #include "KDChartPaintContext.h"
27 #include "KDChartPainterSaver_p.h"
28 
29 using namespace KDChart;
30 
31 #define d d_func()
32 
34  : AbstractCartesianDiagram( new Private(), parent, plane )
35 {
36  init();
37 }
38 
39 StockDiagram::~StockDiagram()
40 {
41 }
42 
46 void StockDiagram::init()
47 {
48  d->diagram = this;
49  d->compressor.setModel( attributesModel() );
50 
51  // Set properties to defaults
52  d->type = HighLowClose;
53  d->upTrendCandlestickBrush = QBrush( Qt::white );
54  d->downTrendCandlestickBrush = QBrush( Qt::black );
55  d->upTrendCandlestickPen = QPen( Qt::black );
56  d->downTrendCandlestickPen = QPen( Qt::black );
57 
58  d->lowHighLinePen = QPen( Qt::black );
60  //setDatasetDimension( 3 );
61 
62  setPen( QPen( Qt::black ) );
63 }
64 
70 {
71  d->type = type;
72  emit propertiesChanged();
73 }
74 
79 {
80  return d->type;
81 }
82 
84 {
86  qVariantFromValue( attr ),
88  emit propertiesChanged();
89 }
90 
92 {
94 }
95 
96 void StockDiagram::setStockBarAttributes( int column, const StockBarAttributes &attr )
97 {
98  d->setDatasetAttrs( column, qVariantFromValue( attr ), StockBarAttributesRole );
99  emit propertiesChanged();
100 }
101 
103 {
104  const QVariant attr( d->datasetAttrs( column, StockBarAttributesRole ) );
105  if ( attr.isValid() )
106  return attr.value<StockBarAttributes>();
107  return stockBarAttributes();
108 }
109 
116 {
118  qVariantFromValue( attr ),
120  emit propertiesChanged();
121 }
122 
129 {
131 }
132 
142 void StockDiagram::setThreeDBarAttributes( int column, const ThreeDBarAttributes &attr )
143 {
144  d->setDatasetAttrs( column, qVariantFromValue( attr ), StockBarAttributesRole );
145  emit propertiesChanged();
146 }
147 
158 {
159  const QVariant attr( d->datasetAttrs( column, ThreeDBarAttributesRole ) );
160  if ( attr.isValid() )
161  return attr.value<ThreeDBarAttributes>();
162  return threeDBarAttributes();
163 }
164 
165 
166 void StockDiagram::setLowHighLinePen( const QPen &pen )
167 {
168  d->lowHighLinePen = pen;
169 }
170 
171 QPen StockDiagram::lowHighLinePen() const
172 {
173  return d->lowHighLinePen;
174 }
175 
176 void StockDiagram::setLowHighLinePen( int column, const QPen &pen )
177 {
178  d->lowHighLinePens[column] = pen;
179 }
180 
181 QPen StockDiagram::lowHighLinePen( int column ) const
182 {
183  if ( d->lowHighLinePens.contains( column ) )
184  return d->lowHighLinePens[column];
185  return d->lowHighLinePen;
186 }
187 
189 {
190  d->upTrendCandlestickBrush = brush;
191 }
192 
194 {
195  return d->upTrendCandlestickBrush;
196 }
197 
199 {
200  d->downTrendCandlestickBrush = brush;
201 }
202 
204 {
205  return d->downTrendCandlestickBrush;
206 }
207 
208 void StockDiagram::setUpTrendCandlestickBrush( int column, const QBrush &brush )
209 {
210  d->upTrendCandlestickBrushes[column] = brush;
211 }
212 
213 QBrush StockDiagram::upTrendCandlestickBrush( int column ) const
214 {
215  if ( d->upTrendCandlestickBrushes.contains( column ) )
216  return d->upTrendCandlestickBrushes[column];
217  return d->upTrendCandlestickBrush;
218 }
219 
220 void StockDiagram::setDownTrendCandlestickBrush( int column, const QBrush &brush )
221 {
222  d->downTrendCandlestickBrushes[column] = brush;
223 }
224 
225 QBrush StockDiagram::downTrendCandlestickBrush( int column ) const
226 {
227  if ( d->downTrendCandlestickBrushes.contains( column ) )
228  return d->downTrendCandlestickBrushes[column];
229  return d->downTrendCandlestickBrush;
230 }
231 
232 
234 {
235  d->upTrendCandlestickPen = pen;
236 }
237 
239 {
240  return d->upTrendCandlestickPen;
241 }
242 
244 {
245  d->downTrendCandlestickPen = pen;
246 }
247 
249 {
250  return d->downTrendCandlestickPen;
251 }
252 
253 void StockDiagram::setUpTrendCandlestickPen( int column, const QPen &pen )
254 {
255  d->upTrendCandlestickPens[column] = pen;
256 }
257 
258 QPen StockDiagram::upTrendCandlestickPen( int column ) const
259 {
260  if ( d->upTrendCandlestickPens.contains( column ) )
261  return d->upTrendCandlestickPens[column];
262  return d->upTrendCandlestickPen;
263 }
264 
265 void StockDiagram::setDownTrendCandlestickPen( int column, const QPen &pen )
266 {
267  d->downTrendCandlestickPens[column] = pen;
268 }
269 
270 QPen StockDiagram::downTrendCandlestickPen( int column ) const
271 {
272  if ( d->downTrendCandlestickPens.contains( column ) )
273  return d->downTrendCandlestickPens[column];
274  return d->downTrendCandlestickPen;
275 }
276 
277 #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
278 const
279 #endif
280 int StockDiagram::numberOfAbscissaSegments() const { return 1; }
281 
282 #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
283 const
284 #endif
285 int StockDiagram::numberOfOrdinateSegments() const { return 1; }
286 
287 void StockDiagram::paint( PaintContext *context )
288 {
289  // Clear old reverse mapping data and create new
290  // reverse mapping scene
291  d->reverseMapper.clear();
292 
293  PainterSaver painterSaver( context->painter() );
294  const int rowCount = attributesModel()->rowCount( attributesModelRootIndex() );
295  const int divisor = ( d->type == OpenHighLowClose || d->type == Candlestick ) ? 4 : 3;
296  const int colCount = attributesModel()->columnCount( attributesModelRootIndex() ) / divisor;
297  for ( int col = 0; col < colCount; ++col )
298  {
299  for ( int row = 0; row < rowCount; row++ ) {
300  CartesianDiagramDataCompressor::DataPoint low;
301  CartesianDiagramDataCompressor::DataPoint high;
302  CartesianDiagramDataCompressor::DataPoint open;
303  CartesianDiagramDataCompressor::DataPoint close;
304  CartesianDiagramDataCompressor::DataPoint volume;
305 
306  if ( d->type == HighLowClose ) {
307  const CartesianDiagramDataCompressor::CachePosition highPos( row, col * divisor );
308  const CartesianDiagramDataCompressor::CachePosition lowPos( row, col * divisor + 1 );
309  const CartesianDiagramDataCompressor::CachePosition closePos( row, col * divisor + 2 );
310  low = d->compressor.data( lowPos );
311  high = d->compressor.data( highPos );
312  close = d->compressor.data( closePos );
313  } else if ( d->type == OpenHighLowClose || d->type == Candlestick ) {
314  const CartesianDiagramDataCompressor::CachePosition openPos( row, col * divisor );
315  const CartesianDiagramDataCompressor::CachePosition highPos( row, col * divisor + 1 );
316  const CartesianDiagramDataCompressor::CachePosition lowPos( row, col * divisor + 2 );
317  const CartesianDiagramDataCompressor::CachePosition closePos( row, col * divisor + 3 );
318  open = d->compressor.data( openPos );
319  low = d->compressor.data( lowPos );
320  high = d->compressor.data( highPos );
321  close = d->compressor.data( closePos );
322  }
323 
324 
325  switch ( d->type ) {
326  case HighLowClose:
327  open.hidden = true;
328  // Fall-through intended!
329  case OpenHighLowClose:
330  if ( close.index.isValid() && low.index.isValid() && high.index.isValid() )
331  d->drawOHLCBar( col, open, high, low, close, context );
332  break;
333  case Candlestick:
334  d->drawCandlestick( col, open, high, low, close, context );
335  break;
336  }
337  }
338  }
339 }
340 
341 void StockDiagram::resize( const QSizeF &size )
342 {
343  d->compressor.setResolution( static_cast< int >( size.width() * coordinatePlane()->zoomFactorX() ),
344  static_cast< int >( size.height() * coordinatePlane()->zoomFactorY() ) );
346  QAbstractItemView::resize( size.toSize() );
347 }
348 
349 qreal StockDiagram::threeDItemDepth( int column ) const
350 {
351  Q_UNUSED( column );
352  //FIXME: Implement threeD functionality
353  return 1.0;
354 }
355 
356 qreal StockDiagram::threeDItemDepth( const QModelIndex &index ) const
357 {
358  Q_UNUSED( index );
359  //FIXME: Implement threeD functionality
360  return 1.0;
361 }
362 
364 {
365  const int rowCount = attributesModel()->rowCount( attributesModelRootIndex() );
366  const int colCount = attributesModel()->columnCount( attributesModelRootIndex() );
367  qreal xMin = 0.0;
368  qreal xMax = rowCount;
369  qreal yMin = 0.0;
370  qreal yMax = 0.0;
371  for ( int row = 0; row < rowCount; row++ ) {
372  for ( int col = 0; col < colCount; col++ ) {
373  const CartesianDiagramDataCompressor::CachePosition pos( row, col );
374  const CartesianDiagramDataCompressor::DataPoint point = d->compressor.data( pos );
375  yMax = qMax( yMax, point.value );
376  yMin = qMin( yMin, point.value ); // FIXME: Can stock charts really have negative values?
377  }
378  }
379  return QPair<QPointF, QPointF>( QPointF( xMin, yMin ), QPointF( xMax, yMax ) );
380 }
381 
void setThreeDBarAttributes(const ThreeDBarAttributes &attr)
QPen downTrendCandlestickPen() const
virtual const QPair< QPointF, QPointF > calculateDataBoundaries() const
virtual void paint(PaintContext *paintContext)
Draw the diagram contents to the rectangle and painter, that are passed in as part of the paint conte...
int rowCount(const QModelIndex &) const
[reimplemented]
QPen lowHighLinePen() const
QPainter * painter() const
virtual AttributesModel * attributesModel() const
Returns the AttributesModel, that is used by this diagram.
QPen upTrendCandlestickPen() const
StockDiagram(QWidget *parent=0, CartesianCoordinatePlane *plane=0)
AbstractCoordinatePlane * coordinatePlane() const
The coordinate plane associated with the diagram.
QVariant modelData(int role) const
void setDatasetDimensionInternal(int dimension)
int columnCount(const QModelIndex &) const
[reimplemented]
void setDownTrendCandlestickBrush(const QBrush &brush)
StockBarAttributes stockBarAttributes() const
virtual const int numberOfOrdinateSegments() const
QBrush brush() const
Retrieve the brush to be used for painting datapoints globally.
void setPen(const QModelIndex &index, const QPen &pen)
Set the pen to be used, for painting the datapoint at the given index.
void setStockBarAttributes(const StockBarAttributes &attr)
Type type() const
virtual qreal threeDItemDepth(int column) const
void setDownTrendCandlestickPen(const QPen &pen)
#define d
void propertiesChanged()
Emitted upon change of a property of the Diagram.
void setType(Type type)
Base class for diagrams based on a cartesian coordianate system.
QBrush downTrendCandlestickBrush() const
Stores information about painting diagrams.
A set of 3D bar attributes.
void setUpTrendCandlestickBrush(const QBrush &brush)
QPen pen() const
Retrieve the pen to be used for painting datapoints globally.
virtual const int numberOfAbscissaSegments() const
QModelIndex attributesModelRootIndex() const
QBrush upTrendCandlestickBrush() const
void setLowHighLinePen(const QPen &pen)
void setUpTrendCandlestickPen(const QPen &pen)
ThreeDBarAttributes threeDBarAttributes() const
Class only listed here to document inheritance of some KDChart classes.
bool setModelData(const QVariant value, int role)
virtual void resize(const QSizeF &size)
Called by the widget&#39;s sizeEvent.
Attributes to customize the appearance of a column in a stock chart.

Klarälvdalens Datakonsult AB (KDAB)
Qt-related services and products
https://www.kdab.com/
https://www.kdab.com/products/kd-chart/