KD Chart 2  [rev.2.5.1]
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Pages
KDChartStockDiagram.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 ** Copyright (C) 2001-2013 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 
69 void StockDiagram::setType( Type type )
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 
188 void StockDiagram::setUpTrendCandlestickBrush( const QBrush &brush )
189 {
190  d->upTrendCandlestickBrush = brush;
191 }
192 
194 {
195  return d->upTrendCandlestickBrush;
196 }
197 
198 void StockDiagram::setDownTrendCandlestickBrush( const QBrush &brush )
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 
233 void StockDiagram::setUpTrendCandlestickPen( const QPen &pen )
234 {
235  d->upTrendCandlestickPen = pen;
236 }
237 
239 {
240  return d->upTrendCandlestickPen;
241 }
242 
243 void StockDiagram::setDownTrendCandlestickPen( const QPen &pen )
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 

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