KD Chart 2  [rev.2.8]
KDChartPlotter.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 ** Copyright (C) 2001-2021 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 "KDChartPlotter.h"
24 #include "KDChartPlotter_p.h"
25 
26 #include "KDChartAbstractGrid.h"
27 #include "KDChartPainterSaver_p.h"
28 
29 #include <KDABLibFakes>
30 
31 #include "KDChartNormalPlotter_p.h"
32 #include "KDChartPercentPlotter_p.h"
33 
34 using namespace KDChart;
35 
36 Plotter::Private::Private()
37  : implementor( 0 )
38  , normalPlotter( 0 )
39  , percentPlotter( 0 )
40 {
41 }
42 
43 Plotter::Private::~Private()
44 {
45  delete normalPlotter;
46  delete percentPlotter;
47 }
48 
49 
50 #define d d_func()
51 
52 
54  AbstractCartesianDiagram( new Private(), parent, plane )
55 {
56  init();
57 }
58 
59 void Plotter::init()
60 {
61  d->diagram = this;
62  d->normalPlotter = new NormalPlotter( this );
63  d->percentPlotter = new PercentPlotter( this );
64  d->implementor = d->normalPlotter;
65  QObject* test = d->implementor->plotterPrivate();
66  connect( this, SIGNAL( boundariesChanged() ), test, SLOT( changedProperties() ) );
67  // The signal is connected to the superclass's slot at this point because the connection happened
68  // in its constructor when "its type was not Plotter yet".
69  disconnect( this, SIGNAL( attributesModelAboutToChange( AttributesModel*, AttributesModel* ) ),
70  this, SLOT( connectAttributesModel( AttributesModel* ) ) );
71  connect( this, SIGNAL( attributesModelAboutToChange( AttributesModel*, AttributesModel* ) ),
72  this, SLOT( connectAttributesModel( AttributesModel* ) ) );
74 }
75 
77 {
78 }
79 
84 {
85  Plotter* newDiagram = new Plotter( new Private( *d ) );
86  newDiagram->setType( type() );
87  return newDiagram;
88 }
89 
90 bool Plotter::compare( const Plotter* other ) const
91 {
92  if ( other == this )
93  return true;
94  if ( other == 0 )
95  return false;
96  return // compare the base class
97  ( static_cast< const AbstractCartesianDiagram* >( this )->compare( other ) ) &&
98  // compare own properties
99  ( type() == other->type() );
100 }
101 
103 {
104  // Order of setting the AttributesModel in compressor and diagram is very important due to slot
105  // invocation order. Refer to the longer comment in
106  // AbstractCartesianDiagram::connectAttributesModel() for details.
107 
109  {
110  d->plotterCompressor.setModel( 0 );
112  }
113  else
114  {
115  d->compressor.setModel( 0 );
116  if ( attributesModel() != d->plotterCompressor.model() )
117  {
118  d->plotterCompressor.setModel( attributesModel() );
119  connect( &d->plotterCompressor, SIGNAL( boundariesChanged() ), this, SLOT(setDataBoundariesDirty() ) );
121  {
122  connect( coordinatePlane(), SIGNAL( internal_geometryChanged( QRect,QRect ) ),
123  this, SLOT( setDataBoundariesDirty() ) );
124  connect( coordinatePlane(), SIGNAL( geometryChanged( QRect,QRect ) ),
125  this, SLOT( setDataBoundariesDirty() ) );
126  calcMergeRadius();
127  }
128  }
129  }
130 }
131 
133 {
134  return d->implementor->useCompression();
135 }
136 
138 {
139  if ( useDataCompression() != value )
140  {
141  d->implementor->setUseCompression( value );
143  {
144  d->compressor.setModel( NULL );
145  if ( attributesModel() != d->plotterCompressor.model() )
146  d->plotterCompressor.setModel( attributesModel() );
147  }
148  }
149 }
150 
152 {
153  return d->plotterCompressor.maxSlopeChange();
154 }
155 
156 void Plotter::setMaxSlopeChange( qreal value )
157 {
158  d->plotterCompressor.setMaxSlopeChange( value );
159 }
160 
162 {
163  return d->mergeRadiusPercentage;
164 }
165 
167 {
168  if ( d->mergeRadiusPercentage != value )
169  {
170  d->mergeRadiusPercentage = value;
171  //d->plotterCompressor.setMergeRadiusPercentage( value );
172  //update();
173  }
174 }
175 
179 void Plotter::setType( const PlotType type )
180 {
181  if ( d->implementor->type() == type ) {
182  return;
183  }
184  if ( datasetDimension() != 2 ) {
185  Q_ASSERT_X ( false, "setType()",
186  "This line chart type can only be used with two-dimensional data." );
187  return;
188  }
189  switch ( type ) {
190  case Normal:
191  d->implementor = d->normalPlotter;
192  break;
193  case Percent:
194  d->implementor = d->percentPlotter;
195  break;
196  default:
197  Q_ASSERT_X( false, "Plotter::setType", "unknown plotter subtype" );
198  }
199  bool connection = connect( this, SIGNAL( boundariesChanged() ),
200  d->implementor->plotterPrivate(), SLOT( changedProperties() ) );
201  Q_ASSERT( connection );
202  Q_UNUSED( connection );
203 
204  // d->lineType = type;
205  Q_ASSERT( d->implementor->type() == type );
206 
208  emit layoutChanged( this );
209  emit propertiesChanged();
210 }
211 
216 {
217  return d->implementor->type();
218 }
219 
224 {
225  d->attributesModel->setModelData( qVariantFromValue( la ), LineAttributesRole );
226  emit propertiesChanged();
227 }
228 
232 void Plotter::setLineAttributes( int column, const LineAttributes& la )
233 {
234  d->setDatasetAttrs( column, qVariantFromValue( la ), LineAttributesRole );
235  emit propertiesChanged();
236 }
237 
242 {
243  d->resetDatasetAttrs( column, LineAttributesRole );
244  emit propertiesChanged();
245 }
246 
250 void Plotter::setLineAttributes( const QModelIndex & index, const LineAttributes& la )
251 {
252  d->attributesModel->setData( d->attributesModel->mapFromSource( index ),
253  qVariantFromValue( la ), LineAttributesRole );
254  emit propertiesChanged();
255 }
256 
260 void Plotter::resetLineAttributes( const QModelIndex & index )
261 {
262  d->attributesModel->resetData(
263  d->attributesModel->mapFromSource(index), LineAttributesRole );
264  emit propertiesChanged();
265 }
266 
271 {
272  return d->attributesModel->data( KDChart::LineAttributesRole ).value<LineAttributes>();
273 }
274 
279 {
280  const QVariant attrs( d->datasetAttrs( column, LineAttributesRole ) );
281  if ( attrs.isValid() )
282  return attrs.value<LineAttributes>();
283  return lineAttributes();
284 }
285 
289 LineAttributes Plotter::lineAttributes( const QModelIndex& index ) const
290 {
291  return d->attributesModel->data(
292  d->attributesModel->mapFromSource( index ), KDChart::LineAttributesRole ).value<LineAttributes>();
293 }
294 
299 {
301  d->attributesModel->setModelData( qVariantFromValue( la ), ThreeDLineAttributesRole );
302  emit propertiesChanged();
303 }
304 
309 {
311  d->setDatasetAttrs( column, qVariantFromValue( la ), ThreeDLineAttributesRole );
312  emit propertiesChanged();
313 }
314 
318 void Plotter::setThreeDLineAttributes( const QModelIndex& index, const ThreeDLineAttributes& la )
319 {
321  d->attributesModel->setData( d->attributesModel->mapFromSource( index ), qVariantFromValue( la ),
323  emit propertiesChanged();
324 }
325 
330 {
331  return d->attributesModel->data( KDChart::ThreeDLineAttributesRole ).value<ThreeDLineAttributes>();
332 }
333 
338 {
339  const QVariant attrs( d->datasetAttrs( column, ThreeDLineAttributesRole ) );
340  if ( attrs.isValid() ) {
341  return attrs.value<ThreeDLineAttributes>();
342  }
343  return threeDLineAttributes();
344 }
345 
349 ThreeDLineAttributes Plotter::threeDLineAttributes( const QModelIndex& index ) const
350 {
351  return d->attributesModel->data(
352  d->attributesModel->mapFromSource( index ), KDChart::ThreeDLineAttributesRole ).value<ThreeDLineAttributes>();
353 }
354 
355 qreal Plotter::threeDItemDepth( const QModelIndex & index ) const
356 {
357  return threeDLineAttributes( index ).validDepth();
358 }
359 
360 qreal Plotter::threeDItemDepth( int column ) const
361 {
362  return threeDLineAttributes( column ).validDepth();
363 }
364 
368 void Plotter::setValueTrackerAttributes( const QModelIndex & index, const ValueTrackerAttributes & va )
369 {
370  d->attributesModel->setData( d->attributesModel->mapFromSource( index ),
371  qVariantFromValue( va ), KDChart::ValueTrackerAttributesRole );
372  emit propertiesChanged();
373 }
374 
378 ValueTrackerAttributes Plotter::valueTrackerAttributes( const QModelIndex & index ) const
379 {
380  return d->attributesModel->data(
381  d->attributesModel->mapFromSource( index ), KDChart::ValueTrackerAttributesRole ).value<ValueTrackerAttributes>();
382 }
383 
384 void Plotter::resizeEvent ( QResizeEvent* )
385 {
386 }
387 
389 {
390  if ( !checkInvariants( true ) )
391  return QPair< QPointF, QPointF >( QPointF( 0, 0 ), QPointF( 0, 0 ) );
392 
393  // note: calculateDataBoundaries() is ignoring the hidden flags.
394  // That's not a bug but a feature: Hiding data does not mean removing them.
395  // For totally removing data from KD Chart's view people can use e.g. a proxy model ...
396 
397  // calculate boundaries for different line types Normal - Stacked - Percent - Default Normal
398  return d->implementor->calculateDataBoundaries();
399 }
400 
401 
402 void Plotter::paintEvent ( QPaintEvent*)
403 {
404  QPainter painter ( viewport() );
405  PaintContext ctx;
406  ctx.setPainter ( &painter );
407  ctx.setRectangle ( QRectF ( 0, 0, width(), height() ) );
408  paint ( &ctx );
409 }
410 
412 {
413  // note: Not having any data model assigned is no bug
414  // but we can not draw a diagram then either.
415  if ( !checkInvariants( true ) ) return;
416 
417  AbstractCoordinatePlane* const plane = ctx->coordinatePlane();
418  if ( ! plane ) return;
419  d->setCompressorResolution( size(), plane );
420 
421  if ( !AbstractGrid::isBoundariesValid(dataBoundaries()) ) return;
422 
423  const PainterSaver p( ctx->painter() );
424  if ( model()->rowCount( rootIndex() ) == 0 || model()->columnCount( rootIndex() ) == 0 )
425  return; // nothing to paint for us
426 
427  ctx->setCoordinatePlane( plane->sharedAxisMasterPlane( ctx->painter() ) );
428 
429  // paint different line types Normal - Stacked - Percent - Default Normal
430  d->implementor->paint( ctx );
431 
432  ctx->setCoordinatePlane( plane );
433 }
434 
435 void Plotter::resize ( const QSizeF& size )
436 {
437  d->setCompressorResolution( size, coordinatePlane() );
439  {
440  d->plotterCompressor.cleanCache();
441  calcMergeRadius();
442  }
444  QAbstractItemView::resize( size.toSize() );
445 }
446 
448 {
451  {
452  calcMergeRadius();
453  //d->plotterCompressor.setMergeRadiusPercentage( d->mergeRadiusPercentage );
454  }
455 }
456 
458 {
460  Q_ASSERT( plane );
461  //Q_ASSERT( plane->translate( plane->translateBack( plane->visibleDiagramArea().topLeft() ) ) == plane->visibleDiagramArea().topLeft() );
462  QRectF range = plane->visibleDataRange();
463  //qDebug() << range;
464  const qreal radius = std::sqrt( ( range.x() + range.width() ) * ( range.y() + range.height() ) );
465  //qDebug() << radius;
466  //qDebug() << radius * d->mergeRadiusPercentage;
467  //qDebug() << d->mergeRadiusPercentage;
468  d->plotterCompressor.setMergeRadius( radius * d->mergeRadiusPercentage );
469 }
470 
471 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && defined(Q_COMPILER_MANGLES_RETURN_TYPE)
472 const
473 #endif
475 {
476  return d->attributesModel->rowCount( attributesModelRootIndex() );
477 }
478 
479 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) && defined(Q_COMPILER_MANGLES_RETURN_TYPE)
480 const
481 #endif
483 {
484  return d->attributesModel->columnCount( attributesModelRootIndex() );
485 }
KDChart::AbstractDiagram::datasetDimension
int datasetDimension() const
The dataset dimension of a diagram determines how many value dimensions it expects each datapoint to ...
Definition: KDChartAbstractDiagram.cpp:954
KDChart::Plotter::setLineAttributes
void setLineAttributes(const LineAttributes &a)
Sets the global line attributes to la.
Definition: KDChartPlotter.cpp:223
KDChart::Plotter
Plotter defines a diagram type plotting two-dimensional data.
Definition: KDChartPlotter.h:39
KDChart::AbstractCoordinatePlane::sharedAxisMasterPlane
virtual AbstractCoordinatePlane * sharedAxisMasterPlane(QPainter *p=0)
Definition: KDChartAbstractCoordinatePlane.cpp:431
QWidget
Class only listed here to document inheritance of some KDChart classes.
KDChart::Plotter::maxSlopeChange
qreal maxSlopeChange() const
Definition: KDChartPlotter.cpp:151
KDChart::AbstractCartesianDiagram::connectAttributesModel
void connectAttributesModel(AttributesModel *)
Definition: KDChartAbstractCartesianDiagram.cpp:185
KDChart::AbstractDiagram::coordinatePlane
AbstractCoordinatePlane * coordinatePlane() const
The coordinate plane associated with the diagram.
Definition: KDChartAbstractDiagram.cpp:111
KDChart::AbstractDiagram::dataBoundaries
const QPair< QPointF, QPointF > dataBoundaries() const
Return the bottom left and top right data point, that the diagram will display (unless the grid adjus...
Definition: KDChartAbstractDiagram.cpp:116
KDChart::Plotter::paint
void paint(PaintContext *paintContext) override
Draw the diagram contents to the rectangle and painter, that are passed in as part of the paint conte...
Definition: KDChartPlotter.cpp:411
KDChart::AbstractDiagram::layoutChanged
void layoutChanged(AbstractDiagram *)
Diagrams are supposed to emit this signal, when the layout of one of their element changes.
KDChart::Plotter::numberOfOrdinateSegments
int numberOfOrdinateSegments() const override
Definition: KDChartPlotter.cpp:482
KDChart::Plotter::threeDItemDepth
qreal threeDItemDepth(const QModelIndex &index) const override
Definition: KDChartPlotter.cpp:355
KDChart::Plotter::setType
void setType(const PlotType type)
Sets the plotter's type to type.
Definition: KDChartPlotter.cpp:179
KDChart::Plotter::clone
virtual Plotter * clone() const
Creates an exact copy of this diagram.
Definition: KDChartPlotter.cpp:83
KDChart
Definition: KDChartAbstractCartesianDiagram.h:30
KDChart::PaintContext::coordinatePlane
AbstractCoordinatePlane * coordinatePlane() const
Definition: KDChartPaintContext.cpp:78
KDChart::Plotter::SLOPE
@ SLOPE
Definition: KDChartPlotter.h:52
KDChart::PaintContext::setPainter
void setPainter(QPainter *painter)
Definition: KDChartPaintContext.cpp:73
KDChart::Plotter::setMergeRadiusPercentage
void setMergeRadiusPercentage(qreal value)
Definition: KDChartPlotter.cpp:166
KDChart::LineAttributesRole
@ LineAttributesRole
Definition: KDChartGlobal.h:194
KDChart::Plotter::setDataBoundariesDirty
void setDataBoundariesDirty()
Definition: KDChartPlotter.cpp:447
KDChart::AbstractDiagram::setDataBoundariesDirty
void setDataBoundariesDirty() const
Definition: KDChartAbstractDiagram.cpp:125
KDChart::Plotter::numberOfAbscissaSegments
int numberOfAbscissaSegments() const override
Definition: KDChartPlotter.cpp:474
KDChart::Plotter::BOTH
@ BOTH
Definition: KDChartPlotter.h:52
KDChart::AbstractDiagram::setDatasetDimensionInternal
void setDatasetDimensionInternal(int dimension)
Definition: KDChartAbstractDiagram.cpp:966
KDChart::PaintContext
Stores information about painting diagrams.
Definition: KDChartPaintContext.h:42
KDChart::Plotter::setUseDataCompression
void setUseDataCompression(CompressionMode value)
Definition: KDChartPlotter.cpp:137
KDChart::Plotter::CompressionMode
CompressionMode
Definition: KDChartPlotter.h:52
KDChart::Plotter::setMaxSlopeChange
void setMaxSlopeChange(qreal value)
Definition: KDChartPlotter.cpp:156
KDChart::ValueTrackerAttributesRole
@ ValueTrackerAttributesRole
Definition: KDChartGlobal.h:202
KDChart::Plotter::calcMergeRadius
void calcMergeRadius()
Definition: KDChartPlotter.cpp:457
KDChart::Plotter::Plotter
Plotter(QWidget *parent=0, CartesianCoordinatePlane *plane=0)
Definition: KDChartPlotter.cpp:53
KDChart::Plotter::type
PlotType type() const
Definition: KDChartPlotter.cpp:215
KDChart::Plotter::connectAttributesModel
void connectAttributesModel(AttributesModel *)
Definition: KDChartPlotter.cpp:102
KDChart::PaintContext::painter
QPainter * painter() const
Definition: KDChartPaintContext.cpp:68
KDChart::Plotter::paintEvent
void paintEvent(QPaintEvent *) override
Definition: KDChartPlotter.cpp:402
KDChart::Plotter::lineAttributes
LineAttributes lineAttributes() const
Definition: KDChartPlotter.cpp:270
KDChart::Plotter::resize
void resize(const QSizeF &area) override
Called by the widget's sizeEvent.
Definition: KDChartPlotter.cpp:435
KDChart::ThreeDLineAttributesRole
@ ThreeDLineAttributesRole
Definition: KDChartGlobal.h:195
KDChart::ThreeDLineAttributes
A set of 3D line attributes.
Definition: KDChartThreeDLineAttributes.h:36
KDChart::Plotter::resetLineAttributes
void resetLineAttributes(int column)
Resets the line attributes of data set column.
Definition: KDChartPlotter.cpp:241
KDChart::Plotter::mergeRadiusPercentage
qreal mergeRadiusPercentage
Definition: KDChartPlotter.h:47
KDChart::AbstractCartesianDiagram
Base class for diagrams based on a cartesian coordianate system.
Definition: KDChartAbstractCartesianDiagram.h:42
KDChart::Plotter::setValueTrackerAttributes
void setValueTrackerAttributes(const QModelIndex &index, const ValueTrackerAttributes &a)
Sets the value tracker attributes of the model index index to va.
Definition: KDChartPlotter.cpp:368
KDChart::ValueTrackerAttributes
Cell-specific attributes regarding value tracking.
Definition: KDChartValueTrackerAttributes.h:43
KDChart::CartesianCoordinatePlane::visibleDataRange
QRectF visibleDataRange() const
Returns the currently visible data range.
Definition: KDChartCartesianCoordinatePlane.cpp:860
KDChart::Plotter::resizeEvent
void resizeEvent(QResizeEvent *) override
Definition: KDChartPlotter.cpp:384
KDChart::AbstractDiagram::boundariesChanged
void boundariesChanged()
Emitted upon change of a data boundary.
KDChart::Plotter::Percent
@ Percent
Definition: KDChartPlotter.h:68
d
#define d
Definition: KDChartPlotter.cpp:50
KDChart::AttributesModel
A proxy model used for decorating data with attributes.
Definition: KDChartAttributesModel.h:47
KDChart::AbstractDiagram::attributesModel
virtual AttributesModel * attributesModel() const
Returns the AttributesModel, that is used by this diagram.
Definition: KDChartAbstractDiagram.cpp:196
KDChart::AbstractDiagram::attributesModelAboutToChange
void attributesModelAboutToChange(AttributesModel *newModel, AttributesModel *oldModel)
This signal is emitted just before the new attributes model is connected internally.
KDChart::LineAttributes
Set of attributes for changing the appearance of line charts.
Definition: KDChartLineAttributes.h:35
KDChart::Plotter::NONE
@ NONE
Definition: KDChartPlotter.h:52
KDChart::Plotter::calculateDataBoundaries
const QPair< QPointF, QPointF > calculateDataBoundaries() const override
[reimplemented]
Definition: KDChartPlotter.cpp:388
KDChart::Plotter::setThreeDLineAttributes
void setThreeDLineAttributes(const ThreeDLineAttributes &a)
Sets the global 3D line attributes to la.
Definition: KDChartPlotter.cpp:298
KDChart::PaintContext::setCoordinatePlane
void setCoordinatePlane(AbstractCoordinatePlane *plane)
Definition: KDChartPaintContext.cpp:83
KDChart::AbstractThreeDAttributes::validDepth
qreal validDepth() const
Definition: KDChartAbstractThreeDAttributes.cpp:105
KDChart::Plotter::PlotType
PlotType
Definition: KDChartPlotter.h:66
KDChart::Plotter::valueTrackerAttributes
ValueTrackerAttributes valueTrackerAttributes(const QModelIndex &index) const
Returns the value tracker attributes of the model index index.
Definition: KDChartPlotter.cpp:378
KDChart::AbstractDiagram::attributesModelRootIndex
QModelIndex attributesModelRootIndex() const
Definition: KDChartAbstractDiagram.cpp:224
QPair
Definition: KDChartWidget.h:35
KDChart::Plotter::~Plotter
~Plotter() override
Definition: KDChartPlotter.cpp:76
KDChart::Plotter::DISTANCE
@ DISTANCE
Definition: KDChartPlotter.h:52
KDChart::Plotter::threeDLineAttributes
ThreeDLineAttributes threeDLineAttributes() const
Definition: KDChartPlotter.cpp:329
KDChartPlotter.h
KDChart::PaintContext::setRectangle
void setRectangle(const QRectF &rect)
Definition: KDChartPaintContext.cpp:63
KDChart::AbstractDiagram::propertiesChanged
void propertiesChanged()
Emitted upon change of a property of the Diagram.
KDChart::CartesianCoordinatePlane
Cartesian coordinate plane.
Definition: KDChartCartesianCoordinatePlane.h:40
QObject
KDChart::AbstractDiagram::checkInvariants
virtual bool checkInvariants(bool justReturnTheStatus=false) const
Definition: KDChartAbstractDiagram.cpp:942
KDChart::Plotter::useDataCompression
CompressionMode useDataCompression
Definition: KDChartPlotter.h:46
KDChart::Plotter::Normal
@ Normal
Definition: KDChartPlotter.h:67
KDChart::AbstractCoordinatePlane
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane,...
Definition: KDChartAbstractCoordinatePlane.h:45
KDChart::Plotter::compare
bool compare(const Plotter *other) const
Returns true if both diagrams have the same settings.
Definition: KDChartPlotter.cpp:90

Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/

https://www.kdab.com/development-resources/qt-tools/kd-chart/