KChart

KChartStockDiagram.cpp
1/*
2 * SPDX-FileCopyrightText: 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved.
3 *
4 * This file is part of the KD Chart library.
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9#include "KChartStockDiagram.h"
10#include "KChartStockDiagram_p.h"
11
12#include "KChartPaintContext.h"
13#include "KChartPainterSaver_p.h"
14
15using namespace KChart;
16
17#define d d_func()
18
19StockDiagram::StockDiagram( QWidget *parent, CartesianCoordinatePlane *plane )
20 : AbstractCartesianDiagram( new Private(), parent, plane )
21{
22 init();
23}
24
25StockDiagram::~StockDiagram()
26{
27}
28
29/*
30 * Initializes the diagram
31 */
32void StockDiagram::init()
33{
34 d->diagram = this;
35 d->compressor.setModel( attributesModel() );
36
37 // Set properties to defaults
38 d->type = HighLowClose;
39 d->upTrendCandlestickBrush = QBrush( Qt::white );
40 d->downTrendCandlestickBrush = QBrush( Qt::black );
41 d->upTrendCandlestickPen = QPen( Qt::black );
42 d->downTrendCandlestickPen = QPen( Qt::black );
43
44 d->lowHighLinePen = QPen( Qt::black );
45 setDatasetDimensionInternal( 3 );
46 //setDatasetDimension( 3 );
47
48 setPen( QPen( Qt::black ) );
49}
50
51void StockDiagram::setType( Type type )
52{
53 d->type = type;
55}
56
57StockDiagram::Type StockDiagram::type() const
58{
59 return d->type;
60}
61
62void StockDiagram::setStockBarAttributes( const StockBarAttributes &attr )
63{
64 attributesModel()->setModelData(
65 QVariant::fromValue( attr ),
66 StockBarAttributesRole );
68}
69
70StockBarAttributes StockDiagram::stockBarAttributes() const
71{
72 return attributesModel()->modelData( StockBarAttributesRole ).value<StockBarAttributes>();
73}
74
75void StockDiagram::setStockBarAttributes( int column, const StockBarAttributes &attr )
76{
77 d->setDatasetAttrs( column, QVariant::fromValue( attr ), StockBarAttributesRole );
79}
80
81StockBarAttributes StockDiagram::stockBarAttributes( int column ) const
82{
83 const QVariant attr( d->datasetAttrs( column, StockBarAttributesRole ) );
84 if ( attr.isValid() )
85 return attr.value<StockBarAttributes>();
86 return stockBarAttributes();
87}
88
89void StockDiagram::setThreeDBarAttributes( const ThreeDBarAttributes &attr )
90{
91 attributesModel()->setModelData(
92 QVariant::fromValue( attr ),
93 ThreeDBarAttributesRole );
95}
96
97ThreeDBarAttributes StockDiagram::threeDBarAttributes() const
98{
99 return attributesModel()->modelData( ThreeDBarAttributesRole ).value<ThreeDBarAttributes>();
100}
101
102void StockDiagram::setThreeDBarAttributes( int column, const ThreeDBarAttributes &attr )
103{
104 d->setDatasetAttrs( column, QVariant::fromValue( attr ), StockBarAttributesRole );
106}
107
108ThreeDBarAttributes StockDiagram::threeDBarAttributes( int column ) const
109{
110 const QVariant attr( d->datasetAttrs( column, ThreeDBarAttributesRole ) );
111 if ( attr.isValid() )
112 return attr.value<ThreeDBarAttributes>();
113 return threeDBarAttributes();
114}
115
116
117void StockDiagram::setLowHighLinePen( const QPen &pen )
118{
119 d->lowHighLinePen = pen;
120}
121
122QPen StockDiagram::lowHighLinePen() const
123{
124 return d->lowHighLinePen;
125}
126
127void StockDiagram::setLowHighLinePen( int column, const QPen &pen )
128{
129 d->lowHighLinePens[column] = pen;
130}
131
132QPen StockDiagram::lowHighLinePen( int column ) const
133{
134 if ( d->lowHighLinePens.contains( column ) )
135 return d->lowHighLinePens[column];
136 return d->lowHighLinePen;
137}
138
139void StockDiagram::setUpTrendCandlestickBrush( const QBrush &brush )
140{
141 d->upTrendCandlestickBrush = brush;
142}
143
144QBrush StockDiagram::upTrendCandlestickBrush() const
145{
146 return d->upTrendCandlestickBrush;
147}
148
149void StockDiagram::setDownTrendCandlestickBrush( const QBrush &brush )
150{
151 d->downTrendCandlestickBrush = brush;
152}
153
154QBrush StockDiagram::downTrendCandlestickBrush() const
155{
156 return d->downTrendCandlestickBrush;
157}
158
159void StockDiagram::setUpTrendCandlestickBrush( int column, const QBrush &brush )
160{
161 d->upTrendCandlestickBrushes[column] = brush;
162}
163
164QBrush StockDiagram::upTrendCandlestickBrush( int column ) const
165{
166 if ( d->upTrendCandlestickBrushes.contains( column ) )
167 return d->upTrendCandlestickBrushes[column];
168 return d->upTrendCandlestickBrush;
169}
170
171void StockDiagram::setDownTrendCandlestickBrush( int column, const QBrush &brush )
172{
173 d->downTrendCandlestickBrushes[column] = brush;
174}
175
176QBrush StockDiagram::downTrendCandlestickBrush( int column ) const
177{
178 if ( d->downTrendCandlestickBrushes.contains( column ) )
179 return d->downTrendCandlestickBrushes[column];
180 return d->downTrendCandlestickBrush;
181}
182
183
184void StockDiagram::setUpTrendCandlestickPen( const QPen &pen )
185{
186 d->upTrendCandlestickPen = pen;
187}
188
189QPen StockDiagram::upTrendCandlestickPen() const
190{
191 return d->upTrendCandlestickPen;
192}
193
194void StockDiagram::setDownTrendCandlestickPen( const QPen &pen )
195{
196 d->downTrendCandlestickPen = pen;
197}
198
199QPen StockDiagram::downTrendCandlestickPen() const
200{
201 return d->downTrendCandlestickPen;
202}
203
204void StockDiagram::setUpTrendCandlestickPen( int column, const QPen &pen )
205{
206 d->upTrendCandlestickPens[column] = pen;
207}
208
209QPen StockDiagram::upTrendCandlestickPen( int column ) const
210{
211 if ( d->upTrendCandlestickPens.contains( column ) )
212 return d->upTrendCandlestickPens[column];
213 return d->upTrendCandlestickPen;
214}
215
216void StockDiagram::setDownTrendCandlestickPen( int column, const QPen &pen )
217{
218 d->downTrendCandlestickPens[column] = pen;
219}
220
221QPen StockDiagram::downTrendCandlestickPen( int column ) const
222{
223 if ( d->downTrendCandlestickPens.contains( column ) )
224 return d->downTrendCandlestickPens[column];
225 return d->downTrendCandlestickPen;
226}
227
228#if defined(Q_COMPILER_MANGLES_RETURN_TYPE)
229const
230#endif
231int StockDiagram::numberOfAbscissaSegments() const { return 1; }
232
233#if defined(Q_COMPILER_MANGLES_RETURN_TYPE)
234const
235#endif
236int StockDiagram::numberOfOrdinateSegments() const { return 1; }
237
238void StockDiagram::paint( PaintContext *context )
239{
240 // Clear old reverse mapping data and create new
241 // reverse mapping scene
242 d->reverseMapper.clear();
243
244 PainterSaver painterSaver( context->painter() );
245 const int rowCount = attributesModel()->rowCount( attributesModelRootIndex() );
246 const int divisor = ( d->type == OpenHighLowClose || d->type == Candlestick ) ? 4 : 3;
247 const int colCount = attributesModel()->columnCount( attributesModelRootIndex() ) / divisor;
248 for ( int col = 0; col < colCount; ++col )
249 {
250 for ( int row = 0; row < rowCount; row++ ) {
251 CartesianDiagramDataCompressor::DataPoint low;
252 CartesianDiagramDataCompressor::DataPoint high;
253 CartesianDiagramDataCompressor::DataPoint open;
254 CartesianDiagramDataCompressor::DataPoint close;
255 CartesianDiagramDataCompressor::DataPoint volume;
256
257 if ( d->type == HighLowClose ) {
258 const CartesianDiagramDataCompressor::CachePosition highPos( row, col * divisor );
259 const CartesianDiagramDataCompressor::CachePosition lowPos( row, col * divisor + 1 );
260 const CartesianDiagramDataCompressor::CachePosition closePos( row, col * divisor + 2 );
261 low = d->compressor.data( lowPos );
262 high = d->compressor.data( highPos );
263 close = d->compressor.data( closePos );
264 } else if ( d->type == OpenHighLowClose || d->type == Candlestick ) {
265 const CartesianDiagramDataCompressor::CachePosition openPos( row, col * divisor );
266 const CartesianDiagramDataCompressor::CachePosition highPos( row, col * divisor + 1 );
267 const CartesianDiagramDataCompressor::CachePosition lowPos( row, col * divisor + 2 );
268 const CartesianDiagramDataCompressor::CachePosition closePos( row, col * divisor + 3 );
269 open = d->compressor.data( openPos );
270 low = d->compressor.data( lowPos );
271 high = d->compressor.data( highPos );
272 close = d->compressor.data( closePos );
273 }
274
275
276 switch ( d->type ) {
277 case HighLowClose:
278 open.hidden = true;
279 Q_FALLTHROUGH();
280 // Fall-through intended!
281 case OpenHighLowClose:
282 if ( close.index.isValid() && low.index.isValid() && high.index.isValid() )
283 d->drawOHLCBar( col, open, high, low, close, context );
284 break;
285 case Candlestick:
286 d->drawCandlestick( col, open, high, low, close, context );
287 break;
288 }
289 }
290 }
291}
292
293void StockDiagram::resize( const QSizeF &size )
294{
295 d->compressor.setResolution( static_cast< int >( size.width() * coordinatePlane()->zoomFactorX() ),
296 static_cast< int >( size.height() * coordinatePlane()->zoomFactorY() ) );
297 setDataBoundariesDirty();
299}
300
301qreal StockDiagram::threeDItemDepth( int column ) const
302{
303 Q_UNUSED( column );
304 //FIXME: Implement threeD functionality
305 return 1.0;
306}
307
308qreal StockDiagram::threeDItemDepth( const QModelIndex &index ) const
309{
310 Q_UNUSED( index );
311 //FIXME: Implement threeD functionality
312 return 1.0;
313}
314
315const QPair<QPointF, QPointF> StockDiagram::calculateDataBoundaries() const
316{
317 const int rowCount = attributesModel()->rowCount( attributesModelRootIndex() );
318 const int colCount = attributesModel()->columnCount( attributesModelRootIndex() );
319 qreal xMin = 0.0;
320 qreal xMax = rowCount;
321 qreal yMin = 0.0;
322 qreal yMax = 0.0;
323 for ( int row = 0; row < rowCount; row++ ) {
324 for ( int col = 0; col < colCount; col++ ) {
325 const CartesianDiagramDataCompressor::CachePosition pos( row, col );
326 const CartesianDiagramDataCompressor::DataPoint point = d->compressor.data( pos );
327 yMax = qMax( yMax, point.value );
328 yMin = qMin( yMin, point.value ); // FIXME: Can stock charts really have negative values?
329 }
330 }
331 return QPair<QPointF, QPointF>( QPointF( xMin, yMin ), QPointF( xMax, yMax ) );
332}
333
Base class for diagrams based on a cartesian coordianate system.
virtual AttributesModel * attributesModel() const
Returns the AttributesModel, that is used by this diagram.
void setPen(const QModelIndex &index, const QPen &pen)
Set the pen to be used, for painting the datapoint at the given index.
QModelIndex attributesModelRootIndex() const
void propertiesChanged()
Emitted upon change of a property of the Diagram.
QPen pen() const
Retrieve the pen to be used for painting datapoints globally.
AbstractCoordinatePlane * coordinatePlane() const
The coordinate plane associated with the diagram.
QBrush brush() const
Retrieve the brush to be used for painting datapoints globally.
int rowCount(const QModelIndex &) const override
\reimpl
int columnCount(const QModelIndex &) const override
\reimpl
Stores information about painting diagrams.
Attributes to customize the appearance of a column in a stock chart.
A set of 3D bar attributes.
Type type(const QSqlDatabase &db)
const QList< QKeySequence > & open()
QCA_EXPORT void init()
Q_EMITQ_EMIT
QVariant fromValue(T &&value)
T value() const const
bool close()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:02:46 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.