##// END OF EJS Templates
bugfix signals not reconnected when domain changed
Michal Klocek -
r2292:29ed1b505c34
parent child
Show More
@@ -1,481 +1,486
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "chartdataset_p.h"
21 #include "chartdataset_p.h"
22 #include "chartpresenter_p.h"
22 #include "chartpresenter_p.h"
23 #include "qchart.h"
23 #include "qchart.h"
24 #include "qchart_p.h"
24 #include "qchart_p.h"
25 #include "qvalueaxis.h"
25 #include "qvalueaxis.h"
26 #include "qbarcategoryaxis.h"
26 #include "qbarcategoryaxis.h"
27 #include "qvalueaxis_p.h"
27 #include "qvalueaxis_p.h"
28 #include "qcategoryaxis.h"
28 #include "qcategoryaxis.h"
29 #include "qabstractseries_p.h"
29 #include "qabstractseries_p.h"
30 #include "qabstractbarseries.h"
30 #include "qabstractbarseries.h"
31 #include "qstackedbarseries.h"
31 #include "qstackedbarseries.h"
32 #include "qpercentbarseries.h"
32 #include "qpercentbarseries.h"
33 #include "qpieseries.h"
33 #include "qpieseries.h"
34 #include "chartitem_p.h"
34 #include "chartitem_p.h"
35 #include "xydomain_p.h"
35 #include "xydomain_p.h"
36 #include "xlogydomain_p.h"
36 #include "xlogydomain_p.h"
37 #include "logxydomain_p.h"
37 #include "logxydomain_p.h"
38 #include "logxlogydomain_p.h"
38 #include "logxlogydomain_p.h"
39
39
40 #ifndef QT_ON_ARM
40 #ifndef QT_ON_ARM
41 #include "qdatetimeaxis.h"
41 #include "qdatetimeaxis.h"
42 #endif
42 #endif
43
43
44 QTCOMMERCIALCHART_BEGIN_NAMESPACE
44 QTCOMMERCIALCHART_BEGIN_NAMESPACE
45
45
46 ChartDataSet::ChartDataSet(QChart *chart)
46 ChartDataSet::ChartDataSet(QChart *chart)
47 : QObject(chart),
47 : QObject(chart),
48 m_chart(chart)
48 m_chart(chart)
49 {
49 {
50
50
51 }
51 }
52
52
53 ChartDataSet::~ChartDataSet()
53 ChartDataSet::~ChartDataSet()
54 {
54 {
55 deleteAllSeries();
55 deleteAllSeries();
56 deleteAllAxes();
56 deleteAllAxes();
57 }
57 }
58
58
59 /*
59 /*
60 * This method adds series to chartdataset, series ownership is taken from caller.
60 * This method adds series to chartdataset, series ownership is taken from caller.
61 */
61 */
62 void ChartDataSet::addSeries(QAbstractSeries *series)
62 void ChartDataSet::addSeries(QAbstractSeries *series)
63 {
63 {
64 if (m_seriesList.contains(series)) {
64 if (m_seriesList.contains(series)) {
65 qWarning() << QObject::tr("Can not add series. Series already on the chart.");
65 qWarning() << QObject::tr("Can not add series. Series already on the chart.");
66 return;
66 return;
67 }
67 }
68
68
69 series->d_ptr->initializeDomain();
69 series->d_ptr->initializeDomain();
70 m_seriesList.append(series);
70 m_seriesList.append(series);
71
71
72 series->setParent(this); // take ownership
72 series->setParent(this); // take ownership
73 series->d_ptr->m_chart = m_chart;
73 series->d_ptr->m_chart = m_chart;
74
74
75 emit seriesAdded(series);
75 emit seriesAdded(series);
76 }
76 }
77
77
78 /*
78 /*
79 * This method adds axis to chartdataset, axis ownership is taken from caller.
79 * This method adds axis to chartdataset, axis ownership is taken from caller.
80 */
80 */
81 void ChartDataSet::addAxis(QAbstractAxis *axis,Qt::Alignment aligment)
81 void ChartDataSet::addAxis(QAbstractAxis *axis,Qt::Alignment aligment)
82 {
82 {
83 if (m_axisList.contains(axis)) {
83 if (m_axisList.contains(axis)) {
84 qWarning() << QObject::tr("Can not add axis. Axis already on the chart.");
84 qWarning() << QObject::tr("Can not add axis. Axis already on the chart.");
85 return;
85 return;
86 }
86 }
87
87
88 axis->d_ptr->setAlignment(aligment);
88 axis->d_ptr->setAlignment(aligment);
89
89
90 if(!axis->alignment()) {
90 if(!axis->alignment()) {
91 qWarning()<< QObject::tr("No alignment specified !");
91 qWarning()<< QObject::tr("No alignment specified !");
92 return;
92 return;
93 };
93 };
94
94
95 QSharedPointer<AbstractDomain> domain(new XYDomain());
95 QSharedPointer<AbstractDomain> domain(new XYDomain());
96 axis->d_ptr->initializeDomain(domain.data());
96 axis->d_ptr->initializeDomain(domain.data());
97
97
98 axis->setParent(this);
98 axis->setParent(this);
99 axis->d_ptr->m_chart = m_chart;
99 axis->d_ptr->m_chart = m_chart;
100 m_axisList.append(axis);
100 m_axisList.append(axis);
101
101
102 emit axisAdded(axis);
102 emit axisAdded(axis);
103 }
103 }
104
104
105 /*
105 /*
106 * This method removes series form chartdataset, series ownership is passed back to caller.
106 * This method removes series form chartdataset, series ownership is passed back to caller.
107 */
107 */
108 void ChartDataSet::removeSeries(QAbstractSeries *series)
108 void ChartDataSet::removeSeries(QAbstractSeries *series)
109 {
109 {
110
110
111 if (! m_seriesList.contains(series)) {
111 if (! m_seriesList.contains(series)) {
112 qWarning() << QObject::tr("Can not remove series. Series not found on the chart.");
112 qWarning() << QObject::tr("Can not remove series. Series not found on the chart.");
113 return;
113 return;
114 }
114 }
115
115
116 emit seriesRemoved(series);
116 emit seriesRemoved(series);
117 m_seriesList.removeAll(series);
117 m_seriesList.removeAll(series);
118
118
119 series->setParent(0);
119 series->setParent(0);
120 series->d_ptr->m_chart = 0;
120 series->d_ptr->m_chart = 0;
121 series->d_ptr->m_domain.reset(0);
121 series->d_ptr->m_domain.reset(0);
122
122
123 QList<QAbstractAxis*> axes = series->d_ptr->m_axes;
123 QList<QAbstractAxis*> axes = series->d_ptr->m_axes;
124
124
125 foreach(QAbstractAxis* axis, axes) {
125 foreach(QAbstractAxis* axis, axes) {
126 axis->d_ptr->m_series.removeAll(series);
126 axis->d_ptr->m_series.removeAll(series);
127 series->d_ptr->m_axes.removeAll(axis);
127 series->d_ptr->m_axes.removeAll(axis);
128 }
128 }
129
129
130 }
130 }
131
131
132 /*
132 /*
133 * This method removes axis form chartdataset, series ownership is passed back to caller.
133 * This method removes axis form chartdataset, series ownership is passed back to caller.
134 */
134 */
135 void ChartDataSet::removeAxis(QAbstractAxis *axis)
135 void ChartDataSet::removeAxis(QAbstractAxis *axis)
136 {
136 {
137 if (! m_axisList.contains(axis)) {
137 if (! m_axisList.contains(axis)) {
138 qWarning() << QObject::tr("Can not remove axis. Axis not found on the chart.");
138 qWarning() << QObject::tr("Can not remove axis. Axis not found on the chart.");
139 return;
139 return;
140 }
140 }
141
141
142 emit axisRemoved(axis);
142 emit axisRemoved(axis);
143 m_axisList.removeAll(axis);
143 m_axisList.removeAll(axis);
144
144
145 axis->setParent(0);
145 axis->setParent(0);
146 axis->d_ptr->m_chart = 0;
146 axis->d_ptr->m_chart = 0;
147
147
148 QList<QAbstractSeries*> series = axis->d_ptr->m_series;
148 QList<QAbstractSeries*> series = axis->d_ptr->m_series;
149
149
150 foreach(QAbstractSeries* s, series) {
150 foreach(QAbstractSeries* s, series) {
151 s->d_ptr->m_axes.removeAll(axis);
151 s->d_ptr->m_axes.removeAll(axis);
152 axis->d_ptr->m_series.removeAll(s);
152 axis->d_ptr->m_series.removeAll(s);
153 }
153 }
154 }
154 }
155
155
156 /*
156 /*
157 * This method attaches axis to series, return true if success.
157 * This method attaches axis to series, return true if success.
158 */
158 */
159 bool ChartDataSet::attachAxis(QAbstractSeries* series,QAbstractAxis *axis)
159 bool ChartDataSet::attachAxis(QAbstractSeries* series,QAbstractAxis *axis)
160 {
160 {
161 Q_ASSERT(series);
161 Q_ASSERT(series);
162 Q_ASSERT(axis);
162 Q_ASSERT(axis);
163
163
164 QList<QAbstractSeries* > attachedSeriesList = axis->d_ptr->m_series;
164 QList<QAbstractSeries* > attachedSeriesList = axis->d_ptr->m_series;
165 QList<QAbstractAxis* > attachedAxisList = series->d_ptr->m_axes;
165 QList<QAbstractAxis* > attachedAxisList = series->d_ptr->m_axes;
166
166
167 if (!m_seriesList.contains(series)) {
167 if (!m_seriesList.contains(series)) {
168 qWarning() << QObject::tr("Can not find series on the chart.");
168 qWarning() << QObject::tr("Can not find series on the chart.");
169 return false;
169 return false;
170 }
170 }
171
171
172 if (axis && !m_axisList.contains(axis)) {
172 if (axis && !m_axisList.contains(axis)) {
173 qWarning() << QObject::tr("Can not find axis on the chart.");
173 qWarning() << QObject::tr("Can not find axis on the chart.");
174 return false;
174 return false;
175 }
175 }
176
176
177 if (attachedAxisList.contains(axis)) {
177 if (attachedAxisList.contains(axis)) {
178 qWarning() << QObject::tr("Axis already attached to series.");
178 qWarning() << QObject::tr("Axis already attached to series.");
179 return false;
179 return false;
180 }
180 }
181
181
182 if (attachedSeriesList.contains(series)) {
182 if (attachedSeriesList.contains(series)) {
183 qWarning() << QObject::tr("Axis already attached to series.");
183 qWarning() << QObject::tr("Axis already attached to series.");
184 return false;
184 return false;
185 }
185 }
186
186
187 AbstractDomain* domain = series->d_ptr->domain();
187 AbstractDomain* domain = series->d_ptr->domain();
188 AbstractDomain::DomainType type = selectDomain(attachedAxisList<<axis);
188 AbstractDomain::DomainType type = selectDomain(attachedAxisList<<axis);
189
189
190 if(type == AbstractDomain::UndefinedDomain) return false;
190 if(type == AbstractDomain::UndefinedDomain) return false;
191
191
192 if(domain->type()!=type){
192 if(domain->type()!=type){
193 domain = createDomain(type);
193 domain = createDomain(type);
194 }
194 }
195
195
196 if(!domain) return false;
196 if(!domain) return false;
197
197
198 if(!domain->attachAxis(axis)) return false;
198 if(!domain->attachAxis(axis)) return false;
199
199
200 series->d_ptr->m_axes<<axis;
201 axis->d_ptr->m_series<<series;
202
203 if(domain!=series->d_ptr->domain()){
200 if(domain!=series->d_ptr->domain()){
201 foreach(QAbstractAxis* axis,series->d_ptr->m_axes){
202 series->d_ptr->domain()->detachAxis(axis);
203 domain->attachAxis(axis);
204 }
204 series->d_ptr->setDomain(domain);
205 series->d_ptr->setDomain(domain);
205 series->d_ptr->initializeDomain();
206 series->d_ptr->initializeDomain();
206 }
207 }
208
209 series->d_ptr->m_axes<<axis;
210 axis->d_ptr->m_series<<series;
211
207 series->d_ptr->initializeAxes();
212 series->d_ptr->initializeAxes();
208 axis->d_ptr->initializeDomain(domain);
213 axis->d_ptr->initializeDomain(domain);
209
214
210 return true;
215 return true;
211 }
216 }
212
217
213 /*
218 /*
214 * This method detaches axis to series, return true if success.
219 * This method detaches axis to series, return true if success.
215 */
220 */
216 bool ChartDataSet::detachAxis(QAbstractSeries* series,QAbstractAxis *axis)
221 bool ChartDataSet::detachAxis(QAbstractSeries* series,QAbstractAxis *axis)
217 {
222 {
218 Q_ASSERT(series);
223 Q_ASSERT(series);
219 Q_ASSERT(axis);
224 Q_ASSERT(axis);
220
225
221 QList<QAbstractSeries* > attachedSeriesList = axis->d_ptr->m_series;
226 QList<QAbstractSeries* > attachedSeriesList = axis->d_ptr->m_series;
222 QList<QAbstractAxis* > attachedAxisList = series->d_ptr->m_axes;
227 QList<QAbstractAxis* > attachedAxisList = series->d_ptr->m_axes;
223 AbstractDomain* domain = series->d_ptr->domain();
228 AbstractDomain* domain = series->d_ptr->domain();
224
229
225 if (!m_seriesList.contains(series)) {
230 if (!m_seriesList.contains(series)) {
226 qWarning() << QObject::tr("Can not find series on the chart.");
231 qWarning() << QObject::tr("Can not find series on the chart.");
227 return false;
232 return false;
228 }
233 }
229
234
230 if (axis && !m_axisList.contains(axis)) {
235 if (axis && !m_axisList.contains(axis)) {
231 qWarning() << QObject::tr("Can not find axis on the chart.");
236 qWarning() << QObject::tr("Can not find axis on the chart.");
232 return false;
237 return false;
233 }
238 }
234
239
235 if (!attachedAxisList.contains(axis)) {
240 if (!attachedAxisList.contains(axis)) {
236 qWarning() << QObject::tr("Axis not attached to series.");
241 qWarning() << QObject::tr("Axis not attached to series.");
237 return false;
242 return false;
238 }
243 }
239
244
240 Q_ASSERT(axis->d_ptr->m_series.contains(series));
245 Q_ASSERT(axis->d_ptr->m_series.contains(series));
241
246
242 domain->detachAxis(axis);
247 domain->detachAxis(axis);
243 series->d_ptr->m_axes.removeAll(axis);
248 series->d_ptr->m_axes.removeAll(axis);
244 axis->d_ptr->m_series.removeAll(series);
249 axis->d_ptr->m_series.removeAll(series);
245
250
246 return true;
251 return true;
247 }
252 }
248
253
249 void ChartDataSet::createDefaultAxes()
254 void ChartDataSet::createDefaultAxes()
250 {
255 {
251 if (m_seriesList.isEmpty())
256 if (m_seriesList.isEmpty())
252 return;
257 return;
253
258
254 QAbstractAxis::AxisTypes typeX(0);
259 QAbstractAxis::AxisTypes typeX(0);
255 QAbstractAxis::AxisTypes typeY(0);
260 QAbstractAxis::AxisTypes typeY(0);
256
261
257 // Remove possibly existing axes
262 // Remove possibly existing axes
258 deleteAllAxes();
263 deleteAllAxes();
259
264
260 Q_ASSERT(m_axisList.isEmpty());
265 Q_ASSERT(m_axisList.isEmpty());
261
266
262 // Select the required axis x and axis y types based on the types of the current series
267 // Select the required axis x and axis y types based on the types of the current series
263 foreach(QAbstractSeries* s, m_seriesList) {
268 foreach(QAbstractSeries* s, m_seriesList) {
264 typeX |= s->d_ptr->defaultAxisType(Qt::Horizontal);
269 typeX |= s->d_ptr->defaultAxisType(Qt::Horizontal);
265 typeY |= s->d_ptr->defaultAxisType(Qt::Vertical);
270 typeY |= s->d_ptr->defaultAxisType(Qt::Vertical);
266 }
271 }
267
272
268 // Create the axes of the types selected
273 // Create the axes of the types selected
269 createAxes(typeX, Qt::Horizontal);
274 createAxes(typeX, Qt::Horizontal);
270 createAxes(typeY, Qt::Vertical);
275 createAxes(typeY, Qt::Vertical);
271
276
272 }
277 }
273
278
274 void ChartDataSet::createAxes(QAbstractAxis::AxisTypes type, Qt::Orientation orientation)
279 void ChartDataSet::createAxes(QAbstractAxis::AxisTypes type, Qt::Orientation orientation)
275 {
280 {
276 QAbstractAxis *axis = 0;
281 QAbstractAxis *axis = 0;
277 //decide what axis should be created
282 //decide what axis should be created
278
283
279 switch (type) {
284 switch (type) {
280 case QAbstractAxis::AxisTypeValue:
285 case QAbstractAxis::AxisTypeValue:
281 axis = new QValueAxis(this);
286 axis = new QValueAxis(this);
282 break;
287 break;
283 case QAbstractAxis::AxisTypeBarCategory:
288 case QAbstractAxis::AxisTypeBarCategory:
284 axis = new QBarCategoryAxis(this);
289 axis = new QBarCategoryAxis(this);
285 break;
290 break;
286 case QAbstractAxis::AxisTypeCategory:
291 case QAbstractAxis::AxisTypeCategory:
287 axis = new QCategoryAxis(this);
292 axis = new QCategoryAxis(this);
288 break;
293 break;
289 #ifndef Q_WS_QWS
294 #ifndef Q_WS_QWS
290 case QAbstractAxis::AxisTypeDateTime:
295 case QAbstractAxis::AxisTypeDateTime:
291 axis = new QDateTimeAxis(this);
296 axis = new QDateTimeAxis(this);
292 break;
297 break;
293 #endif
298 #endif
294 default:
299 default:
295 axis = 0;
300 axis = 0;
296 break;
301 break;
297 }
302 }
298
303
299 if (axis) {
304 if (axis) {
300 //create one axis for all
305 //create one axis for all
301
306
302 addAxis(axis,orientation==Qt::Horizontal?Qt::AlignBottom:Qt::AlignLeft);
307 addAxis(axis,orientation==Qt::Horizontal?Qt::AlignBottom:Qt::AlignLeft);
303
308
304 foreach(QAbstractSeries *s, m_seriesList) {
309 foreach(QAbstractSeries *s, m_seriesList) {
305 attachAxis(s,axis);
310 attachAxis(s,axis);
306 }
311 }
307
312
308 }
313 }
309 else if (!type.testFlag(QAbstractAxis::AxisTypeNoAxis)) {
314 else if (!type.testFlag(QAbstractAxis::AxisTypeNoAxis)) {
310 //create separate axis
315 //create separate axis
311 foreach(QAbstractSeries *s, m_seriesList) {
316 foreach(QAbstractSeries *s, m_seriesList) {
312 QAbstractAxis *axis = s->d_ptr->createDefaultAxis(orientation);
317 QAbstractAxis *axis = s->d_ptr->createDefaultAxis(orientation);
313 if(axis) {
318 if(axis) {
314 addAxis(axis,orientation==Qt::Horizontal?Qt::AlignBottom:Qt::AlignLeft);
319 addAxis(axis,orientation==Qt::Horizontal?Qt::AlignBottom:Qt::AlignLeft);
315 attachAxis(s,axis);
320 attachAxis(s,axis);
316 }
321 }
317 }
322 }
318 }
323 }
319 }
324 }
320
325
321 void ChartDataSet::deleteAllSeries()
326 void ChartDataSet::deleteAllSeries()
322 {
327 {
323 foreach (QAbstractSeries *s , m_seriesList){
328 foreach (QAbstractSeries *s , m_seriesList){
324 removeSeries(s);
329 removeSeries(s);
325 delete s;
330 delete s;
326 }
331 }
327 Q_ASSERT(m_seriesList.count() == 0);
332 Q_ASSERT(m_seriesList.count() == 0);
328 }
333 }
329
334
330 void ChartDataSet::deleteAllAxes()
335 void ChartDataSet::deleteAllAxes()
331 {
336 {
332 foreach (QAbstractAxis *a , m_axisList){
337 foreach (QAbstractAxis *a , m_axisList){
333 removeAxis(a);
338 removeAxis(a);
334 delete a;
339 delete a;
335 }
340 }
336 Q_ASSERT(m_axisList.count() == 0);
341 Q_ASSERT(m_axisList.count() == 0);
337 }
342 }
338
343
339 void ChartDataSet::zoomInDomain(const QRectF &rect)
344 void ChartDataSet::zoomInDomain(const QRectF &rect)
340 {
345 {
341 QList<AbstractDomain*> domains;
346 QList<AbstractDomain*> domains;
342 foreach(QAbstractSeries *s, m_seriesList) {
347 foreach(QAbstractSeries *s, m_seriesList) {
343 AbstractDomain* domain = s->d_ptr->domain();
348 AbstractDomain* domain = s->d_ptr->domain();
344 s->d_ptr->m_domain->blockRangeSignals(true);
349 s->d_ptr->m_domain->blockRangeSignals(true);
345 domains<<domain;
350 domains<<domain;
346 }
351 }
347
352
348 foreach(AbstractDomain *domain, domains)
353 foreach(AbstractDomain *domain, domains)
349 domain->zoomIn(rect);
354 domain->zoomIn(rect);
350
355
351 foreach(AbstractDomain *domain, domains)
356 foreach(AbstractDomain *domain, domains)
352 domain->blockRangeSignals(false);
357 domain->blockRangeSignals(false);
353 }
358 }
354
359
355 void ChartDataSet::zoomOutDomain(const QRectF &rect)
360 void ChartDataSet::zoomOutDomain(const QRectF &rect)
356 {
361 {
357 QList<AbstractDomain*> domains;
362 QList<AbstractDomain*> domains;
358 foreach(QAbstractSeries *s, m_seriesList) {
363 foreach(QAbstractSeries *s, m_seriesList) {
359 AbstractDomain* domain = s->d_ptr->domain();
364 AbstractDomain* domain = s->d_ptr->domain();
360 s->d_ptr->m_domain->blockRangeSignals(true);
365 s->d_ptr->m_domain->blockRangeSignals(true);
361 domains<<domain;
366 domains<<domain;
362 }
367 }
363
368
364 foreach(AbstractDomain *domain, domains)
369 foreach(AbstractDomain *domain, domains)
365 domain->zoomOut(rect);
370 domain->zoomOut(rect);
366
371
367 foreach(AbstractDomain *domain, domains)
372 foreach(AbstractDomain *domain, domains)
368 domain->blockRangeSignals(false);
373 domain->blockRangeSignals(false);
369 }
374 }
370
375
371 void ChartDataSet::scrollDomain(qreal dx, qreal dy)
376 void ChartDataSet::scrollDomain(qreal dx, qreal dy)
372 {
377 {
373 QList<AbstractDomain*> domains;
378 QList<AbstractDomain*> domains;
374 foreach(QAbstractSeries *s, m_seriesList) {
379 foreach(QAbstractSeries *s, m_seriesList) {
375 AbstractDomain* domain = s->d_ptr->domain();
380 AbstractDomain* domain = s->d_ptr->domain();
376 s->d_ptr->m_domain->blockRangeSignals(true);
381 s->d_ptr->m_domain->blockRangeSignals(true);
377 domains<<domain;
382 domains<<domain;
378 }
383 }
379
384
380 foreach(AbstractDomain *domain, domains)
385 foreach(AbstractDomain *domain, domains)
381 domain->move(dx, dy);
386 domain->move(dx, dy);
382
387
383 foreach(AbstractDomain *domain, domains)
388 foreach(AbstractDomain *domain, domains)
384 domain->blockRangeSignals(false);
389 domain->blockRangeSignals(false);
385 }
390 }
386
391
387 QList<QAbstractAxis*> ChartDataSet::axes() const
392 QList<QAbstractAxis*> ChartDataSet::axes() const
388 {
393 {
389 return m_axisList;
394 return m_axisList;
390 }
395 }
391
396
392 QList<QAbstractSeries *> ChartDataSet::series() const
397 QList<QAbstractSeries *> ChartDataSet::series() const
393 {
398 {
394 return m_seriesList;
399 return m_seriesList;
395 }
400 }
396
401
397 AbstractDomain::DomainType ChartDataSet::selectDomain(QList<QAbstractAxis*> axes)
402 AbstractDomain::DomainType ChartDataSet::selectDomain(QList<QAbstractAxis*> axes)
398 {
403 {
399 enum Type {
404 enum Type {
400 Undefined = 0,
405 Undefined = 0,
401 LogType = 0x1,
406 LogType = 0x1,
402 ValueType = 0x2
407 ValueType = 0x2
403 };
408 };
404
409
405 int horizontal(Undefined);
410 int horizontal(Undefined);
406 int vertical(Undefined);
411 int vertical(Undefined);
407
412
408 foreach(QAbstractAxis* axis, axes)
413 foreach(QAbstractAxis* axis, axes)
409 {
414 {
410 switch(axis->type()) {
415 switch(axis->type()) {
411 case QAbstractAxis::AxisTypeLogValue:
416 case QAbstractAxis::AxisTypeLogValue:
412
417
413 if(axis->orientation()==Qt::Horizontal) {
418 if(axis->orientation()==Qt::Horizontal) {
414 horizontal|=LogType;
419 horizontal|=LogType;
415 }
420 }
416 if(axis->orientation()==Qt::Vertical) {
421 if(axis->orientation()==Qt::Vertical) {
417 vertical|=LogType;
422 vertical|=LogType;
418 }
423 }
419
424
420 break;
425 break;
421 case QAbstractAxis::AxisTypeValue:
426 case QAbstractAxis::AxisTypeValue:
422 case QAbstractAxis::AxisTypeBarCategory:
427 case QAbstractAxis::AxisTypeBarCategory:
423 case QAbstractAxis::AxisTypeCategory:
428 case QAbstractAxis::AxisTypeCategory:
424 case QAbstractAxis::AxisTypeDateTime:
429 case QAbstractAxis::AxisTypeDateTime:
425 if(axis->orientation()==Qt::Horizontal) {
430 if(axis->orientation()==Qt::Horizontal) {
426 horizontal|=ValueType;
431 horizontal|=ValueType;
427 }
432 }
428 if(axis->orientation()==Qt::Vertical) {
433 if(axis->orientation()==Qt::Vertical) {
429 vertical|=ValueType;
434 vertical|=ValueType;
430 }
435 }
431 break;
436 break;
432 default:
437 default:
433 qWarning()<<"Undefined type";
438 qWarning()<<"Undefined type";
434 break;
439 break;
435 }
440 }
436 }
441 }
437
442
438 if(vertical==Undefined) vertical=ValueType;
443 if(vertical==Undefined) vertical=ValueType;
439 if(horizontal==Undefined) horizontal=ValueType;
444 if(horizontal==Undefined) horizontal=ValueType;
440
445
441 if(vertical==ValueType && horizontal== ValueType) {
446 if(vertical==ValueType && horizontal== ValueType) {
442 return AbstractDomain::XYDomain;
447 return AbstractDomain::XYDomain;
443 }
448 }
444
449
445 if(vertical==LogType && horizontal== ValueType) {
450 if(vertical==LogType && horizontal== ValueType) {
446 return AbstractDomain::XLogYDomain;
451 return AbstractDomain::XLogYDomain;
447 }
452 }
448
453
449 if(vertical==ValueType && horizontal== LogType) {
454 if(vertical==ValueType && horizontal== LogType) {
450 return AbstractDomain::LogXYDomain;
455 return AbstractDomain::LogXYDomain;
451 }
456 }
452
457
453 if(vertical==LogType && horizontal== LogType) {
458 if(vertical==LogType && horizontal== LogType) {
454 return AbstractDomain::LogXLogYDomain;
459 return AbstractDomain::LogXLogYDomain;
455 }
460 }
456
461
457 return AbstractDomain::UndefinedDomain;
462 return AbstractDomain::UndefinedDomain;
458 }
463 }
459
464
460
465
461 //refactor create factory
466 //refactor create factory
462 AbstractDomain* ChartDataSet::createDomain(AbstractDomain::DomainType type)
467 AbstractDomain* ChartDataSet::createDomain(AbstractDomain::DomainType type)
463 {
468 {
464 switch(type)
469 switch(type)
465 {
470 {
466 case AbstractDomain::LogXLogYDomain:
471 case AbstractDomain::LogXLogYDomain:
467 return new LogXLogYDomain();
472 return new LogXLogYDomain();
468 case AbstractDomain::XYDomain:
473 case AbstractDomain::XYDomain:
469 return new XYDomain();
474 return new XYDomain();
470 case AbstractDomain::XLogYDomain:
475 case AbstractDomain::XLogYDomain:
471 return new XLogYDomain();
476 return new XLogYDomain();
472 case AbstractDomain::LogXYDomain:
477 case AbstractDomain::LogXYDomain:
473 return new LogXYDomain();
478 return new LogXYDomain();
474 default:
479 default:
475 return 0;
480 return 0;
476 }
481 }
477 }
482 }
478
483
479 #include "moc_chartdataset_p.cpp"
484 #include "moc_chartdataset_p.cpp"
480
485
481 QTCOMMERCIALCHART_END_NAMESPACE
486 QTCOMMERCIALCHART_END_NAMESPACE
@@ -1,211 +1,209
1 /****************************************************************************
1 /****************************************************************************
2 **
2 **
3 ** Copyright (C) 2012 Digia Plc
3 ** Copyright (C) 2012 Digia Plc
4 ** All rights reserved.
4 ** All rights reserved.
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 **
6 **
7 ** This file is part of the Qt Commercial Charts Add-on.
7 ** This file is part of the Qt Commercial Charts Add-on.
8 **
8 **
9 ** $QT_BEGIN_LICENSE$
9 ** $QT_BEGIN_LICENSE$
10 ** Licensees holding valid Qt Commercial licenses may use this file in
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Commercial License Agreement provided with the
11 ** accordance with the Qt Commercial License Agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.
13 ** a written agreement between you and Digia.
14 **
14 **
15 ** If you have questions regarding the use of this file, please use
15 ** If you have questions regarding the use of this file, please use
16 ** contact form at http://qt.digia.com
16 ** contact form at http://qt.digia.com
17 ** $QT_END_LICENSE$
17 ** $QT_END_LICENSE$
18 **
18 **
19 ****************************************************************************/
19 ****************************************************************************/
20
20
21 #include "xlogydomain_p.h"
21 #include "xlogydomain_p.h"
22 #include "qabstractaxis_p.h"
22 #include "qabstractaxis_p.h"
23 #include "qlogvalueaxis.h"
23 #include "qlogvalueaxis.h"
24 #include <qmath.h>
24 #include <qmath.h>
25
25
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
26 QTCOMMERCIALCHART_BEGIN_NAMESPACE
27
27
28 XLogYDomain::XLogYDomain(QObject *parent)
28 XLogYDomain::XLogYDomain(QObject *parent)
29 : AbstractDomain(parent),
29 : AbstractDomain(parent),
30 m_logMinY(0),
30 m_logMinY(0),
31 m_logMaxY(1),
31 m_logMaxY(1),
32 m_logBaseY(10)
32 m_logBaseY(10)
33 {
33 {
34 }
34 }
35
35
36 XLogYDomain::~XLogYDomain()
36 XLogYDomain::~XLogYDomain()
37 {
37 {
38 }
38 }
39
39
40 void XLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
40 void XLogYDomain::setRange(qreal minX, qreal maxX, qreal minY, qreal maxY)
41 {
41 {
42 bool axisXChanged = false;
42 bool axisXChanged = false;
43 bool axisYChanged = false;
43 bool axisYChanged = false;
44
44
45 if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) {
45 if (!qFuzzyIsNull(m_minX - minX) || !qFuzzyIsNull(m_maxX - maxX)) {
46 m_minX = minX;
46 m_minX = minX;
47 m_maxX = maxX;
47 m_maxX = maxX;
48 axisXChanged = true;
48 axisXChanged = true;
49 if(!m_signalsBlocked)
49 if(!m_signalsBlocked)
50 emit rangeHorizontalChanged(m_minX, m_maxX);
50 emit rangeHorizontalChanged(m_minX, m_maxX);
51 }
51 }
52
52
53 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
53 if (!qFuzzyIsNull(m_minY - minY) || !qFuzzyIsNull(m_maxY - maxY)) {
54 m_minY = minY;
54 m_minY = minY;
55 m_maxY = maxY;
55 m_maxY = maxY;
56 axisYChanged = true;
56 axisYChanged = true;
57 m_logMinY = log10(m_minY) / log10(m_logBaseY);
57 m_logMinY = log10(m_minY) / log10(m_logBaseY);
58 m_logMaxY = log10(m_maxY) / log10(m_logBaseY);
58 m_logMaxY = log10(m_maxY) / log10(m_logBaseY);
59 if(!m_signalsBlocked)
59 if(!m_signalsBlocked)
60 emit rangeVerticalChanged(m_minY, m_maxY);
60 emit rangeVerticalChanged(m_minY, m_maxY);
61 }
61 }
62
62
63 if (axisXChanged || axisYChanged)
63 if (axisXChanged || axisYChanged)
64 emit updated();
64 emit updated();
65 }
65 }
66
66
67 void XLogYDomain::zoomIn(const QRectF &rect)
67 void XLogYDomain::zoomIn(const QRectF &rect)
68 {
68 {
69 qreal dx = spanX() / m_size.width();
69 qreal dx = spanX() / m_size.width();
70 qreal maxX = m_maxX;
70 qreal maxX = m_maxX;
71 qreal minX = m_minX;
71 qreal minX = m_minX;
72
72
73 maxX = minX + dx * rect.right();
73 maxX = minX + dx * rect.right();
74 minX = minX + dx * rect.left();
74 minX = minX + dx * rect.left();
75
75
76 qreal newLogMinY = m_logMaxY - rect.bottom() * (m_logMaxY - m_logMinY) / m_size.height();
76 qreal newLogMinY = m_logMaxY - rect.bottom() * (m_logMaxY - m_logMinY) / m_size.height();
77 qreal newLogMaxY = m_logMaxY - rect.top() * (m_logMaxY - m_logMinY) / m_size.height();
77 qreal newLogMaxY = m_logMaxY - rect.top() * (m_logMaxY - m_logMinY) / m_size.height();
78 qreal minY = qPow(m_logBaseY, newLogMinY);
78 qreal minY = qPow(m_logBaseY, newLogMinY);
79 qreal maxY = qPow(m_logBaseY, newLogMaxY);
79 qreal maxY = qPow(m_logBaseY, newLogMaxY);
80
80
81 setRange(minX, maxX, minY, maxY);
81 setRange(minX, maxX, minY, maxY);
82 }
82 }
83
83
84 void XLogYDomain::zoomOut(const QRectF &rect)
84 void XLogYDomain::zoomOut(const QRectF &rect)
85 {
85 {
86 qreal dx = spanX() / rect.width();
86 qreal dx = spanX() / rect.width();
87 qreal maxX = m_maxX;
87 qreal maxX = m_maxX;
88 qreal minX = m_minX;
88 qreal minX = m_minX;
89
89
90 minX = maxX - dx * rect.right();
90 minX = maxX - dx * rect.right();
91 maxX = minX + dx * m_size.width();
91 maxX = minX + dx * m_size.width();
92
92
93 qreal ratioY = m_size.height()/rect.height();
93 qreal ratioY = m_size.height()/rect.height();
94 qreal newLogMinY = m_logMaxY - (m_logMaxY - m_logMinY) / ratioY;
94 qreal newLogMinY = m_logMaxY - (m_logMaxY - m_logMinY) / ratioY;
95 qreal newLogMaxY = m_logMaxY + (m_logMaxY - m_logMinY) / ratioY;
95 qreal newLogMaxY = m_logMaxY + (m_logMaxY - m_logMinY) / ratioY;
96 qreal minY = qPow(m_logBaseY, newLogMinY);
96 qreal minY = qPow(m_logBaseY, newLogMinY);
97 qreal maxY = qPow(m_logBaseY, newLogMaxY);
97 qreal maxY = qPow(m_logBaseY, newLogMaxY);
98
98
99 setRange(minX, maxX, minY, maxY);
99 setRange(minX, maxX, minY, maxY);
100 }
100 }
101
101
102 void XLogYDomain::move(qreal dx, qreal dy)
102 void XLogYDomain::move(qreal dx, qreal dy)
103 {
103 {
104 qreal x = spanX() / m_size.width();
104 qreal x = spanX() / m_size.width();
105 qreal maxX = m_maxX;
105 qreal maxX = m_maxX;
106 qreal minX = m_minX;
106 qreal minX = m_minX;
107
107
108 if (dx != 0) {
108 if (dx != 0) {
109 minX = minX + x * dx;
109 minX = minX + x * dx;
110 maxX = maxX + x * dx;
110 maxX = maxX + x * dx;
111 }
111 }
112
112
113 qreal stepY = dy * qAbs(m_logMaxY - m_logMinY) / m_size.height();
113 qreal stepY = dy * qAbs(m_logMaxY - m_logMinY) / m_size.height();
114 qreal minY = qPow(m_logBaseY, m_logMinY + stepY);
114 qreal minY = qPow(m_logBaseY, m_logMinY + stepY);
115 qreal maxY = qPow(m_logBaseY, m_logMaxY + stepY);
115 qreal maxY = qPow(m_logBaseY, m_logMaxY + stepY);
116
116
117 setRange(minX, maxX, minY, maxY);
117 setRange(minX, maxX, minY, maxY);
118 }
118 }
119
119
120 QPointF XLogYDomain::calculateGeometryPoint(const QPointF &point) const
120 QPointF XLogYDomain::calculateGeometryPoint(const QPointF &point) const
121 {
121 {
122 const qreal leftEdge = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
122 const qreal leftEdge = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
123 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
123 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
124 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
124 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
125
125
126 qreal x = (point.x() - m_minX) * deltaX;
126 qreal x = (point.x() - m_minX) * deltaX;
127 qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - leftEdge * -deltaY + m_size.height();
127 qreal y = (log10(point.y()) / log10(m_logBaseY)) * -deltaY - leftEdge * -deltaY + m_size.height();
128 return QPointF(x, y);
128 return QPointF(x, y);
129 }
129 }
130
130
131 QVector<QPointF> XLogYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
131 QVector<QPointF> XLogYDomain::calculateGeometryPoints(const QList<QPointF>& vector) const
132 {
132 {
133 const qreal leftEdge = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
133 const qreal leftEdge = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
134 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
134 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
135 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
135 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
136
136
137 QVector<QPointF> result;
137 QVector<QPointF> result;
138 result.resize(vector.count());
138 result.resize(vector.count());
139
139
140 for (int i = 0; i < vector.count(); ++i) {
140 for (int i = 0; i < vector.count(); ++i) {
141 qreal x = (vector[i].x() - m_minX) * deltaX;
141 qreal x = (vector[i].x() - m_minX) * deltaX;
142 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - leftEdge * -deltaY + m_size.height();
142 qreal y = (log10(vector[i].y()) / log10(m_logBaseY)) * -deltaY - leftEdge * -deltaY + m_size.height();
143 result[i].setX(x);
143 result[i].setX(x);
144 result[i].setY(y);
144 result[i].setY(y);
145 }
145 }
146 return result;
146 return result;
147 }
147 }
148
148
149 QPointF XLogYDomain::calculateDomainPoint(const QPointF &point) const
149 QPointF XLogYDomain::calculateDomainPoint(const QPointF &point) const
150 {
150 {
151 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
151 const qreal deltaX = m_size.width() / (m_maxX - m_minX);
152 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
152 const qreal leftEdgeY = m_logMinY < m_logMaxY ? m_logMinY : m_logMaxY;
153 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
153 const qreal deltaY = m_size.height() / qAbs(m_logMaxY - m_logMinY);
154 qreal x = point.x() / deltaX + m_minX;
154 qreal x = point.x() / deltaX + m_minX;
155 qreal y = qPow(m_logBaseY, leftEdgeY + (m_size.height() - point.y()) / deltaY);
155 qreal y = qPow(m_logBaseY, leftEdgeY + (m_size.height() - point.y()) / deltaY);
156 return QPointF(x, y);
156 return QPointF(x, y);
157 }
157 }
158
158
159 bool XLogYDomain::attachAxis(QAbstractAxis* axis)
159 bool XLogYDomain::attachAxis(QAbstractAxis* axis)
160 {
160 {
161 AbstractDomain::attachAxis(axis);
162 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
161 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
163
162
164 if(logAxis && logAxis->orientation()==Qt::Vertical)
163 if(logAxis && logAxis->orientation()==Qt::Vertical)
165 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
164 QObject::connect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
166
165
167 return true;
166 return AbstractDomain::attachAxis(axis);
168 }
167 }
169
168
170 bool XLogYDomain::detachAxis(QAbstractAxis* axis)
169 bool XLogYDomain::detachAxis(QAbstractAxis* axis)
171 {
170 {
172 AbstractDomain::detachAxis(axis);
173 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
171 QLogValueAxis *logAxis = qobject_cast<QLogValueAxis *>(axis);
174
172
175 if(logAxis && logAxis->orientation()==Qt::Vertical)
173 if(logAxis && logAxis->orientation()==Qt::Vertical)
176 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
174 QObject::disconnect(logAxis, SIGNAL(baseChanged(qreal)), this, SLOT(handleVerticalAxisBaseChanged(qreal)));
177
175
178 return true;
176 return AbstractDomain::detachAxis(axis);
179 }
177 }
180
178
181 void XLogYDomain::handleVerticalAxisBaseChanged(qreal baseY)
179 void XLogYDomain::handleVerticalAxisBaseChanged(qreal baseY)
182 {
180 {
183 m_logBaseY = baseY;
181 m_logBaseY = baseY;
184 }
182 }
185
183
186 // operators
184 // operators
187
185
188 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const XLogYDomain &domain1, const XLogYDomain &domain2)
186 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator== (const XLogYDomain &domain1, const XLogYDomain &domain2)
189 {
187 {
190 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
188 return (qFuzzyIsNull(domain1.m_maxX - domain2.m_maxX) &&
191 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
189 qFuzzyIsNull(domain1.m_maxY - domain2.m_maxY) &&
192 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
190 qFuzzyIsNull(domain1.m_minX - domain2.m_minX) &&
193 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
191 qFuzzyIsNull(domain1.m_minY - domain2.m_minY));
194 }
192 }
195
193
196
194
197 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const XLogYDomain &domain1, const XLogYDomain &domain2)
195 bool QTCOMMERCIALCHART_AUTOTEST_EXPORT operator!= (const XLogYDomain &domain1, const XLogYDomain &domain2)
198 {
196 {
199 return !(domain1 == domain2);
197 return !(domain1 == domain2);
200 }
198 }
201
199
202
200
203 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const XLogYDomain &domain)
201 QDebug QTCOMMERCIALCHART_AUTOTEST_EXPORT operator<<(QDebug dbg, const XLogYDomain &domain)
204 {
202 {
205 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
203 dbg.nospace() << "AbstractDomain(" << domain.m_minX << ',' << domain.m_maxX << ',' << domain.m_minY << ',' << domain.m_maxY << ')' << domain.m_size;
206 return dbg.maybeSpace();
204 return dbg.maybeSpace();
207 }
205 }
208
206
209 #include "moc_xlogydomain_p.cpp"
207 #include "moc_xlogydomain_p.cpp"
210
208
211 QTCOMMERCIALCHART_END_NAMESPACE
209 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now