KChart

KChartAbstractCartesianDiagram.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 "KChartAbstractCartesianDiagram.h"
10 #include "KChartAbstractCartesianDiagram_p.h"
11 
12 #include "KChartMath_p.h"
13 
14 
15 using namespace KChart;
16 
17 AbstractCartesianDiagram::Private::Private()
18  : referenceDiagram( nullptr )
19 {
20 }
21 
22 AbstractCartesianDiagram::Private::~Private()
23 {
24 }
25 
27 {
28  if ( other == this ) return true;
29  if ( ! other ) {
30  return false;
31  }
32  return // compare the base class
33  ( static_cast<const AbstractDiagram*>(this)->compare( other ) ) &&
34  // compare own properties
35  (referenceDiagram() == other->referenceDiagram()) &&
37 }
38 
39 
40 #define d d_func()
41 
42 AbstractCartesianDiagram::AbstractCartesianDiagram ( QWidget* parent, CartesianCoordinatePlane* plane )
43  : AbstractDiagram ( new Private(), parent, plane )
44 {
45  init();
46 }
47 
48 KChart::AbstractCartesianDiagram::~AbstractCartesianDiagram()
49 {
50  for ( CartesianAxis* axis : qAsConst(d->axesList) ) {
51  axis->deleteObserver( this );
52  }
53  d->axesList.clear();
54 }
55 
56 void AbstractCartesianDiagram::init()
57 {
58  d->compressor.setModel( attributesModel() );
59  // NOTE: These signals are disconnected elsewhere (e.g: Plotter) so be careful to make any changes.
61  &d->compressor, SLOT(slotDiagramLayoutChanged(KChart::AbstractDiagram*)) );
63  this, SLOT(connectAttributesModel(KChart::AttributesModel*)) );
64 
65  if ( d->plane ) {
66  connect( d->plane, SIGNAL(viewportCoordinateSystemChanged()),
67  this, SIGNAL(viewportCoordinateSystemChanged()) );
68  }
69 }
70 
72 {
73  if ( !d->axesList.contains( axis ) ) {
74  d->axesList.append( axis );
75  axis->createObserver( this );
76  layoutPlanes();
77  }
78 }
79 
81 {
82  const int idx = d->axesList.indexOf( axis );
83  if ( idx != -1 )
84  d->axesList.takeAt( idx );
85  axis->deleteObserver( this );
86  axis->setParentWidget( nullptr );
87  layoutPlanes();
88 }
89 
91 {
92  return d->axesList;
93 }
94 
96 {
97  AbstractCoordinatePlane* plane = coordinatePlane();
98  if ( plane ) {
99  plane->layoutPlanes();
100  }
101 }
102 
104 {
105  if ( coordinatePlane() ) {
106  disconnect( attributesModel(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
107  coordinatePlane(), SLOT(relayout()) );
108  disconnect( attributesModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
109  coordinatePlane(), SLOT(relayout()) );
110  disconnect( attributesModel(), SIGNAL(columnsRemoved(QModelIndex,int,int)),
111  coordinatePlane(), SLOT(relayout()) );
112  disconnect( attributesModel(), SIGNAL(columnsInserted(QModelIndex,int,int)),
113  coordinatePlane(), SLOT(relayout()) );
114  disconnect( coordinatePlane() );
115  }
116 
118  if ( plane ) {
119  // Readjust the layout when the dataset count changes
120  connect( attributesModel(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
121  plane, SLOT(relayout()) );
122  connect( attributesModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
123  plane, SLOT(relayout()) );
124  connect( attributesModel(), SIGNAL(columnsRemoved(QModelIndex,int,int)),
125  plane, SLOT(relayout()) );
126  connect( attributesModel(), SIGNAL(columnsInserted(QModelIndex,int,int)),
127  plane, SLOT(relayout()) );
128  connect( plane, SIGNAL(viewportCoordinateSystemChanged()),
129  this, SIGNAL(viewportCoordinateSystemChanged()) );
130  connect( plane, SIGNAL(viewportCoordinateSystemChanged()), this, SLOT(update()) );
131  }
132 }
133 
135 {
136  d->referenceDiagram = diagram;
137  d->referenceDiagramOffset = offset;
138 }
139 
141 {
142  return d->referenceDiagram;
143 }
144 
146 {
147  return d->referenceDiagramOffset;
148 }
149 
150 void AbstractCartesianDiagram::setRootIndex( const QModelIndex& index )
151 {
152  d->compressor.setRootIndex( attributesModel()->mapFromSource( index ) );
154 }
155 
156 void AbstractCartesianDiagram::setModel( QAbstractItemModel* m )
157 {
158  if ( m == model() ) {
159  return;
160  }
162 }
163 
165 {
166  if ( model == attributesModel() ) {
167  return;
168  }
170 }
171 
172 void AbstractCartesianDiagram::connectAttributesModel( AttributesModel* newModel )
173 {
174  // The compressor must receive model signals before the diagram because the diagram will ask the
175  // compressor for data upon receiving dataChanged() et al. from the model, at which point the
176  // compressor must be up to date already.
177  // Starting from Qt 4.6, the invocation order of slots is guaranteed to be equal to connection
178  // order (and probably was before).
179  // This is our opportunity to connect to the AttributesModel before the AbstractDiagram does.
180 
181  // ### A better design would be to properly recognize that the compressor is the real data interface
182  // for Cartesian diagrams and make diagrams listen to updates from the *compressor*, not the model.
183  // However, this would change the outside interface of AbstractCartesianDiagram which would be bad.
184  // So we're stuck with the complication of this slot and the corresponding signal.
185  d->compressor.setModel( newModel );
186 }
void setRootIndex(const QModelIndex &idx) override
Set the root index in the model, where the diagram starts referencing data for display.
virtual void setParentWidget(QWidget *widget)
Inform the item about its widget: This enables the item, to trigger that widget's update,...
bool compare(const AbstractCartesianDiagram *other) const
Returns true if both diagrams have the same settings.
virtual void takeAxis(CartesianAxis *axis)
Removes the axis from the diagram, without deleting it.
virtual void layoutPlanes()
Triggers layouting of all coordinate planes on the current chart.
virtual void setReferenceDiagram(AbstractCartesianDiagram *diagram, const QPointF &offset=QPointF())
Makes this diagram use another diagram diagram as reference diagram with relative offset offset.
QAbstractItemModel * model() const const
Class only listed here to document inheritance of some KChart classes.
virtual AttributesModel * attributesModel() const
Returns the AttributesModel, that is used by this diagram.
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane,...
virtual void setCoordinatePlane(AbstractCoordinatePlane *plane)
Set the coordinate plane associated with the diagram.
void viewportCoordinateSystemChanged()
Emitted upon change of the view coordinate system.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void setCoordinatePlane(AbstractCoordinatePlane *plane) override
\reimpl
virtual KChart::CartesianAxisList axes() const
void deleteObserver(AbstractDiagram *diagram)
virtual AbstractCartesianDiagram * referenceDiagram() const
A proxy model used for decorating data with attributes.
void createObserver(AbstractDiagram *diagram)
void layoutPlanes()
Calling layoutPlanes() on the plane triggers the global KChart::Chart::slotLayoutPlanes()
virtual void addAxis(CartesianAxis *axis)
Add the axis to the diagram.
The class for cartesian axes.
void attributesModelAboutToChange(KChart::AttributesModel *newModel, KChart::AttributesModel *oldModel)
This signal is emitted just before the new attributes model is connected internally.
AbstractDiagram defines the interface for diagram classes.
void setModel(QAbstractItemModel *model) override
Associate a model with the diagram.
virtual void setAttributesModel(AttributesModel *model)
Associate an AttributesModel with this diagram.
void layoutChanged(KChart::AbstractDiagram *)
Diagrams are supposed to emit this signal, when the layout of one of their element changes.
void setAttributesModel(AttributesModel *model) override
Associate an AttributesModel with this diagram.
Base class for diagrams based on a cartesian coordianate system.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Thu Sep 21 2023 03:54:17 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.