##// END OF EJS Templates
Uncomment domainScale function in XYSeries
Marek Rosa -
r1205:40041b6bff54
parent child
Show More
@@ -1,524 +1,524
1 1 /****************************************************************************
2 2 **
3 3 ** Copyright (C) 2012 Digia Plc
4 4 ** All rights reserved.
5 5 ** For any questions to Digia, please use contact form at http://qt.digia.com
6 6 **
7 7 ** This file is part of the Qt Commercial Charts Add-on.
8 8 **
9 9 ** $QT_BEGIN_LICENSE$
10 10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 11 ** accordance with the Qt Commercial License Agreement provided with the
12 12 ** Software or, alternatively, in accordance with the terms contained in
13 13 ** a written agreement between you and Digia.
14 14 **
15 15 ** If you have questions regarding the use of this file, please use
16 16 ** contact form at http://qt.digia.com
17 17 ** $QT_END_LICENSE$
18 18 **
19 19 ****************************************************************************/
20 20
21 21 #include "qxyseries.h"
22 22 #include "qxyseries_p.h"
23 23 #include "domain_p.h"
24 24 #include "legendmarker_p.h"
25 25 #include <QAbstractItemModel>
26 26 #include "qxymodelmapper.h"
27 27
28 28 QTCOMMERCIALCHART_BEGIN_NAMESPACE
29 29
30 30 /*!
31 31 \class QXYSeries
32 32 \brief The QXYSeries class is a base class for line, spline and scatter series.
33 33 */
34 34
35 35 /*!
36 36 \fn QPen QXYSeries::pen() const
37 37 \brief Returns pen used to draw points for series.
38 38 \sa setPen()
39 39 */
40 40
41 41 /*!
42 42 \fn QBrush QXYSeries::brush() const
43 43 \brief Returns brush used to draw points for series.
44 44 \sa setBrush()
45 45 */
46 46
47 47 /*!
48 48 \fn void QXYSeries::clicked(const QPointF& point)
49 49 \brief Signal is emitted when user clicks the \a point on chart.
50 50 */
51 51
52 52
53 53 /*!
54 54 \fn void QXYSeriesPrivate::pointReplaced(int index)
55 55 \brief \internal \a index
56 56 */
57 57
58 58 /*!
59 59 \fn void QXYSeriesPrivate::pointAdded(int index)
60 60 \brief \internal \a index
61 61 */
62 62
63 63 /*!
64 64 \fn void QXYSeriesPrivate::pointRemoved(int index)
65 65 \brief \internal \a index
66 66 */
67 67
68 68 /*!
69 69 \fn void QXYSeriesPrivate::updated()
70 70 \brief \internal
71 71 */
72 72
73 73 /*!
74 74 \internal
75 75
76 76 Constructs empty series object which is a child of \a parent.
77 77 When series object is added to QChartView or QChart instance ownerships is transferred.
78 78 */
79 79 QXYSeries::QXYSeries(QXYSeriesPrivate &d,QObject *parent) : QAbstractSeries(d, parent)
80 80 {
81 81
82 82 }
83 83 /*!
84 84 Destroys the object. Series added to QChartView or QChart instances are owned by those,
85 85 and are deleted when mentioned object are destroyed.
86 86 */
87 87 QXYSeries::~QXYSeries()
88 88 {
89 89 }
90 90
91 91 /*!
92 92 Adds data point \a x \a y to the series. Points are connected with lines on the chart.
93 93 */
94 94 void QXYSeries::append(qreal x,qreal y)
95 95 {
96 96 append(QPointF(x,y));
97 97 }
98 98
99 99 /*!
100 100 This is an overloaded function.
101 101 Adds data \a point to the series. Points are connected with lines on the chart.
102 102 */
103 103 void QXYSeries::append(const QPointF &point)
104 104 {
105 105 Q_D(QXYSeries);
106 106 d->m_points<<point;
107 107 emit d->pointAdded(d->m_points.count()-1);
108 108 }
109 109
110 110 /*!
111 111 This is an overloaded function.
112 112 Adds list of data \a points to the series. Points are connected with lines on the chart.
113 113 */
114 114 void QXYSeries::append(const QList<QPointF> &points)
115 115 {
116 116 foreach(const QPointF& point , points) {
117 117 append(point);
118 118 }
119 119 }
120 120
121 121
122 122 void QXYSeries::replace(qreal oldX,qreal oldY,qreal newX,qreal newY)
123 123 {
124 124 replace(QPointF(oldX,oldY),QPointF(newX,newY));
125 125 }
126 126
127 127 void QXYSeries::replace(const QPointF &oldPoint,const QPointF &newPoint)
128 128 {
129 129 Q_D(QXYSeries);
130 130 int index = d->m_points.indexOf(oldPoint);
131 131 if(index==-1) return;
132 132 d->m_points[index] = newPoint;
133 133 emit d->pointReplaced(index);
134 134 }
135 135
136 136 /*!
137 137 Removes current \a x and \a y value.
138 138 */
139 139 void QXYSeries::remove(qreal x,qreal y)
140 140 {
141 141 remove(QPointF(x,y));
142 142 }
143 143
144 144 /*!
145 145 Removes current \a point x value. Note \a point y value is ignored.
146 146 */
147 147 void QXYSeries::remove(const QPointF &point)
148 148 {
149 149 Q_D(QXYSeries);
150 150 int index = d->m_points.indexOf(point);
151 151 if(index==-1) return;
152 152 d->m_points.remove(index);
153 153 emit d->pointRemoved(index);
154 154 }
155 155
156 156 /*!
157 157 Removes all data points from the series.
158 158 */
159 159 void QXYSeries::removeAll()
160 160 {
161 161 Q_D(QXYSeries);
162 162 foreach(const QPointF& point, d->m_points) {
163 163 remove(point);
164 164 }
165 165 }
166 166
167 167 /*!
168 168 \internal \a pos
169 169 */
170 170 QList<QPointF> QXYSeries::points() const
171 171 {
172 172 // Q_ASSERT(false);
173 173 Q_D(const QXYSeries);
174 174 if (d->m_model && d->m_mapper) {
175 175 QList<QPointF> result;
176 176 if (d->m_mapper->orientation() == Qt::Vertical){
177 177 // consecutive data is read from model's column
178 178 if (d->m_mapper->mapX() >= d->m_model->columnCount() || d->m_mapper->mapY() >= d->m_model->columnCount())
179 179 return result; // mapped columns are not existing
180 180
181 181 for(int i = d->m_mapper->first(); i< d->m_mapper->first() + count(); ++i) {
182 182 qreal x = d->m_model->data(d->m_model->index(i, d->m_mapper->mapX()), Qt::DisplayRole).toReal();
183 183 qreal y = d->m_model->data(d->m_model->index(i, d->m_mapper->mapY()), Qt::DisplayRole).toReal();
184 184 result << QPointF(x,y);
185 185 }
186 186 return result;
187 187 }
188 188 else{
189 189 // consecutive data is read from model's row
190 190 if (d->m_mapper->mapX() >= d->m_model->rowCount() || d->m_mapper->mapY() >= d->m_model->rowCount())
191 191 return result; // mapped rows are not existing
192 192
193 193 for(int i = d->m_mapper->first(); i< d->m_mapper->first() + count(); ++i) {
194 194 qreal x = d->m_model->data(d->m_model->index(d->m_mapper->mapX(), i), Qt::DisplayRole).toReal();
195 195 qreal y = d->m_model->data(d->m_model->index(d->m_mapper->mapY(), i), Qt::DisplayRole).toReal();
196 196 result << QPointF(x,y);
197 197 }
198 198 return result;
199 199 }
200 200 } else {
201 201 // model is not specified, return the data from series' internal data store
202 202 return d->m_points.toList();
203 203 }
204 204 }
205 205
206 206 /*!
207 207 Returns number of data points within series.
208 208 */
209 209 int QXYSeries::count() const
210 210 {
211 211 Q_D(const QXYSeries);
212 212
213 213 if (d->m_model && d->m_mapper) {
214 214
215 215 if (d->m_mapper->orientation() == Qt::Vertical) {
216 216 // data is in a column. Return the number of mapped items if the model's column have enough items
217 217 // or the number of items that can be mapped
218 218 if (d->m_mapper->mapX() >= d->m_model->columnCount() || d->m_mapper->mapY() >= d->m_model->columnCount())
219 219 return 0; // mapped columns are not existing
220 220 else if (d->m_mapper->count() != -1)
221 221 return qMin(d->m_mapper->count(), qMax(d->m_model->rowCount() - d->m_mapper->first(), 0));
222 222 else
223 223 return qMax(d->m_model->rowCount() - d->m_mapper->first(), 0);
224 224 } else {
225 225 // data is in a row. Return the number of mapped items if the model's row have enough items
226 226 // or the number of items that can be mapped
227 227 if (d->m_mapper->mapX() >= d->m_model->rowCount() || d->m_mapper->mapY() >= d->m_model->rowCount())
228 228 return 0; // mapped rows are not existing
229 229 else if (d->m_mapper->count() != -1)
230 230 return qMin(d->m_mapper->count(), qMax(d->m_model->columnCount() - d->m_mapper->first(), 0));
231 231 else
232 232 return qMax(d->m_model->columnCount() - d->m_mapper->first(), 0);
233 233 }
234 234 }
235 235
236 236 // model is not specified, return the number of points in the series internal data store
237 237 return d->m_points.count();
238 238 }
239 239
240 240
241 241 /*!
242 242 Sets \a pen used for drawing points on the chart. If the pen is not defined, the
243 243 pen from chart theme is used.
244 244 \sa QChart::setTheme()
245 245 */
246 246 void QXYSeries::setPen(const QPen &pen)
247 247 {
248 248 Q_D(QXYSeries);
249 249 if (d->m_pen!=pen) {
250 250 d->m_pen = pen;
251 251 emit d->updated();
252 252 }
253 253 }
254 254
255 255 QPen QXYSeries::pen() const
256 256 {
257 257 Q_D(const QXYSeries);
258 258 return d->m_pen;
259 259 }
260 260
261 261 /*!
262 262 Sets \a brush used for drawing points on the chart. If the brush is not defined, brush
263 263 from chart theme setting is used.
264 264 \sa QChart::setTheme()
265 265 */
266 266 void QXYSeries::setBrush(const QBrush &brush)
267 267 {
268 268 Q_D(QXYSeries);
269 269 if (d->m_brush!=brush) {
270 270 d->m_brush = brush;
271 271 emit d->updated();
272 272 }
273 273 }
274 274
275 275 QBrush QXYSeries::brush() const
276 276 {
277 277 Q_D(const QXYSeries);
278 278 return d->m_brush;
279 279 }
280 280
281 281
282 282 /*!
283 283 Sets if data points are \a visible and should be drawn on line.
284 284 */
285 285 void QXYSeries::setPointsVisible(bool visible)
286 286 {
287 287 Q_D(QXYSeries);
288 288 if (d->m_pointsVisible != visible){
289 289 d->m_pointsVisible = visible;
290 290 emit d->updated();
291 291 }
292 292 }
293 293
294 294 /*!
295 295 Returns true if drawing the data points of the series is enabled.
296 296 */
297 297 bool QXYSeries::pointsVisible() const
298 298 {
299 299 Q_D(const QXYSeries);
300 300 return d->m_pointsVisible;
301 301 }
302 302
303 303
304 304 /*!
305 305 Stream operator for adding a data \a point to the series.
306 306 \sa append()
307 307 */
308 308 QXYSeries& QXYSeries::operator<< (const QPointF &point)
309 309 {
310 310 append(point);
311 311 return *this;
312 312 }
313 313
314 314
315 315 /*!
316 316 Stream operator for adding a list of \a points to the series.
317 317 \sa append()
318 318 */
319 319
320 320 QXYSeries& QXYSeries::operator<< (const QList<QPointF>& points)
321 321 {
322 322 append(points);
323 323 return *this;
324 324 }
325 325
326 326 /*!
327 327 \fn bool QXYSeries::setModel(QAbstractItemModel *model)
328 328 Sets the \a model to be used as a data source
329 329 \sa setModelMapping()
330 330 */
331 331 void QXYSeries::setModel(QAbstractItemModel *model)
332 332 {
333 333 Q_D(QXYSeries);
334 334 // disconnect signals from old model
335 335 if (d->m_model) {
336 336 QObject::disconnect(d->m_model, 0, this, 0);
337 337 }
338 338
339 339 // set new model
340 340 if (model) {
341 341 d->m_model = model;
342 342 emit d->reinitialized();
343 343
344 344 // connect signals from the model
345 345 connect(d->m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)), d, SLOT(modelUpdated(QModelIndex,QModelIndex)));
346 346 connect(d->m_model,SIGNAL(rowsInserted(QModelIndex,int,int)), d, SLOT(modelRowsAdded(QModelIndex,int,int)));
347 347 connect(d->m_model,SIGNAL(rowsRemoved(QModelIndex,int,int)), d, SLOT(modelRowsRemoved(QModelIndex,int,int)));
348 348 connect(d->m_model, SIGNAL(columnsInserted(QModelIndex,int,int)), d, SLOT(modelColumnsAdded(QModelIndex,int,int)));
349 349 connect(d->m_model, SIGNAL(columnsRemoved(QModelIndex,int,int)), d, SLOT(modelColumnsRemoved(QModelIndex,int,int)));
350 350 } else {
351 351 d->m_model = 0;
352 352 }
353 353 }
354 354
355 355 void QXYSeries::setModelMapper(QXYModelMapper *mapper)
356 356 {
357 357 Q_D(QXYSeries);
358 358 // disconnect signals from old mapper
359 359 if (d->m_mapper) {
360 360 QObject::disconnect(d->m_mapper, 0, this, 0);
361 361 }
362 362
363 363 if (mapper) {
364 364 d->m_mapper = mapper;
365 365 emit d->reinitialized();
366 366
367 367 // connect the signal from the mapper
368 368 connect(d->m_mapper, SIGNAL(updated()), d, SLOT(mappingUpdated()));
369 369 } else {
370 370 d->m_mapper = 0;
371 371 }
372 372 }
373 373
374 374 QXYModelMapper* QXYSeries::modelMapper() const
375 375 {
376 376 Q_D(const QXYSeries);
377 377 return d->m_mapper;
378 378 }
379 379
380 380 /*!
381 381 Sets the \a modelX to be used as a data source for x coordinate and \a modelY to be used
382 382 as a data source for y coordinate. The \a orientation parameter specifies whether the data
383 383 is in columns or in rows.
384 384 \sa setModel()
385 385 */
386 386
387 387
388 388 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
389 389
390 390
391 391 QXYSeriesPrivate::QXYSeriesPrivate(QXYSeries *q) : QAbstractSeriesPrivate(q),
392 392 m_mapper(0),
393 393 m_pointsVisible(false)
394 394 {
395 395 }
396 396
397 397 void QXYSeriesPrivate::scaleDomain(Domain& domain)
398 398 {
399 399 qreal minX(domain.minX());
400 400 qreal minY(domain.minY());
401 401 qreal maxX(domain.maxX());
402 402 qreal maxY(domain.maxY());
403 403 int tickXCount(domain.tickXCount());
404 404 int tickYCount(domain.tickYCount());
405 405
406 406 Q_Q(QXYSeries);
407 407
408 408 const QList<QPointF>& points = q->points();
409 409
410 // if(points.isEmpty()){
411 // minX=0.0;
412 // minY=0.0;
413 // maxX=1.0;
414 // maxY=1.0;
415 // }
416
417 // for (int i = 0; i < points.count(); i++)
418 // {
419 // qreal x = points[i].x();
420 // qreal y = points[i].y();
421 // minX = qMin(minX, x);
422 // minY = qMin(minY, y);
423 // maxX = qMax(maxX, x);
424 // maxY = qMax(maxY, y);
425 // }
426
427 // domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
410 if(points.isEmpty()){
411 minX=0.0;
412 minY=0.0;
413 maxX=1.0;
414 maxY=1.0;
415 }
416
417 for (int i = 0; i < points.count(); i++)
418 {
419 qreal x = points[i].x();
420 qreal y = points[i].y();
421 minX = qMin(minX, x);
422 minY = qMin(minY, y);
423 maxX = qMax(maxX, x);
424 maxY = qMax(maxY, y);
425 }
426
427 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
428 428
429 429 if (!points.isEmpty()) {
430 430 for (int i = 0; i < points.count(); i++) {
431 431 qreal x = points[i].x();
432 432 qreal y = points[i].y();
433 433 minX = qMin(minX, x);
434 434 minY = qMin(minY, y);
435 435 maxX = qMax(maxX, x);
436 436 maxY = qMax(maxY, y);
437 437 }
438 438 domain.setRange(minX,maxX,minY,maxY,tickXCount,tickYCount);
439 439 }
440 440 }
441 441
442 442 QList<LegendMarker*> QXYSeriesPrivate::createLegendMarker(QLegend* legend)
443 443 {
444 444 Q_Q(QXYSeries);
445 445 QList<LegendMarker*> list;
446 446 return list << new XYLegendMarker(q,legend);
447 447 }
448 448
449 449 void QXYSeriesPrivate::mappingUpdated()
450 450 {
451 451 if (m_model)
452 452 emit reinitialized();
453 453 }
454 454
455 455 void QXYSeriesPrivate::modelUpdated(QModelIndex topLeft, QModelIndex bottomRight)
456 456 {
457 457 if (m_mapper) {
458 458 for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
459 459 for (int column = topLeft.column(); column <= bottomRight.column(); column++) {
460 460 if (m_mapper->orientation() == Qt::Vertical) {
461 461 if ((column == m_mapper->mapX() || column == m_mapper->mapY()) // modified item is in a mapped column
462 462 && row >= m_mapper->first() // modfied item in not before first item
463 463 && (m_mapper->count() == -1 || row < m_mapper->first() + m_mapper->count())) // map is not limited or item lays before the end of map
464 464 emit pointReplaced(row - m_mapper->first());
465 465 } else {
466 466 if ((row == m_mapper->mapX() || row == m_mapper->mapY()) // modified item is in a mapped row
467 467 && column >= m_mapper->first() // modfied item in not before first item
468 468 && (m_mapper->count() == -1 || column < m_mapper->first() + m_mapper->count())) // map is not limited or item lays before the end of map
469 469 emit pointReplaced(column - m_mapper->first());
470 470 }
471 471 }
472 472 }
473 473 }
474 474 }
475 475
476 476
477 477 void QXYSeriesPrivate::modelRowsAdded(QModelIndex parent, int start, int end)
478 478 {
479 479 Q_UNUSED(parent);
480 480 if (m_mapper) {
481 481 if (m_mapper->orientation() == Qt::Vertical)
482 482 emit pointsAdded(start, end);
483 483 else if (start <= m_mapper->mapX() || start <= m_mapper->mapY())
484 484 emit reinitialized();
485 485 }
486 486 }
487 487
488 488 void QXYSeriesPrivate::modelRowsRemoved(QModelIndex parent, int start, int end)
489 489 {
490 490 Q_UNUSED(parent);
491 491 if (m_mapper) {
492 492 if (m_mapper->orientation() == Qt::Vertical)
493 493 emit pointsRemoved(start, end);
494 494 else if (start <= m_mapper->mapX() || start <= m_mapper->mapY())
495 495 emit reinitialized();
496 496 }
497 497 }
498 498
499 499 void QXYSeriesPrivate::modelColumnsAdded(QModelIndex parent, int start, int end)
500 500 {
501 501 Q_UNUSED(parent);
502 502 if (m_mapper) {
503 503 if (m_mapper->orientation() == Qt::Horizontal)
504 504 emit pointsAdded(start, end);
505 505 else if (start <= m_mapper->mapX() || start <= m_mapper->mapY())
506 506 emit reinitialized();
507 507 }
508 508 }
509 509
510 510 void QXYSeriesPrivate::modelColumnsRemoved(QModelIndex parent, int start, int end)
511 511 {
512 512 Q_UNUSED(parent);
513 513 if (m_mapper) {
514 514 if (m_mapper->orientation() == Qt::Horizontal)
515 515 emit pointsRemoved(start, end);
516 516 else if (start <= m_mapper->mapX() || start <= m_mapper->mapY())
517 517 emit reinitialized();
518 518 }
519 519 }
520 520
521 521 #include "moc_qxyseries.cpp"
522 522 #include "moc_qxyseries_p.cpp"
523 523
524 524 QTCOMMERCIALCHART_END_NAMESPACE
General Comments 0
You need to be logged in to leave comments. Login now