KD Chart 2  [rev.2.6]
KDChartLineDiagram.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 "KDChartLineDiagram.h"
24 #include "KDChartLineDiagram_p.h"
25 
26 #include "KDChartBarDiagram.h"
27 #include "KDChartPalette.h"
28 #include "KDChartAttributesModel.h"
29 #include "KDChartAbstractGrid.h"
30 #include "KDChartPainterSaver_p.h"
31 
32 #include <KDABLibFakes>
33 
34 #include "KDChartNormalLineDiagram_p.h"
35 #include "KDChartStackedLineDiagram_p.h"
36 #include "KDChartPercentLineDiagram_p.h"
37 
38 #include <QDebug>
39 #include <QPainter>
40 #include <QString>
41 #include <QPainterPath>
42 #include <QPen>
43 #include <QVector>
44 
45 using namespace KDChart;
46 
47 LineDiagram::Private::Private()
48 {
49 }
50 
51 LineDiagram::Private::~Private() {}
52 
53 
54 #define d d_func()
55 
56 
58  AbstractCartesianDiagram( new Private(), parent, plane )
59 {
60  init();
61 }
62 
63 void LineDiagram::init()
64 {
65  d->normalDiagram = new NormalLineDiagram( this );
66  d->stackedDiagram = new StackedLineDiagram( this );
67  d->percentDiagram = new PercentLineDiagram( this );
68  d->implementor = d->normalDiagram;
69  d->centerDataPoints = false;
70  d->reverseDatasetOrder = false;
71 }
72 
74 {
75  delete d->normalDiagram;
76  delete d->stackedDiagram;
77  delete d->percentDiagram;
78 }
79 
84 {
85  LineDiagram* newDiagram = new LineDiagram( new Private( *d ) );
86  newDiagram->setType( type() );
87  return newDiagram;
88 }
89 
90 
91 bool LineDiagram::compare( const LineDiagram* other ) const
92 {
93  if ( other == this ) return true;
94  if ( ! other ) {
95  return false;
96  }
97  return // compare the base class
98  ( static_cast<const AbstractCartesianDiagram*>(this)->compare( other ) ) &&
99  // compare own properties
100  (type() == other->type()) &&
101  (centerDataPoints() == other->centerDataPoints()) &&
103 }
104 
110 {
111  if ( d->implementor->type() == type ) return;
112  if ( type != LineDiagram::Normal && datasetDimension() > 1 ) {
113  Q_ASSERT_X ( false, "setType()",
114  "This line chart type can't be used with multi-dimensional data." );
115  return;
116  }
117  switch ( type ) {
118  case Normal:
119  d->implementor = d->normalDiagram;
120  break;
121  case Stacked:
122  d->implementor = d->stackedDiagram;
123  break;
124  case Percent:
125  d->implementor = d->percentDiagram;
126  break;
127  default:
128  Q_ASSERT_X( false, "LineDiagram::setType", "unknown diagram subtype" );
129  };
130 
131  // d->lineType = type;
132  Q_ASSERT( d->implementor->type() == type );
133 
134  // AbstractAxis settings - see AbstractDiagram and CartesianAxis
137  emit layoutChanged( this );
138  emit propertiesChanged();
139 }
140 
145 {
146  return d->implementor->type();
147 }
148 
150 {
151  if ( d->centerDataPoints == center ) {
152  return;
153  }
154 
155  d->centerDataPoints = center;
156  // The actual data boundaries haven't changed, but the axis will have one more or less tick
157  // A B =\ A B
158  // 1......2 =/ 1......2......3
160  emit layoutChanged( this );
161  emit propertiesChanged();
162 }
163 
165 {
166  return d->centerDataPoints;
167 }
168 
170 {
171  d->reverseDatasetOrder = reverse;
172 }
173 
175 {
176  return d->reverseDatasetOrder;
177 }
178 
183 {
184  d->attributesModel->setModelData(
185  qVariantFromValue( la ),
187  emit propertiesChanged();
188 }
189 
194  int column,
195  const LineAttributes& la )
196 {
197  d->setDatasetAttrs( column, qVariantFromValue( la ), LineAttributesRole );
198  emit propertiesChanged();
199 }
200 
205 {
206  d->resetDatasetAttrs( column, LineAttributesRole );
207  emit propertiesChanged();
208 }
209 
214  const QModelIndex& index,
215  const LineAttributes& la )
216 {
217  d->attributesModel->setData(
218  d->attributesModel->mapFromSource(index),
219  qVariantFromValue( la ),
221  emit propertiesChanged();
222 }
223 
227 void LineDiagram::resetLineAttributes( const QModelIndex & index )
228 {
229  d->attributesModel->resetData(
230  d->attributesModel->mapFromSource(index), LineAttributesRole );
231  emit propertiesChanged();
232 }
233 
238 {
239  return d->attributesModel->data( KDChart::LineAttributesRole ).value<LineAttributes>();
240 }
241 
246 {
247  const QVariant attrs( d->datasetAttrs( column, LineAttributesRole ) );
248  if ( attrs.isValid() )
249  return attrs.value<LineAttributes>();
250  return lineAttributes();
251 }
252 
257  const QModelIndex& index ) const
258 {
259  return d->attributesModel->data(
260  d->attributesModel->mapFromSource(index),
261  KDChart::LineAttributesRole ).value<LineAttributes>();
262 }
263 
268  const ThreeDLineAttributes& la )
269 {
271  d->attributesModel->setModelData(
272  qVariantFromValue( la ),
274  emit propertiesChanged();
275 }
276 
281  int column,
282  const ThreeDLineAttributes& la )
283 {
285  d->setDatasetAttrs( column, qVariantFromValue( la ), ThreeDLineAttributesRole );
286  emit propertiesChanged();
287 }
288 
293  const QModelIndex & index,
294  const ThreeDLineAttributes& la )
295 {
297  d->attributesModel->setData(
298  d->attributesModel->mapFromSource(index),
299  qVariantFromValue( la ),
301  emit propertiesChanged();
302 }
303 
308 {
309  return d->attributesModel->data( KDChart::ThreeDLineAttributesRole ).value<ThreeDLineAttributes>();
310 }
311 
316 {
317  const QVariant attrs( d->datasetAttrs( column, ThreeDLineAttributesRole ) );
318  if ( attrs.isValid() )
319  return attrs.value<ThreeDLineAttributes>();
320  return threeDLineAttributes();
321 }
322 
327 {
328  return d->attributesModel->data(
329  d->attributesModel->mapFromSource( index ),
330  KDChart::ThreeDLineAttributesRole ).value<ThreeDLineAttributes>();
331 }
332 
333 qreal LineDiagram::threeDItemDepth( const QModelIndex& index ) const
334 {
335  return threeDLineAttributes( index ).validDepth();
336 }
337 
338 qreal LineDiagram::threeDItemDepth( int column ) const
339 {
340  return threeDLineAttributes( column ).validDepth();
341 }
342 
346 void LineDiagram::setValueTrackerAttributes( const QModelIndex & index,
347  const ValueTrackerAttributes & va )
348 {
349  d->attributesModel->setData( d->attributesModel->mapFromSource(index),
350  qVariantFromValue( va ),
352  emit propertiesChanged();
353 }
354 
359  const QModelIndex & index ) const
360 {
361  return d->attributesModel->data(
362  d->attributesModel->mapFromSource( index ),
363  KDChart::ValueTrackerAttributesRole ).value<ValueTrackerAttributes>();
364 }
365 
366 void LineDiagram::resizeEvent ( QResizeEvent* )
367 {
368 }
369 
371 {
372  d->compressor.setResolution( static_cast<int>( this->size().width() * coordinatePlane()->zoomFactorX() ),
373  static_cast<int>( this->size().height() * coordinatePlane()->zoomFactorY() ) );
374 
375  if ( !checkInvariants( true ) ) return QPair<QPointF, QPointF>( QPointF( 0, 0 ), QPointF( 0, 0 ) );
376 
377  // note: calculateDataBoundaries() is ignoring the hidden flags.
378  // That's not a bug but a feature: Hiding data does not mean removing them.
379  // For totally removing data from KD Chart's view people can use e.g. a proxy model ...
380 
381  // calculate boundaries for different line types Normal - Stacked - Percent - Default Normal
382  return d->implementor->calculateDataBoundaries();
383 }
384 
385 
386 void LineDiagram::paintEvent ( QPaintEvent*)
387 {
388  QPainter painter ( viewport() );
389  PaintContext ctx;
390  ctx.setPainter ( &painter );
391  ctx.setRectangle ( QRectF ( 0, 0, width(), height() ) );
392  paint ( &ctx );
393 }
394 
396 {
397  // note: Not having any data model assigned is no bug
398  // but we can not draw a diagram then either.
399  if ( !checkInvariants( true ) ) return;
400  if ( !AbstractGrid::isBoundariesValid(dataBoundaries()) ) return;
401  const PainterSaver p( ctx->painter() );
402  if ( model()->rowCount( rootIndex() ) == 0 || model()->columnCount( rootIndex() ) == 0 )
403  return; // nothing to paint for us
404 
405  AbstractCoordinatePlane* const plane = ctx->coordinatePlane();
406  ctx->setCoordinatePlane( plane->sharedAxisMasterPlane( ctx->painter() ) );
407 
408 
409  // paint different line types Normal - Stacked - Percent - Default Normal
410  d->implementor->paint( ctx );
411 
412  ctx->setCoordinatePlane( plane );
413 }
414 
415 void LineDiagram::resize ( const QSizeF& size )
416 {
417  d->compressor.setResolution( static_cast<int>( size.width() * coordinatePlane()->zoomFactorX() ),
418  static_cast<int>( size.height() * coordinatePlane()->zoomFactorY() ) );
420  QAbstractItemView::resize( size.toSize() );
421 }
422 
423 #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
424 const
425 #endif
427 {
428  return d->attributesModel->rowCount(attributesModelRootIndex());
429 }
430 
431 #if QT_VERSION < 0x040400 || defined(Q_COMPILER_MANGLES_RETURN_TYPE)
432 const
433 #endif
435 {
436  return d->attributesModel->columnCount(attributesModelRootIndex());
437 }
void setLineAttributes(const LineAttributes &a)
Sets the global line attributes to la.
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane, TernaryCoordinatePlane.
virtual AbstractCoordinatePlane * sharedAxisMasterPlane(QPainter *p=0)
void setPainter(QPainter *painter)
void setType(const LineType type)
Sets the line diagram&#39;s type to type.
virtual bool checkInvariants(bool justReturnTheStatus=false) const
void resetLineAttributes(int column)
Resets the line attributes of data set column.
AbstractCoordinatePlane * coordinatePlane() const
LineDiagram(QWidget *parent=0, CartesianCoordinatePlane *plane=0)
const int numberOfAbscissaSegments() const
void setPercentMode(bool percent)
Deprecated method that turns the percent mode of this diagram on or off.
QPainter * painter() const
void setReverseDatasetOrder(bool reverse)
With this property set to true, data sets in a normal line diagram are drawn in reversed order...
AbstractCoordinatePlane * coordinatePlane() const
The coordinate plane associated with the diagram.
ThreeDLineAttributes threeDLineAttributes() const
Set of attributes for changing the appearance of line charts.
ValueTrackerAttributes valueTrackerAttributes(const QModelIndex &index) const
Returns the value tracker attributes of the model index index.
const QPair< QPointF, QPointF > dataBoundaries() const
Return the bottom left and top right data point, that the diagram will display (unless the grid adjus...
void resizeEvent(QResizeEvent *)
#define d
void propertiesChanged()
Emitted upon change of a property of the Diagram.
LineDiagram defines a common line diagram.
Cell-specific attributes regarding value tracking.
void resize(const QSizeF &area)
Called by the widget&#39;s sizeEvent.
Base class for diagrams based on a cartesian coordianate system.
Stores information about painting diagrams.
virtual qreal threeDItemDepth(const QModelIndex &index) const
void paintEvent(QPaintEvent *)
virtual LineDiagram * clone() const
Creates an exact copy of this diagram.
void layoutChanged(AbstractDiagram *)
Diagrams are supposed to emit this signal, when the layout of one of their element changes...
void paint(PaintContext *paintContext)
Draw the diagram contents to the rectangle and painter, that are passed in as part of the paint conte...
void setThreeDLineAttributes(const ThreeDLineAttributes &a)
Sets the global 3D line attributes to la.
QModelIndex attributesModelRootIndex() const
LineAttributes lineAttributes() const
void setCenterDataPoints(bool center)
If centerDataPoints() is true, all data points are moved by an offset of 0.5 to the right...
void setCoordinatePlane(AbstractCoordinatePlane *plane)
void setRectangle(const QRectF &rect)
Class only listed here to document inheritance of some KDChart classes.
bool reverseDatasetOrder() const
int datasetDimension() const
The dataset dimension of a diagram determines how many value dimensions it expects each datapoint to ...
virtual const QPair< QPointF, QPointF > calculateDataBoundaries() const
[reimplemented]
const int numberOfOrdinateSegments() const
void setValueTrackerAttributes(const QModelIndex &index, const ValueTrackerAttributes &a)
Sets the value tracker attributes of the model index index to va.
A set of 3D line attributes.
bool compare(const LineDiagram *other) const
Returns true if both diagrams have the same settings.

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