KChart

KChartAbstractCartesianDiagram.cpp
1 /*
2  * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved.
3  *
4  * This file is part of the KD Chart library.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #include "KChartAbstractCartesianDiagram.h"
21 #include "KChartAbstractCartesianDiagram_p.h"
22 
23 #include "KChartMath_p.h"
24 
25 
26 using namespace KChart;
27 
28 AbstractCartesianDiagram::Private::Private()
29  : referenceDiagram( nullptr )
30 {
31 }
32 
33 AbstractCartesianDiagram::Private::~Private()
34 {
35 }
36 
38 {
39  if ( other == this ) return true;
40  if ( ! other ) {
41  return false;
42  }
43  return // compare the base class
44  ( static_cast<const AbstractDiagram*>(this)->compare( other ) ) &&
45  // compare own properties
46  (referenceDiagram() == other->referenceDiagram()) &&
47  ((! referenceDiagram()) || (referenceDiagramOffset() == other->referenceDiagramOffset()));
48 }
49 
50 
51 #define d d_func()
52 
53 AbstractCartesianDiagram::AbstractCartesianDiagram ( QWidget* parent, CartesianCoordinatePlane* plane )
54  : AbstractDiagram ( new Private(), parent, plane )
55 {
56  init();
57 }
58 
59 KChart::AbstractCartesianDiagram::~AbstractCartesianDiagram()
60 {
61  for ( CartesianAxis* axis : d->axesList ) {
62  axis->deleteObserver( this );
63  }
64  d->axesList.clear();
65 }
66 
67 void AbstractCartesianDiagram::init()
68 {
69  d->compressor.setModel( attributesModel() );
70  connect( this, SIGNAL(layoutChanged(AbstractDiagram*)),
71  &d->compressor, SLOT(slotDiagramLayoutChanged(AbstractDiagram*)) );
72  connect( this, SIGNAL(attributesModelAboutToChange(AttributesModel*,AttributesModel*)),
73  this, SLOT(connectAttributesModel(AttributesModel*)) );
74 
75  if ( d->plane ) {
76  connect( d->plane, SIGNAL(viewportCoordinateSystemChanged()),
77  this, SIGNAL(viewportCoordinateSystemChanged()) );
78  }
79 }
80 
82 {
83  if ( !d->axesList.contains( axis ) ) {
84  d->axesList.append( axis );
85  axis->createObserver( this );
86  layoutPlanes();
87  }
88 }
89 
91 {
92  const int idx = d->axesList.indexOf( axis );
93  if ( idx != -1 )
94  d->axesList.takeAt( idx );
95  axis->deleteObserver( this );
96  axis->setParentWidget( nullptr );
97  layoutPlanes();
98 }
99 
101 {
102  return d->axesList;
103 }
104 
106 {
108  if ( plane ) {
109  plane->layoutPlanes();
110  }
111 }
112 
114 {
115  if ( coordinatePlane() ) {
116  disconnect( attributesModel(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
117  coordinatePlane(), SLOT(relayout()) );
118  disconnect( attributesModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
119  coordinatePlane(), SLOT(relayout()) );
120  disconnect( attributesModel(), SIGNAL(columnsRemoved(QModelIndex,int,int)),
121  coordinatePlane(), SLOT(relayout()) );
122  disconnect( attributesModel(), SIGNAL(columnsInserted(QModelIndex,int,int)),
123  coordinatePlane(), SLOT(relayout()) );
125  }
126 
128  if ( plane ) {
129  // Readjust the layout when the dataset count changes
130  connect( attributesModel(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
131  plane, SLOT(relayout()) );
132  connect( attributesModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
133  plane, SLOT(relayout()) );
134  connect( attributesModel(), SIGNAL(columnsRemoved(QModelIndex,int,int)),
135  plane, SLOT(relayout()) );
136  connect( attributesModel(), SIGNAL(columnsInserted(QModelIndex,int,int)),
137  plane, SLOT(relayout()) );
138  connect( plane, SIGNAL(viewportCoordinateSystemChanged()),
139  this, SIGNAL(viewportCoordinateSystemChanged()) );
140  connect( plane, SIGNAL(viewportCoordinateSystemChanged()), this, SLOT(update()) );
141  }
142 }
143 
145 {
146  d->referenceDiagram = diagram;
147  d->referenceDiagramOffset = offset;
148 }
149 
151 {
152  return d->referenceDiagram;
153 }
154 
156 {
157  return d->referenceDiagramOffset;
158 }
159 
160 void AbstractCartesianDiagram::setRootIndex( const QModelIndex& index )
161 {
162  d->compressor.setRootIndex( attributesModel()->mapFromSource( index ) );
164 }
165 
166 void AbstractCartesianDiagram::setModel( QAbstractItemModel* m )
167 {
168  if ( m == model() ) {
169  return;
170  }
172 }
173 
175 {
176  if ( model == attributesModel() ) {
177  return;
178  }
180 }
181 
182 void AbstractCartesianDiagram::connectAttributesModel( AttributesModel* newModel )
183 {
184  // The compressor must receive model signals before the diagram because the diagram will ask the
185  // compressor for data upon receiving dataChanged() et al. from the model, at which point the
186  // compressor must be up to date already.
187  // Starting from Qt 4.6, the invocation order of slots is guaranteed to be equal to connection
188  // order (and probably was before).
189  // This is our opportunity to connect to the AttributesModel before the AbstractDiagram does.
190 
191  // ### A better design would be to properly recognize that the compressor is the real data interface
192  // for Cartesian diagrams and make diagrams listen to updates from the *compressor*, not the model.
193  // However, this would change the outside interface of AbstractCartesianDiagram which would be bad.
194  // So we're stuck with the complication of this slot and the corresponding signal.
195  d->compressor.setModel( newModel );
196 }
Class only listed here to document inheritance of some KChart classes.
void createObserver(AbstractDiagram *diagram)
AbstractDiagram defines the interface for diagram classes.
virtual void addAxis(CartesianAxis *axis)
Add the axis to the diagram.
bool compare(const AbstractAxis *other) const
Returns true if both axes have the same settings.
bool compare(const AbstractCartesianDiagram *other) const
Returns true if both diagrams have the same settings.
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
The class for cartesian axes.
void layoutPlanes()
Calling layoutPlanes() on the plane triggers the global KChart::Chart::slotLayoutPlanes() ...
virtual void setAttributesModel(AttributesModel *model)
Associate an AttributesModel with this diagram.
virtual void setReferenceDiagram(AbstractCartesianDiagram *diagram, const QPointF &offset=QPointF())
Makes this diagram use another diagram diagram as reference diagram with relative offset offset...
Base class for diagrams based on a cartesian coordianate system.
Base class common for all coordinate planes, CartesianCoordinatePlane, PolarCoordinatePlane, TernaryCoordinatePlane.
virtual void setParentWidget(QWidget *widget)
Inform the item about its widget: This enables the item, to trigger that widget&#39;s update...
A proxy model used for decorating data with attributes.
virtual KChart::CartesianAxisList axes() const
virtual void setCoordinatePlane(AbstractCoordinatePlane *plane)
Set the coordinate plane associated with the diagram.
void setAttributesModel(AttributesModel *model) override
Associate an AttributesModel with this diagram.
void setCoordinatePlane(AbstractCoordinatePlane *plane) override
QCA_EXPORT void init()
virtual void takeAxis(CartesianAxis *axis)
Removes the axis from the diagram, without deleting it.
void setRootIndex(const QModelIndex &idx) override
Set the root index in the model, where the diagram starts referencing data for display.
void deleteObserver(AbstractDiagram *diagram)
virtual void layoutPlanes()
Triggers layouting of all coordinate planes on the current chart.
void setModel(QAbstractItemModel *model) override
Associate a model with the diagram.
Global namespace.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
virtual AbstractCartesianDiagram * referenceDiagram() const
const AbstractCoordinatePlane * coordinatePlane() const
Convenience function, returns the coordinate plane, in which this axis is used.
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Thu Sep 17 2020 22:36:39 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.