KChart

KChartLineDiagram.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 "KChartLineDiagram.h"
10 #include "KChartLineDiagram_p.h"
11 
12 #include "KChartBarDiagram.h"
13 #include "KChartPalette.h"
14 #include "KChartAttributesModel.h"
15 #include "KChartAbstractGrid.h"
16 #include "KChartPainterSaver_p.h"
17 
18 #include "KChartNormalLineDiagram_p.h"
19 #include "KChartStackedLineDiagram_p.h"
20 #include "KChartPercentLineDiagram_p.h"
21 #include "KChartMath_p.h"
22 
23 #include <QDebug>
24 #include <QPainter>
25 #include <QString>
26 #include <QPainterPath>
27 #include <QPen>
28 #include <QVector>
29 
30 using namespace KChart;
31 
32 LineDiagram::Private::Private()
33 {
34 }
35 
36 LineDiagram::Private::~Private() {}
37 
38 
39 #define d d_func()
40 
41 
42 LineDiagram::LineDiagram( QWidget* parent, CartesianCoordinatePlane* plane ) :
43  AbstractCartesianDiagram( new Private(), parent, plane )
44 {
45  init();
46 }
47 
48 void LineDiagram::init()
49 {
50  d->normalDiagram = new NormalLineDiagram( this );
51  d->stackedDiagram = new StackedLineDiagram( this );
52  d->percentDiagram = new PercentLineDiagram( this );
53  d->implementor = d->normalDiagram;
54  d->centerDataPoints = false;
55  d->reverseDatasetOrder = false;
56 }
57 
58 LineDiagram::~LineDiagram()
59 {
60  delete d->normalDiagram;
61  delete d->stackedDiagram;
62  delete d->percentDiagram;
63 }
64 
66 {
67  LineDiagram* newDiagram = new LineDiagram( new Private( *d ) );
68  newDiagram->setType( type() );
69  return newDiagram;
70 }
71 
72 
73 bool LineDiagram::compare( const LineDiagram* other ) const
74 {
75  if ( other == this ) return true;
76  if ( ! other ) {
77  return false;
78  }
79  return // compare the base class
80  ( static_cast<const AbstractCartesianDiagram*>(this)->compare( other ) ) &&
81  // compare own properties
82  (type() == other->type()) &&
83  (centerDataPoints() == other->centerDataPoints()) &&
85 }
86 
87 void LineDiagram::setType( const LineType type )
88 {
89  if ( d->implementor->type() == type ) return;
90  if ( type != LineDiagram::Normal && datasetDimension() > 1 ) {
91  Q_ASSERT_X ( false, "setType()",
92  "This line chart type can't be used with multi-dimensional data." );
93  return;
94  }
95  switch ( type ) {
96  case Normal:
97  d->implementor = d->normalDiagram;
98  break;
99  case Stacked:
100  d->implementor = d->stackedDiagram;
101  break;
102  case Percent:
103  d->implementor = d->percentDiagram;
104  break;
105  default:
106  Q_ASSERT_X( false, "LineDiagram::setType", "unknown diagram subtype" );
107  };
108 
109  // d->lineType = type;
110  Q_ASSERT( d->implementor->type() == type );
111 
112  // AbstractAxis settings - see AbstractDiagram and CartesianAxis
113  setPercentMode( type == LineDiagram::Percent );
114  setDataBoundariesDirty();
115  Q_EMIT layoutChanged( this );
117 }
118 
119 LineDiagram::LineType LineDiagram::type() const
120 {
121  return d->implementor->type();
122 }
123 
125 {
126  if ( d->centerDataPoints == center ) {
127  return;
128  }
129 
130  d->centerDataPoints = center;
131  // The actual data boundaries haven't changed, but the axis will have one more or less tick
132  // A B =\ A B
133  // 1......2 =/ 1......2......3
134  setDataBoundariesDirty();
135  Q_EMIT layoutChanged( this );
137 }
138 
140 {
141  return d->centerDataPoints;
142 }
143 
145 {
146  d->reverseDatasetOrder = reverse;
147 }
148 
150 {
151  return d->reverseDatasetOrder;
152 }
153 
155 {
156  d->attributesModel->setModelData(
157  QVariant::fromValue( la ),
158  LineAttributesRole );
160 }
161 
163  int column,
164  const LineAttributes& la )
165 {
166  d->setDatasetAttrs( column, QVariant::fromValue( la ), LineAttributesRole );
168 }
169 
171 {
172  d->resetDatasetAttrs( column, LineAttributesRole );
174 }
175 
177  const QModelIndex& index,
178  const LineAttributes& la )
179 {
180  d->attributesModel->setData(
181  d->attributesModel->mapFromSource(index),
182  QVariant::fromValue( la ),
183  LineAttributesRole );
185 }
186 
188 {
189  d->attributesModel->resetData(
190  d->attributesModel->mapFromSource(index), LineAttributesRole );
192 }
193 
195 {
196  return d->attributesModel->data( KChart::LineAttributesRole ).value<LineAttributes>();
197 }
198 
200 {
201  const QVariant attrs( d->datasetAttrs( column, LineAttributesRole ) );
202  if ( attrs.isValid() )
203  return attrs.value<LineAttributes>();
204  return lineAttributes();
205 }
206 
208  const QModelIndex& index ) const
209 {
210  return d->attributesModel->data(
211  d->attributesModel->mapFromSource(index),
212  KChart::LineAttributesRole ).value<LineAttributes>();
213 }
214 
216  const ThreeDLineAttributes& la )
217 {
218  setDataBoundariesDirty();
219  d->attributesModel->setModelData(
220  QVariant::fromValue( la ),
221  ThreeDLineAttributesRole );
223 }
224 
226  int column,
227  const ThreeDLineAttributes& la )
228 {
229  setDataBoundariesDirty();
230  d->setDatasetAttrs( column, QVariant::fromValue( la ), ThreeDLineAttributesRole );
232 }
233 
235  const QModelIndex & index,
236  const ThreeDLineAttributes& la )
237 {
238  setDataBoundariesDirty();
239  d->attributesModel->setData(
240  d->attributesModel->mapFromSource(index),
241  QVariant::fromValue( la ),
242  ThreeDLineAttributesRole );
244 }
245 
247 {
248  return d->attributesModel->data( KChart::ThreeDLineAttributesRole ).value<ThreeDLineAttributes>();
249 }
250 
252 {
253  const QVariant attrs( d->datasetAttrs( column, ThreeDLineAttributesRole ) );
254  if ( attrs.isValid() )
255  return attrs.value<ThreeDLineAttributes>();
256  return threeDLineAttributes();
257 }
258 
260 {
261  return d->attributesModel->data(
262  d->attributesModel->mapFromSource( index ),
263  KChart::ThreeDLineAttributesRole ).value<ThreeDLineAttributes>();
264 }
265 
266 qreal LineDiagram::threeDItemDepth( const QModelIndex& index ) const
267 {
268  return threeDLineAttributes( index ).validDepth();
269 }
270 
271 qreal LineDiagram::threeDItemDepth( int column ) const
272 {
273  return threeDLineAttributes( column ).validDepth();
274 }
275 
277  const ValueTrackerAttributes & va )
278 {
279  d->attributesModel->setData( d->attributesModel->mapFromSource(index),
280  QVariant::fromValue( va ),
281  KChart::ValueTrackerAttributesRole );
283 }
284 
286  const QModelIndex & index ) const
287 {
288  return d->attributesModel->data(
289  d->attributesModel->mapFromSource( index ),
290  KChart::ValueTrackerAttributesRole ).value<ValueTrackerAttributes>();
291 }
292 
293 void LineDiagram::resizeEvent ( QResizeEvent* )
294 {
295 }
296 
298 {
299  d->compressor.setResolution( static_cast<int>( this->size().width() * coordinatePlane()->zoomFactorX() ),
300  static_cast<int>( this->size().height() * coordinatePlane()->zoomFactorY() ) );
301 
302  if ( !checkInvariants( true ) ) return QPair<QPointF, QPointF>( QPointF( 0, 0 ), QPointF( 0, 0 ) );
303 
304  // note: calculateDataBoundaries() is ignoring the hidden flags.
305  // That's not a bug but a feature: Hiding data does not mean removing them.
306  // For totally removing data from KD Chart's view people can use e.g. a proxy model ...
307 
308  // calculate boundaries for different line types Normal - Stacked - Percent - Default Normal
309  return d->implementor->calculateDataBoundaries();
310 }
311 
312 
313 void LineDiagram::paintEvent ( QPaintEvent*)
314 {
315  QPainter painter ( viewport() );
316  PaintContext ctx;
317  ctx.setPainter ( &painter );
318  ctx.setRectangle ( QRectF ( 0, 0, width(), height() ) );
319  paint ( &ctx );
320 }
321 
323 {
324  // note: Not having any data model assigned is no bug
325  // but we can not draw a diagram then either.
326  if ( !checkInvariants( true ) ) return;
328  const PainterSaver p( ctx->painter() );
329  if ( model()->rowCount( rootIndex() ) == 0 || model()->columnCount( rootIndex() ) == 0 )
330  return; // nothing to paint for us
331 
332  AbstractCoordinatePlane* const plane = ctx->coordinatePlane();
333  ctx->setCoordinatePlane( plane->sharedAxisMasterPlane( ctx->painter() ) );
334 
335 
336  // paint different line types Normal - Stacked - Percent - Default Normal
337  d->implementor->paint( ctx );
338 
339  ctx->setCoordinatePlane( plane );
340 }
341 
342 void LineDiagram::resize ( const QSizeF& size )
343 {
344  d->compressor.setResolution( static_cast<int>( size.width() * coordinatePlane()->zoomFactorX() ),
345  static_cast<int>( size.height() * coordinatePlane()->zoomFactorY() ) );
346  setDataBoundariesDirty();
348 }
349 
350 #if defined(Q_COMPILER_MANGLES_RETURN_TYPE)
351 const
352 #endif
353 int LineDiagram::numberOfAbscissaSegments () const
354 {
355  return d->attributesModel->rowCount(attributesModelRootIndex());
356 }
357 
358 #if defined(Q_COMPILER_MANGLES_RETURN_TYPE)
359 const
360 #endif
361 int LineDiagram::numberOfOrdinateSegments () const
362 {
363  return d->attributesModel->columnCount(attributesModelRootIndex());
364 }
bool isValid() const const
QVariant fromValue(const T &value)
Q_EMITQ_EMIT
void setLineAttributes(const LineAttributes &a)
Sets the global line attributes to la.
void resetLineAttributes(int column)
Resets the line attributes of data set column.
QAbstractItemModel * model() const const
QCA_EXPORT void init()
T value() const const
Cell-specific attributes regarding value tracking.
bool compare(const LineDiagram *other) const
Returns true if both diagrams have the same settings.
Class only listed here to document inheritance of some KChart classes.
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane,...
void setReverseDatasetOrder(bool reverse)
With this property set to true, data sets in a normal line diagram are drawn in reversed order.
void propertiesChanged()
Emitted upon change of a property of the Diagram.
const QPair< QPointF, QPointF > dataBoundaries() const
Return the bottom left and top right data point, that the diagram will display (unless the grid adjus...
Stores information about painting diagrams.
void setThreeDLineAttributes(const ThreeDLineAttributes &a)
Sets the global 3D line attributes to la.
void setValueTrackerAttributes(const QModelIndex &index, const ValueTrackerAttributes &a)
Sets the value tracker attributes of the model index index to va.
AbstractCoordinatePlane * coordinatePlane() const
The coordinate plane associated with the diagram.
void setType(const LineType type)
Sets the line diagram's type to type.
Set of attributes for changing the appearance of line charts.
const QPair< QPointF, QPointF > calculateDataBoundaries() const override
\reimpl
qreal threeDItemDepth(const QModelIndex &index) const override
QModelIndex attributesModelRootIndex() const
QModelIndex rootIndex() const const
ThreeDLineAttributes threeDLineAttributes() const
int datasetDimension() const
The dataset dimension of a diagram determines how many value dimensions it expects each datapoint to ...
virtual LineDiagram * clone() const
Creates an exact copy of this diagram.
ValueTrackerAttributes valueTrackerAttributes(const QModelIndex &index) const
Returns the value tracker attributes of the model index index.
static bool isBoundariesValid(const QRectF &r)
Checks whether both coordinates of r are valid according to isValueValid.
void setCenterDataPoints(bool center)
If centerDataPoints() is true, all data points are moved by an offset of 0.5 to the right.
void setPercentMode(bool percent)
Deprecated method that turns the percent mode of this diagram on or off.
virtual void resize(const QSizeF &area)
Called by the widget's sizeEvent.
LineDiagram defines a common line diagram.
bool reverseDatasetOrder() const
A set of 3D line attributes.
LineAttributes lineAttributes() const
QWidget * viewport() const const
void paint(PaintContext *paintContext) override
Draw the diagram contents to the rectangle and painter, that are passed in as part of the paint conte...
void layoutChanged(KChart::AbstractDiagram *)
Diagrams are supposed to emit this signal, when the layout of one of their element changes.
void resize(const QSizeF &area) override
Called by the widget's sizeEvent.
Base class for diagrams based on a cartesian coordianate system.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sun Nov 27 2022 04:01:42 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.